forked from JointCloud/JCC-RIP
Compare commits
8 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
a02a83edfb | |
|
|
54db9af5f0 | |
|
|
4028773037 | |
|
|
4ede8e4a35 | |
|
|
bf240dc5c3 | |
|
|
d6301bc9cd | |
|
|
3ae57a365c | |
|
|
63296475e5 |
|
|
@ -238,6 +238,7 @@
|
|||
"password": "Password",
|
||||
"createVirtualmachine": "Create Virtual Machine",
|
||||
"createHpcbase": "Create Supercomputing Base Template",
|
||||
"createVasp": "Create Vasp Task",
|
||||
"createAibase": "Create Intelligent Computing Task",
|
||||
"createAiCard": "Create Specific Computing Power Card Task",
|
||||
"dict": "Dictionary",
|
||||
|
|
@ -568,6 +569,11 @@
|
|||
"application": "Application",
|
||||
"deployment": "Deployment",
|
||||
"instanceCenter": "Instance Center",
|
||||
"instanceType": "Instance Type"
|
||||
"instanceType": "Instance Type",
|
||||
"createVaspTask": "Create Vasp Task",
|
||||
"partition": "Partition",
|
||||
"cmdScript": "Script",
|
||||
"fileUpload": "File Upload",
|
||||
"uploadSuccess": "Upload Success"
|
||||
}
|
||||
}
|
||||
|
|
@ -238,8 +238,9 @@
|
|||
"password": "密码",
|
||||
"createVirtualmachine": "创建虚拟机",
|
||||
"createHpcbase": "创建超算基础模板",
|
||||
"createVasp": "中国算力网-创建Vasp任务",
|
||||
"createAibase": "创建智算训练任务",
|
||||
"createAiCard": "创建指定算力卡训练任务",
|
||||
"createAiCard": "中国算力网-创建指定算力卡训练任务",
|
||||
"dict": "字典",
|
||||
"dictName": "字典名称",
|
||||
"dictCode": "code",
|
||||
|
|
@ -568,6 +569,11 @@
|
|||
"application": "应用",
|
||||
"deployment": "部署",
|
||||
"instanceCenter": "实例中心",
|
||||
"instanceType": "实例类型"
|
||||
"instanceType": "实例类型",
|
||||
"createVaspTask": "创建Vasp任务",
|
||||
"partition": "分区",
|
||||
"cmdScript": "脚本",
|
||||
"fileUpload": "文件上传",
|
||||
"uploadSuccess": "上传成功"
|
||||
}
|
||||
}
|
||||
|
|
@ -19,3 +19,8 @@ export const getHomeOverview = () => {
|
|||
export const getSituation = () => {
|
||||
return request({ url: '/pcm/v1/monitoring/schedule/situation', method: 'get' })
|
||||
}
|
||||
|
||||
export const getCpList = () => {
|
||||
return request({ url: '/ai4m/v1/screen/resources', method: 'get' })
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,12 @@ export const addApp = (data) => {
|
|||
export const addHpcTask = (data) => {
|
||||
return request({ url: '/pcm/v1/hpc/commitHpcTask', method: 'post', data })
|
||||
}
|
||||
export const uploadVaspContent = (data) => {
|
||||
return request({ url: '/ai4m/v1/sftp/upload', method: 'post', data })
|
||||
}
|
||||
export const downloadVaspContent = (params) => {
|
||||
return request({ url: '/ai4m/v1/sftp/download', method: 'get', params })
|
||||
}
|
||||
export const addVirtualMachine = (data) => {
|
||||
return request({ url: '/pcm/v1/core/commitVmTask', method: 'post', data })
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
|
|
@ -99,6 +99,17 @@ export const constantRoutes = [
|
|||
component: () => import('@/views/monitorSelectPcm/index'),
|
||||
meta: { title: 'monitorSelectPcm' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/resourceList',
|
||||
component: () => import('@/views/cluster/resourceList'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/monitorSelectDev',
|
||||
component: () => import('@/views/monitorSelectDev/index'),
|
||||
meta: { title: 'monitorSelectDev' },
|
||||
hidden: true
|
||||
}
|
||||
// {
|
||||
// path: '/resourceList',
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@
|
|||
<div>
|
||||
<Navbar />
|
||||
<el-card class="list-detail">
|
||||
<el-page-header content="资源清单" @back="goBack" />
|
||||
<el-page-header content="算力清单" @back="goBack" />
|
||||
<List
|
||||
ref="multipleTable"
|
||||
class="multipleTable"
|
||||
:columns="columns"
|
||||
:pagination="false"
|
||||
func-name="getServerResourceData"
|
||||
list-key="data"
|
||||
:get-list-action="getCpList"
|
||||
/>
|
||||
</el-card>
|
||||
</div>
|
||||
|
|
@ -17,34 +18,38 @@
|
|||
<script>
|
||||
import List from '@/components/list'
|
||||
import Navbar from '@/layout/components/Navbar'
|
||||
import { getCpList } from '@/api/pcm/dashboard'
|
||||
|
||||
export default {
|
||||
components: { List, Navbar },
|
||||
data() {
|
||||
return {
|
||||
getCpList,
|
||||
columns: [
|
||||
{ prop: 'name', label: '资产名称' },
|
||||
{ prop: 'ip', label: 'ip' },
|
||||
{ prop: 'publicIp', label: '公网ip' },
|
||||
{ prop: 'hpcPartition', label: '超算队列' },
|
||||
{ prop: 'cpuName', label: 'cpu名称' },
|
||||
{ prop: 'cpuGHz', label: 'cpu单核主频' },
|
||||
{ prop: 'cpuCores', label: 'cpu单节点核心数' },
|
||||
{ prop: 'cpuSingleCycle', label: 'cpu单周期指令执行数' },
|
||||
{ prop: 'cpuGFlops', label: 'cpu理论峰值/GFlops' },
|
||||
{ prop: 'totalThreads', label: 'cpu单节点线程数' },
|
||||
{ prop: 'gpuDcu', label: 'gpu或dcu名称' },
|
||||
{ prop: 'gpuGFlops', label: 'gpu理论峰值/GFlops' },
|
||||
{ prop: 'memory', label: this.$t('page.memory') },
|
||||
{ prop: 'num', label: '节点数' },
|
||||
{ prop: 'region', label: '地域' },
|
||||
{ prop: 'flops', width: 140, label: '理论峰值/GFlops' }
|
||||
{ prop: 'name', label: '名称' },
|
||||
// { prop: 'ip', label: 'ip' },
|
||||
// { prop: 'publicIp', label: '公网ip' },
|
||||
// { prop: 'hpcPartition', label: '超算队列' },
|
||||
// { prop: 'cpuName', label: 'cpu名称' },
|
||||
// { prop: 'cpuGHz', label: 'cpu单核主频' },
|
||||
// { prop: 'cpuCores', label: 'cpu单节点核心数' },
|
||||
// { prop: 'cpuSingleCycle', label: 'cpu单周期指令执行数' },
|
||||
// { prop: 'cpuGFlops', label: 'cpu理论峰值/GFlops' },
|
||||
// { prop: 'totalThreads', label: 'cpu单节点线程数' },
|
||||
// { prop: 'gpuDcu', label: 'gpu或dcu名称' },
|
||||
// { prop: 'gpuGFlops', label: 'gpu理论峰值/GFlops' },
|
||||
// { prop: 'memory', label: '内存' },
|
||||
{ prop: 'resourceType', label: '算力资源类型' },
|
||||
{ prop: 'num', label: '卡数(张)' },
|
||||
{ prop: 'singleTFLOPS', label: '单卡算力(TFLOPS@FP32)' },
|
||||
// { prop: 'region', label: '地域' },
|
||||
{ prop: 'totalPFLOPS', width: 140, label: '算力总量(PFLOPS@FP32)' }
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
this.$router.push('/cluster/clusterMapViews')
|
||||
this.$router.push('/monitorSelectPcm')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,143 @@
|
|||
<template>
|
||||
<div class="chainList">
|
||||
<ul class="chain" :style="'width: '+ blockChainList*7 + 'vw'">
|
||||
<li v-for="(item, index) in blockChainList" :key="index" class="chainItem">
|
||||
<div class="item" @click="goChain" />
|
||||
<div class="itemChain" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
blockChainList: [
|
||||
{
|
||||
name: ''
|
||||
},
|
||||
{
|
||||
name: ''
|
||||
},
|
||||
{
|
||||
name: ''
|
||||
},
|
||||
{
|
||||
name: ''
|
||||
},
|
||||
{
|
||||
name: ''
|
||||
}
|
||||
],
|
||||
active: 0,
|
||||
timer: ''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
const vw = window.innerWidth / 100
|
||||
const elwrapper = document.getElementsByClassName('chainList')[0]
|
||||
elwrapper.style.width = '25vw'
|
||||
const elBody = document.getElementsByClassName('chain')[0]
|
||||
const elRow = document.getElementsByClassName('chainItem')
|
||||
for (const node of elRow) {
|
||||
node.style.width = '7vw'
|
||||
}
|
||||
elBody.style.left = 0
|
||||
elBody.style.transactionDuration = '2000ms'
|
||||
this.timer = setInterval(() => {
|
||||
if (this.active < parseInt(this.blockChainList.length) - 2) {
|
||||
this.active += 1
|
||||
elBody.style.left = parseInt(elBody.style.left) - parseInt(vw * 3.5) + 'px'
|
||||
} else {
|
||||
if (this.isClear) {
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
// if (this.isAgain) {
|
||||
this.active = 0
|
||||
elBody.style.left = 0
|
||||
// } else {
|
||||
// clearInterval(this.timer)
|
||||
// }
|
||||
}
|
||||
}, '5000')
|
||||
})
|
||||
},
|
||||
destroyed() {
|
||||
clearInterval(this.timer)
|
||||
},
|
||||
methods: {
|
||||
goChain() {
|
||||
this.$store.dispatch('user/setRouteType', 'blockChain')
|
||||
this.$router.push({ path: '/blockChain/blockList' })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.chainList{
|
||||
width: 100%;
|
||||
height: 6vh;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
padding: 0 10px;
|
||||
|
||||
ul {
|
||||
width: 1000px;
|
||||
height: 6vh;
|
||||
list-style: none;
|
||||
// overflow-x: auto;
|
||||
white-space: nowrap;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
transition:left 1s ease-in-out;
|
||||
left: 0;
|
||||
}
|
||||
li{
|
||||
width: 7vw;
|
||||
height: 6vh;
|
||||
display: block;
|
||||
float: left;
|
||||
.item{
|
||||
width: 50%;
|
||||
height: 6vh;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
background: url('../../../assets/monitor/chainItem.png') center no-repeat;
|
||||
background-size: contain;
|
||||
float: left;
|
||||
position: relative;
|
||||
.data{
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
z-index: 99;
|
||||
border: 1px solid rgba(62, 223, 252, 1);
|
||||
background-color: rgba(1, 14, 41, 0.8);
|
||||
color: #ffffff;
|
||||
// display: none;
|
||||
}
|
||||
&:hover{
|
||||
background-image: url('../../../assets/monitor/chainItemClick.png');
|
||||
// background-position: -1px -1px;
|
||||
.data{
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
.itemChain{
|
||||
width: 50%;
|
||||
height: 1vh;
|
||||
margin-top: 2vh;
|
||||
float: left;
|
||||
// position: absolute;
|
||||
background: url('../../../assets/monitor/chain.png') center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
<template>
|
||||
<!-- 计算域信息 -->
|
||||
<div style="height:100%">
|
||||
<el-row class="top">
|
||||
<el-col :span="10"><div class="img" /></el-col>
|
||||
<el-col :span="14">
|
||||
<div class="text">
|
||||
<el-carousel direction="vertical" :autoplay="true" @change="changeItem">
|
||||
<el-carousel-item v-for="(item, index) in areaItem" :key="'areaItem' + index" class="areaList">
|
||||
<div class="area">{{ item.domainName || 'DomainName' }}</div>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<span>资源类型:</span>
|
||||
</td>
|
||||
<td>
|
||||
{{ item.resourceType }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span>适配技术栈:</span>
|
||||
</td>
|
||||
<td>
|
||||
{{ item.stack }}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row class="bottom">
|
||||
<el-col :span="10">
|
||||
<div id="radarChart" ref="radarChart" style="width: 100%; height: 16vh" />
|
||||
</el-col>
|
||||
<el-col :span="14">
|
||||
<div class="text">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<span>本地存储</span>
|
||||
</td>
|
||||
<td>
|
||||
<el-progress :stroke-width="8" :percentage="Number(computePercent.diskUsage)" />
|
||||
</td>
|
||||
<td>
|
||||
<span>/ {{ computePercent.diskTotal }} GB</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span>节点数</span>
|
||||
</td>
|
||||
<td>
|
||||
<el-progress :stroke-width="8" :percentage="Number(computePercent.nodeUsage)" />
|
||||
</td>
|
||||
<td>
|
||||
<span> / {{ computePercent.nodeTotal }} 个</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span>内存</span>
|
||||
</td>
|
||||
<td>
|
||||
<el-progress :stroke-width="8" :percentage="Number(computePercent.memoryUsage)" />
|
||||
</td>
|
||||
<td>
|
||||
<span>/ {{ computePercent.memoryTotal }} GB</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span>cpuUsage</span>
|
||||
</td>
|
||||
<td>
|
||||
<el-progress :stroke-width="8" :percentage="Number(computePercent.cpuUsage)" />
|
||||
</td>
|
||||
<td>
|
||||
<span>/ {{ computePercent.cpuTotal }} Core</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import { getComputeArea } from '@/api/container/monitorSelect.js'
|
||||
import { debounce } from '@/utils'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
areaItem: [],
|
||||
radarChart: undefined,
|
||||
computePercent: {
|
||||
diskUsage: 0,
|
||||
memoryUsage: 0,
|
||||
nodeUsage: 0,
|
||||
cpuUsage: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
getComputeArea().then((res) => {
|
||||
this.areaItem = res.data.domainResourceList
|
||||
const charts = echarts.init(this.$refs.radarChart)
|
||||
const { diskUsage, memoryUsage, nodeUsage, cpuUsage } = this.areaItem[0]
|
||||
this.computePercent = this.areaItem[0]
|
||||
charts.setOption(this.returnRadarChart([diskUsage, memoryUsage, nodeUsage, cpuUsage]))
|
||||
window.addEventListener('resize', debounce(() => {
|
||||
charts.resize()
|
||||
}, 100))
|
||||
this.radarChart = charts
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
changeItem(e) {
|
||||
const { diskUsage, memoryUsage, nodeUsage, cpuUsage } = this.areaItem[e]
|
||||
this.computePercent = this.areaItem[e]
|
||||
this.radarChart.setOption(this.returnRadarChart([diskUsage, memoryUsage, nodeUsage, cpuUsage]))
|
||||
},
|
||||
fontSize(rem) {
|
||||
const scale = window.innerHeight / 900
|
||||
console.log(scale)
|
||||
return scale >= 1 ? 16 * rem : 14 * rem
|
||||
},
|
||||
returnRadarChart(data) {
|
||||
return {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
backgroundColor: '#000033',
|
||||
textStyle: { color: '#fff' },
|
||||
borderWidth: 0,
|
||||
position: 'right'
|
||||
},
|
||||
radar: {
|
||||
radius: '60%',
|
||||
shape: 'circle',
|
||||
splitArea: {
|
||||
show: false,
|
||||
areaStyle: {
|
||||
color: ['rgba(255,255,255,0.45)', 'rgba(255,255,255,0.35)', 'rgba(255,255,255,0.25)', 'rgba(255,255,255,0.15)', 'rgba(255,255,255,0.1)']
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(14, 55, 100, 1)'
|
||||
}
|
||||
},
|
||||
axisLine: { // 坐标轴线
|
||||
show: false // 默认显示,属性show控制显示与否
|
||||
},
|
||||
name: { // (圆外的标签)雷达图每个指示器名称的配置项。
|
||||
formatter: '{value}',
|
||||
textStyle: {
|
||||
fontSize: this.fontSize(0.7)
|
||||
}
|
||||
},
|
||||
indicator: [
|
||||
{ name: '本地存储', max: 100 },
|
||||
{ name: '内存', max: 100 },
|
||||
{ name: '节点数', max: 100 },
|
||||
{ name: 'cpuUsage', max: 100 }
|
||||
],
|
||||
nameGap: 4
|
||||
},
|
||||
series: [{
|
||||
name: '计算域信息',
|
||||
type: 'radar',
|
||||
symbol: 'none',
|
||||
data: [
|
||||
{
|
||||
value: data
|
||||
}
|
||||
],
|
||||
itemStyle: {
|
||||
color: ['red'],
|
||||
opacity: 1
|
||||
},
|
||||
lineStyle: {
|
||||
color: 'rgba(35, 162, 236, 0.8)',
|
||||
type: 'dashed'
|
||||
},
|
||||
areaStyle: // 雷达图辐射区域的样式
|
||||
{
|
||||
color: 'rgba(1, 154, 251, 0.5)'
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.top{
|
||||
// display: flex;
|
||||
// justify-content: space-between;
|
||||
// padding: 5px 3%;
|
||||
margin: 1vh 0;
|
||||
::v-deep .el-carousel__indicators{
|
||||
display: none;
|
||||
}
|
||||
.img{
|
||||
height: 8vh;
|
||||
background: url('../../../assets/images/monitorSelect/computingArea.png') center no-repeat;
|
||||
background-size: auto 100%;
|
||||
// margin-left: 3vw;
|
||||
}
|
||||
}
|
||||
|
||||
.text{
|
||||
// width: 65%;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
height: 8vh;
|
||||
.areaList{
|
||||
height: 8vh;
|
||||
}
|
||||
span{
|
||||
font-size: 1rem;
|
||||
}
|
||||
.area{
|
||||
height: 2vh;
|
||||
line-height: 2vh;
|
||||
font-size: 1.13rem;
|
||||
margin: 0.4vh 0;
|
||||
background-image: linear-gradient(0deg, #00C0FF 0%, #ffffff 100%);
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
table{
|
||||
padding: 0;
|
||||
border-spacing: 0px;
|
||||
width: 100%;
|
||||
td{
|
||||
@media screen and (max-height: 900px) {
|
||||
transform: scale(0.8);
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
color: #DDDDDD;
|
||||
height: 3vh;
|
||||
}
|
||||
}
|
||||
}
|
||||
.bottom{
|
||||
margin-top: 2vh;
|
||||
.text{
|
||||
margin-top: 1.5vh;
|
||||
height: 14vh;
|
||||
}
|
||||
table tr td:nth-child(2) {
|
||||
padding-right: 2.5rem;
|
||||
}
|
||||
span{
|
||||
margin: 0;
|
||||
// height: 2.4vh;
|
||||
// line-height: 3.4vh;
|
||||
// @media screen and (max-height: 900px) {
|
||||
// transform: scale(0.8);
|
||||
// transform-origin: 0 0;
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
::v-deep {
|
||||
.el-progress{
|
||||
height: 2.4vh;
|
||||
line-height: 2.4vh;
|
||||
}
|
||||
.el-progress-bar{
|
||||
margin: 0;
|
||||
line-height: 2.5rem;
|
||||
margin-right: 0px;
|
||||
padding-right: 0px;
|
||||
margin-left: -10px;
|
||||
}
|
||||
.el-progress__text{
|
||||
color: white;
|
||||
font-size: 0.5rem!important;
|
||||
}
|
||||
.el-progress-bar__outer {
|
||||
background-color: rgba(135, 189, 245, 0.2);
|
||||
}
|
||||
.el-progress-bar__inner{
|
||||
background-image: linear-gradient(90deg, #419eff, #00d9a6);
|
||||
}
|
||||
}
|
||||
// @media screen and (min-width: 1921px) {
|
||||
// .top{
|
||||
// .img{
|
||||
// width: auto;
|
||||
// height: 100%;
|
||||
// }
|
||||
// .text{
|
||||
// .area{
|
||||
// font-size: 20px;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
<template>
|
||||
<!-- 算力中心总数 -->
|
||||
<div>
|
||||
<div class="two">
|
||||
<div v-for="(item, index) in dataArray" :key="'data'+index">
|
||||
<p class="title">{{ item.name }}</p>
|
||||
<div class="num">{{ item.value }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dataArray: [
|
||||
{
|
||||
name: '算力中心总数(计算域)',
|
||||
value: 34
|
||||
},
|
||||
{
|
||||
name: '已接入算力 POps@FP16',
|
||||
value: '112.06'
|
||||
},
|
||||
{
|
||||
name: '接入集群数',
|
||||
value: '48'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.two{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 10px;
|
||||
// text-align: center;
|
||||
>div{
|
||||
padding: 10px;
|
||||
padding-top: 0;
|
||||
background: url('../../../assets/images/monitorSelect/dataBg.png') no-repeat left;
|
||||
background-size: auto 100%;
|
||||
}
|
||||
.title{
|
||||
font-size: 1.1rem;
|
||||
margin: 0.5rem;
|
||||
margin-bottom: 0.3rem;
|
||||
letter-spacing: 0.1rem;
|
||||
font-weight: bold;
|
||||
color: #DDDDDD;
|
||||
}
|
||||
.num{
|
||||
font-size: 1.9rem;
|
||||
font-family: Impact;
|
||||
font-weight: 400;
|
||||
// padding-bottom: 5px;
|
||||
text-align: right;
|
||||
width: 80%;
|
||||
// text-indent: 130%;
|
||||
letter-spacing: 0.1rem;
|
||||
display: inline-block;
|
||||
padding: 0 15px 3px;
|
||||
}
|
||||
}
|
||||
|
||||
// @media screen and (min-width: 1921px) {
|
||||
// .one{
|
||||
// background-size: 39px 39px;
|
||||
// font-size: 20px;
|
||||
// .num{
|
||||
// font-size: 38px;
|
||||
// }
|
||||
// }
|
||||
// .two{
|
||||
// p{
|
||||
// margin: 16px 0 ;
|
||||
// }
|
||||
// .title{
|
||||
// font-size: 14px;
|
||||
// }
|
||||
// .num{
|
||||
// font-size: 27px;
|
||||
// padding: 0 17px 5px;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
<!-- 算力使用趋势 -->
|
||||
<template>
|
||||
<div :id="id" ref="echart" style="width: 100%; height: 80%" />
|
||||
</template>
|
||||
<script>
|
||||
import { debounce } from '@/utils'
|
||||
|
||||
export default {
|
||||
name: 'LineChart',
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
type: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
Data: { used: [], xData: [] }
|
||||
// xDataNumber: 120,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data: {
|
||||
handler(newValue, oldValue) {
|
||||
// console.log(newValue)
|
||||
const TempData = JSON.parse(JSON.stringify(newValue))
|
||||
this.Data.used = TempData.used
|
||||
this.Data.xData = TempData.xData
|
||||
this.drawLine()
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// this.Data = { used: [59688.1, 59252.5, 59189.0, 55766.5, 55537.2, 54804.4, 52764.9], xData: ["2022-06-30", "2022-07-31", "2022-07-31", "2022-08-31", "2022-09-30", "2022-10-31", "2022-11-30"] }
|
||||
this.$nextTick(() => {
|
||||
this.drawLine()
|
||||
})
|
||||
},
|
||||
destroyed() {
|
||||
clearInterval(this.timer)
|
||||
},
|
||||
methods: {
|
||||
fontSize(rem) {
|
||||
const scale = window.innerHeight / 900
|
||||
return scale >= 1 ? 16 * rem : 12 * rem
|
||||
},
|
||||
drawLine() {
|
||||
const scaleRate = window.innerHeight / 1080 >= 1
|
||||
// 基于准备好的dom,初始化echarts实例
|
||||
const chart = this.$echarts.init(this.$refs.echart)
|
||||
var option
|
||||
option = {
|
||||
title: {
|
||||
text: '',
|
||||
textStyle: {
|
||||
color: '#008B45'
|
||||
}
|
||||
},
|
||||
color: ['rgba(79, 172, 254, 1)'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
show: false
|
||||
},
|
||||
backgroundColor: '#000033',
|
||||
textStyle: { fontSize: this.fontSize(0.7), color: '#fff' },
|
||||
borderWidth: 0
|
||||
},
|
||||
grid: {
|
||||
right: '5%',
|
||||
bottom: '25%',
|
||||
top: scaleRate ? '15%' : '20%',
|
||||
left: '13%'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: this.Data.xData,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(135, 189, 245, 0.1)'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
interval: 28,
|
||||
// rotate: -18,
|
||||
// padding: [1, 0, 0, -10],
|
||||
margin: scaleRate ? 14 : 10,
|
||||
textStyle: {
|
||||
fontSize: this.fontSize(0.75),
|
||||
lineHeight: scaleRate ? 20 : 10,
|
||||
color: '#DDDDDD',
|
||||
fontFamily: 'Source Han Sans CN'
|
||||
},
|
||||
formatter: function(params) {
|
||||
return params.slice(5).replaceAll('-', '/')
|
||||
}
|
||||
// formatter: function(params) {
|
||||
// switch (params) {
|
||||
// case '2023-04-30':
|
||||
// return params.slice(2).replaceAll('-', '/')
|
||||
// case '2023-03-31':
|
||||
// return params.slice(2).replaceAll('-', '/')
|
||||
// case '2023-02-28':
|
||||
// return params.slice(2).replaceAll('-', '/')
|
||||
// case '2023-01-31':
|
||||
// return params.slice(2).replaceAll('-', '/')
|
||||
// case '2022-12-31':
|
||||
// return params.slice(2).replaceAll('-', '/')
|
||||
// case '2022-11-30':
|
||||
// return params.slice(2).replaceAll('-', '/')
|
||||
// case '2022-10-31':
|
||||
// return params.slice(2).replaceAll('-', '/')
|
||||
// case '2022-09-30':
|
||||
// return params.slice(2).replaceAll('-', '/')
|
||||
// default:
|
||||
// // return params.slice(2).replaceAll('-', '/')
|
||||
// }
|
||||
// }
|
||||
},
|
||||
axisTick: {
|
||||
// x轴刻度相关设置
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: this.config.unit,
|
||||
// nameTextStyle: { // 关键代码
|
||||
// padding: this.config.unit.length > 7 ? [0, 0, 0, 45] : [0, 0, 0, 0]
|
||||
// },
|
||||
nameTextStyle: {
|
||||
color: '#aaa',
|
||||
fontSize: this.fontSize(0.75),
|
||||
nameLocation: 'start'
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: 'rgba(135, 189, 245, 0.1)'
|
||||
}
|
||||
},
|
||||
nameGap: 10,
|
||||
data: [],
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
interval: 0,
|
||||
align: 'right',
|
||||
textStyle: {
|
||||
fontSize: this.fontSize(0.75),
|
||||
color: 'rgba(221, 221, 221, 1)',
|
||||
fontFamily: 'Source Han Sans CN'
|
||||
}
|
||||
},
|
||||
scale: true,
|
||||
min: 0,
|
||||
splitNumber: 3
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: this.config.status[0] ? this.config.status[0] : '',
|
||||
type: 'line',
|
||||
symbol: 'none',
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
data: this.Data.used,
|
||||
areaStyle: {
|
||||
opacity: 1,
|
||||
color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(0, 242, 254, 1)' // 0% 处的颜色
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(79, 172, 254, 1)' // 100% 处的颜色
|
||||
}
|
||||
])
|
||||
}
|
||||
}
|
||||
],
|
||||
animation: true,
|
||||
animationDuration: function(idx) {
|
||||
// 越往后的数据时长越大
|
||||
return idx * 500
|
||||
},
|
||||
animationEasing: 'backln'
|
||||
}
|
||||
chart.setOption(option)
|
||||
window.addEventListener('resize', debounce(() => {
|
||||
chart.resize()
|
||||
}, 100))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,306 @@
|
|||
|
||||
<!-- 算力使用情况 -->
|
||||
<template>
|
||||
<div :id="id" ref="echart" style="width: 95%; height: 85%" />
|
||||
</template>
|
||||
<script>
|
||||
import { debounce } from '@/utils'
|
||||
|
||||
export default {
|
||||
name: 'Histogram',
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => { }
|
||||
},
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
timer: null,
|
||||
Data: {
|
||||
unused: [], used: [], xData: []
|
||||
},
|
||||
barWidth: '40%',
|
||||
Max: 0
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data: {
|
||||
handler(newValue, oldValue) {
|
||||
const Data = { unused: [], used: [], xData: [] }
|
||||
clearInterval(this.timer)
|
||||
const TempData = JSON.parse(JSON.stringify(newValue))
|
||||
// if (TempData.xData.length <= 5) {
|
||||
// this.barWidth = this.fontSize(1.62)
|
||||
// } else {
|
||||
// this.barWidth = this.fontSize(0.81)
|
||||
// }
|
||||
Data.xData = TempData.xData
|
||||
Data.used = TempData.used ? TempData.used : []
|
||||
Data.unused = TempData.unused ? TempData.unused : []
|
||||
if (Data.unused.length !== 0) { this.Max = Math.max(...Data.used) + Math.max(...Data.unused) } else { this.Max = Math.max(...Data.used) }
|
||||
const num = this.digit(this.Max)
|
||||
let number = this.Max.toString()[0]
|
||||
number = parseFloat(number)
|
||||
if (number < 9) {
|
||||
number++
|
||||
if (num <= 3) { this.Max = number + '00' } else if (num <= 4) { this.Max = number + '000' } else if (num <= 5) { this.Max = number + '0000' }
|
||||
} else {
|
||||
if (num <= 3) { this.Max = 1000 } else if (num <= 4) { this.Max = 10000 } else if (num <= 5) { this.Max = 100000 }
|
||||
}
|
||||
if (TempData.xData.length <= 5) {
|
||||
this.Data = Data
|
||||
this.drawLine()
|
||||
} else {
|
||||
this.Data.unused = Data.unused.slice(0, 5)
|
||||
this.Data.used = Data.used.slice(0, 5)
|
||||
this.Data.xData = Data.xData.slice(0, 5)
|
||||
this.drawLine()
|
||||
this.timer = setInterval(() => {
|
||||
const unused = Data.unused.shift()
|
||||
const used = Data.used.shift()
|
||||
const xData = Data.xData.shift()
|
||||
Data.unused.push(unused)
|
||||
Data.used.push(used)
|
||||
Data.xData.push(xData)
|
||||
this.Data.unused = Data.unused.slice(0, 5)
|
||||
this.Data.used = Data.used.slice(0, 5)
|
||||
this.Data.xData = Data.xData.slice(0, 5)
|
||||
this.drawLine()
|
||||
}, 3000)
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// this.Data = {
|
||||
// used: [1400, 700, 200, 800, 600], xData
|
||||
// : ["鹏城云脑一", "云脑二号智算", "武汉智算", "北京大学GPU智算","中科类脑智算"]
|
||||
// }
|
||||
this.$nextTick(() => {
|
||||
this.drawLine()
|
||||
})
|
||||
},
|
||||
destroyed() {
|
||||
clearInterval(this.timer)
|
||||
},
|
||||
methods: {
|
||||
fontSize(rem) {
|
||||
const scale = window.innerHeight / 900
|
||||
return scale >= 1 ? 16 * rem : 12 * rem
|
||||
},
|
||||
drawLine() {
|
||||
const scaleRate = window.innerHeight / 900 >= 1
|
||||
const chart = this.$echarts.init(this.$refs.echart)
|
||||
var option
|
||||
option = {
|
||||
title: {
|
||||
text: '',
|
||||
textStyle: {
|
||||
color: '#008B45'
|
||||
},
|
||||
padding: [10, 0, 0, 10] // 位置
|
||||
},
|
||||
color: ['rgba(135, 189, 245, 1)', 'rgba(62, 223, 252, 1)', 'rgba(5, 155, 252, 1)'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'none',
|
||||
show: false
|
||||
},
|
||||
backgroundColor: '#000033',
|
||||
textStyle: { fontSize: this.fontSize(0.7), color: '#fff' },
|
||||
borderWidth: 0
|
||||
},
|
||||
legend: {
|
||||
right: '0',
|
||||
itemWidth: 15,
|
||||
selectedMode: false, // 是否允许点击
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: this.fontSize(0.75),
|
||||
fontFamily: 'Source Han Sans CN'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
right: '1%',
|
||||
bottom: '20%',
|
||||
top: scaleRate ? '15%' : '20%',
|
||||
left: '15%'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: this.Data.xData,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(135, 189, 245, 0.1)'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
interval: 0,
|
||||
textStyle: {
|
||||
fontSize: this.fontSize(0.75),
|
||||
lineHeight: scaleRate ? 20 : 10,
|
||||
color: 'rgba(221, 221, 221, 1)',
|
||||
fontFamily: 'Source Han Sans CN'
|
||||
},
|
||||
margin: scaleRate ? (this.config.unit.length > 10 ? 35 : 8) : 10,
|
||||
formatter: function(params) {
|
||||
var provideNumber = 4 // 一行显示几个字
|
||||
return params.slice(0, provideNumber) + (params.length > provideNumber ? '...' : '')
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
// x轴刻度相关设置
|
||||
alignWithLabel: true
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
// offset: this.config.unit.length > 10 ? -40 : 0,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: 'rgba(135, 189, 245, 0.1)'
|
||||
}
|
||||
},
|
||||
name: this.config.unit,
|
||||
nameTextStyle: {
|
||||
color: '#aaa',
|
||||
padding: [0, 10, 0, 0],
|
||||
fontSize: this.fontSize(0.75),
|
||||
nameLocation: 'start'
|
||||
},
|
||||
nameGap: 10,
|
||||
data: [],
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(135, 189, 245, 0.1)'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
show: true,
|
||||
textStyle: {
|
||||
fontSize: this.fontSize(0.75),
|
||||
color: 'rgba(221, 221, 221, 1)',
|
||||
fontFamily: 'Source Han Sans CN'
|
||||
}
|
||||
},
|
||||
scale: true,
|
||||
min: 0,
|
||||
max: 30000,
|
||||
splitNumber: 3
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: this.config.status[0] ? this.config.status[0] : '',
|
||||
type: 'bar',
|
||||
stack: 'total',
|
||||
barWidth: this.barWidth,
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: this.Data.used ? this.Data.used : [],
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgb(24, 144, 255)' // 0% 处的颜色
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(24, 144, 255,0.5)' // 100% 处的颜色
|
||||
}
|
||||
],
|
||||
global: false // 缺省为 false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: this.config.status[1] ? this.config.status[1] : '',
|
||||
type: 'bar',
|
||||
stack: 'total',
|
||||
barWidth: this.barWidth,
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: this.Data.unused !== [] ? this.Data.unused : [],
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(30, 231, 231,0.5)' // 0% 处的颜色
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgb(30, 231, 231)' // 100% 处的颜色
|
||||
}
|
||||
],
|
||||
global: false // 缺省为 false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
animation: true,
|
||||
animationDuration: function(idx) {
|
||||
// 越往后的数据时长越大
|
||||
return idx * 100
|
||||
},
|
||||
animationEasing: 'backln'
|
||||
}
|
||||
|
||||
chart.setOption(option)
|
||||
|
||||
window.addEventListener('resize', debounce(() => {
|
||||
chart.resize()
|
||||
}, 100))
|
||||
},
|
||||
digit(val) {
|
||||
let num = Math.trunc(val)
|
||||
// const number = num.toString() // 把数字转换成字符串
|
||||
// var temp = num
|
||||
var count = 0
|
||||
if (num === 0) {
|
||||
return 0
|
||||
} else {
|
||||
while (num !== 0) {
|
||||
count++ // 统计位数;
|
||||
num = parseInt(num / 10) // 赋值给 num 以备下次循环使用;
|
||||
}
|
||||
return count
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
<template>
|
||||
<div class="taskArea">
|
||||
<el-row class="taskDiv">
|
||||
<el-col v-for="(item,index) in taskDetail" :key="'task'+index" :span="8">
|
||||
<div class="num">{{ item.num }}</div>
|
||||
<div class="name">{{ item.name }}</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<dt-srcoll v-if="fresh" class="scrollList" :new-data="dutyRateData" :menu-data="menuData" :line-height="7" :is-again="true" :table-height="37" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import DtSrcoll from '../components/scroll'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DtSrcoll
|
||||
},
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
taskDetail: [
|
||||
{
|
||||
name: '运行任务合计',
|
||||
num: 0
|
||||
},
|
||||
{
|
||||
name: '运行卡时数',
|
||||
num: 0
|
||||
},
|
||||
{
|
||||
name: '运行时长',
|
||||
num: 0
|
||||
}
|
||||
],
|
||||
menuData: [ // 表格内容
|
||||
{
|
||||
name: '作业名称',
|
||||
prop: 'name'
|
||||
},
|
||||
{
|
||||
name: '作业状态',
|
||||
prop: 'status'
|
||||
},
|
||||
{
|
||||
name: '策略',
|
||||
prop: 'strategy'
|
||||
},
|
||||
{
|
||||
name: '协同状态',
|
||||
prop: 'synergyStatus'
|
||||
},
|
||||
{
|
||||
name: '承接方',
|
||||
prop: 'serviceName'
|
||||
}
|
||||
],
|
||||
dutyRateData: [],
|
||||
fresh: false
|
||||
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data: {
|
||||
handler(newValue, oldValue) {
|
||||
this.fresh = false
|
||||
this.taskDetail[0].num = newValue.totalCount
|
||||
this.taskDetail[1].num = newValue.cardTime
|
||||
this.taskDetail[2].num = newValue.totalRunTime
|
||||
this.dutyRateData = newValue.tableData.map(e => { e.strategy = '时间优先'; return e })
|
||||
this.$nextTick(() => {
|
||||
this.fresh = true
|
||||
})
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.taskArea{
|
||||
height: 29vh;
|
||||
}
|
||||
.scrollList{
|
||||
height: 32vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
.taskDiv{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
text-align: center;
|
||||
margin-bottom: 1%;
|
||||
// height: calc(100% - 190px);
|
||||
>div{
|
||||
// width: 25%;
|
||||
.num{
|
||||
font-size: 1.5rem;
|
||||
font-family: Impact;
|
||||
color: #FFFFFF;
|
||||
letter-spacing: 0.1rem;
|
||||
// height: 3vh;
|
||||
// line-height: 4vh;
|
||||
height: 30%;
|
||||
line-height: 200%;
|
||||
}
|
||||
.name{
|
||||
font-size: 1rem;
|
||||
letter-spacing: 0.1rem;
|
||||
font-weight: bold;
|
||||
height: 70%;
|
||||
line-height: 300%;
|
||||
background: url('../../../assets/images/monitorSelect/task.png') no-repeat center;
|
||||
background-size: auto 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
::v-deep{
|
||||
.el-table--mini th, .el-table--mini td{
|
||||
// padding: 0.375rem 0;
|
||||
height: 2vh;
|
||||
padding: 0;
|
||||
}
|
||||
.el-table--mini th{
|
||||
height: 4vh;
|
||||
}
|
||||
.el-table thead {
|
||||
font-size: 1rem;
|
||||
}
|
||||
.el-table__body {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
// @media screen and (min-width: 1921px) {
|
||||
// .taskDiv{
|
||||
// margin-bottom: 1%;
|
||||
// >div{
|
||||
// .num{
|
||||
// font-size: 26px;
|
||||
// }
|
||||
// .name{
|
||||
// font-size: 16px;
|
||||
// height: 80px;
|
||||
// line-height: 55px;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
</style>
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
<!-- 计算资源负载 -->
|
||||
<template>
|
||||
<div id="myBarEchart" ref="myBarEchart" style="width: 100%; height: 80%" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import { getTotalAverage } from '@/api/top-menu/TotalNum'
|
||||
import moment from 'moment'
|
||||
import { debounce } from '@/utils'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
const day = [[], [], [], [], [], [], []]
|
||||
for (let i = 0; i < 7; i++) {
|
||||
day[i][0] = moment().subtract(7 - i, 'days').endOf('day').unix()
|
||||
day[i][1] = moment().subtract(7 - i, 'days').endOf('day').format('MMDD')
|
||||
}
|
||||
return {
|
||||
day,
|
||||
cpuAverage: [], // cpu 平均负载
|
||||
ramAverage: [] // 内存平均负载
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
jcceTheme() {
|
||||
return localStorage.getItem('jcceTheme')
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getAllData()
|
||||
},
|
||||
methods: {
|
||||
fontSize(rem) {
|
||||
const scale = window.innerHeight / 900
|
||||
return scale >= 1 ? 16 * rem : 12 * rem
|
||||
},
|
||||
// 获取资源负载状况
|
||||
async getAllData() {
|
||||
await getTotalAverage().then(res => {
|
||||
const data = res.data
|
||||
// cpu 平均负载 (%)
|
||||
const cpuData = data.find(item => item.metric_name === 'cpu_avg_usage').data.result[0].values || []
|
||||
cpuData.forEach(element => {
|
||||
this.cpuAverage.push((element[1] - 0).toFixed(2))
|
||||
// this.date.push(moment(element[0] * 1000).format('MM/DD'))
|
||||
})
|
||||
this.cpuAverage = this.cpuAverage.slice(0, 7)
|
||||
// 内存平均负载 (%)
|
||||
const ramAverage = data.find(item => item.metric_name === 'mem_avg_usage').data.result[0].values || []
|
||||
ramAverage.forEach(element => {
|
||||
this.ramAverage.push(((element[1] - 0) / 1024 / 1024 / 1024).toFixed(2))
|
||||
})
|
||||
this.ramAverage = this.ramAverage.slice(0, 7)
|
||||
})
|
||||
this.initCharts()
|
||||
},
|
||||
// 资源负载状况echart图表
|
||||
initCharts() {
|
||||
const scaleRate = window.innerHeight / 900 >= 1
|
||||
const chart = echarts.init(this.$refs.myBarEchart)
|
||||
// 把配置和数据放这里
|
||||
const legend = ['CPU整体负载', '内存整体负载', 'CPU平均负载', '内存平均负载']
|
||||
// const legend = ['CPU整体负载', '内存整体负载', 'CPU平均负载']
|
||||
chart.setOption({
|
||||
legend: {
|
||||
right: '0',
|
||||
itemWidth: 14,
|
||||
data: legend,
|
||||
itemHeight: scaleRate ? 10 : 2,
|
||||
selectedMode: false, // 是否允许点击
|
||||
textStyle: {
|
||||
color: '#FFFFFF',
|
||||
fontSize: this.fontSize(0.7)
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
right: '12%',
|
||||
bottom: '16%',
|
||||
top: scaleRate ? '25%' : '30%',
|
||||
left: '12%'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
label: {
|
||||
backgroundColor: '#000033'
|
||||
}
|
||||
},
|
||||
backgroundColor: '#000033',
|
||||
textStyle: { fontSize: this.fontSize(0.7), color: '#fff' },
|
||||
borderWidth: 0,
|
||||
formatter: (params) => {
|
||||
let val = params[0].name
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
const unit = params[i].seriesName.indexOf('CPU') > -1 ? '核' : 'GB'
|
||||
val += '<br/>' + params[i].marker + (params[i].seriesName.indexOf('平均') > -1 ? '七日' : '') + params[i].seriesName + ': ' + params[i].value + unit
|
||||
}
|
||||
return val
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: this.day.map(n => n[1]),
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
fontSize: this.fontSize(0.75),
|
||||
color: 'rgba(221, 221, 221, 1)'
|
||||
},
|
||||
interval: 0,
|
||||
margin: scaleRate ? 14 : 10
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(135, 189, 245, 0.01)'
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
name: '单位:核',
|
||||
nameTextStyle: {
|
||||
color: '#aaa',
|
||||
// padding: [0, 10, 0, 0],
|
||||
fontSize: this.fontSize(0.75),
|
||||
nameLocation: 'start'
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
fontSize: this.fontSize(0.75),
|
||||
color: 'rgba(221, 221, 221, 1)'
|
||||
},
|
||||
formatter: '{value}'
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(135, 189, 245, 0.1)'
|
||||
}},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#DDDDDD'
|
||||
}
|
||||
},
|
||||
splitNumber: 3,
|
||||
position: 'left',
|
||||
alignTicks: true
|
||||
},
|
||||
{
|
||||
name: '单位:GB',
|
||||
nameTextStyle: {
|
||||
color: '#aaa',
|
||||
// padding: [0, 10, 0, 0],
|
||||
fontSize: this.fontSize(0.75),
|
||||
nameLocation: 'start'
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
fontSize: this.fontSize(0.75),
|
||||
color: 'rgba(221, 221, 221, 1)'
|
||||
},
|
||||
formatter: '{value}'
|
||||
},
|
||||
position: 'right',
|
||||
alignTicks: true,
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(255,255,255,0.1)'
|
||||
}},
|
||||
splitNumber: 3,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#999999'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
color: '#3282CE',
|
||||
series: [
|
||||
{
|
||||
name: legend[2],
|
||||
data: this.cpuAverage,
|
||||
type: 'line',
|
||||
showSymbol: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 8,
|
||||
itemStyle: {
|
||||
color: '#30BFB6',
|
||||
shadowColor: '#30BFB6',
|
||||
shadowBlur: 8
|
||||
},
|
||||
yAxisIndex: 0,
|
||||
lineStyle: {
|
||||
color: '#30BFB6', // 改变折线颜色
|
||||
width: 1
|
||||
},
|
||||
smooth: true
|
||||
},
|
||||
{
|
||||
name: legend[3],
|
||||
data: this.ramAverage,
|
||||
yAxisIndex: 1,
|
||||
type: 'line',
|
||||
showSymbol: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 8,
|
||||
itemStyle: {
|
||||
color: '#87BDF5',
|
||||
shadowColor: '#87BDF5',
|
||||
shadowBlur: 8
|
||||
},
|
||||
lineStyle: {
|
||||
color: '#87BDF5',
|
||||
width: 1
|
||||
},
|
||||
smooth: true
|
||||
}
|
||||
]
|
||||
})
|
||||
window.addEventListener('resize', debounce(() => {
|
||||
chart.resize()
|
||||
}, 100))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,355 @@
|
|||
<!-- 计算资源负载 -->
|
||||
<template>
|
||||
<div id="myBarEchart" ref="myBarEchart" style="width: 100%; height: 80%" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import { getTotalAverage } from '@/api/top-menu/TotalNum'
|
||||
import moment from 'moment'
|
||||
import { debounce } from '@/utils'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
const day = [[], [], [], [], [], [], []]
|
||||
for (let i = 0; i < 7; i++) {
|
||||
day[i][0] = moment().subtract(7 - i, 'days').endOf('day').unix()
|
||||
day[i][1] = moment().subtract(7 - i, 'days').endOf('day').format('MM/DD')
|
||||
}
|
||||
return {
|
||||
day,
|
||||
ramLoad: [], // 内存整体负载
|
||||
cpuLoad: [], // CPU整体负载
|
||||
cpuAverage: [], // cpu 平均负载
|
||||
ramAverage: [] // 内存平均负载
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
jcceTheme() {
|
||||
return localStorage.getItem('jcceTheme')
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getAllData()
|
||||
},
|
||||
methods: {
|
||||
fontSize(rem) {
|
||||
const scale = window.innerHeight / 900
|
||||
return scale >= 1 ? 16 * rem : 12 * rem
|
||||
},
|
||||
// 获取资源负载状况
|
||||
async getAllData() {
|
||||
await getTotalAverage().then(res => {
|
||||
this.ramLoad = res.data.memoryLoad
|
||||
this.ramAverage = res.data.memoryAvg
|
||||
this.cpuLoad = res.data.cpuLoad
|
||||
this.cpuAverage = res.data.cpuAvg
|
||||
|
||||
// const data = res.data
|
||||
// // 内存整体负载 (GB)
|
||||
// const ramData = data.find(item => item.metric_name === 'mem_total_usage').data.result[0].values || []
|
||||
// ramData.forEach(element => {
|
||||
// this.ramLoad.push(((element[1] - 0) / 1024 / 1024 / 1024).toFixed(2))
|
||||
// // this.date.push(moment(element[0] * 1000).format('MM/DD'))
|
||||
// })
|
||||
// this.ramLoad = this.ramLoad.slice(0, 7)
|
||||
// // CPU整体负载 (Core)
|
||||
// const cpuLoad = data.find(item => item.metric_name === 'cpu_total_usage').data.result[0].values || []
|
||||
// cpuLoad.forEach(element => {
|
||||
// this.cpuLoad.push(((element[1] - 0)).toFixed(2))
|
||||
// })
|
||||
// this.cpuLoad = this.cpuLoad.slice(0, 7)
|
||||
// // cpu 平均负载 (%)
|
||||
// const cpuData = data.find(item => item.metric_name === 'cpu_avg_usage').data.result[0].values || []
|
||||
// cpuData.forEach(element => {
|
||||
// this.cpuAverage.push((element[1] - 0).toFixed(2))
|
||||
// // this.date.push(moment(element[0] * 1000).format('MM/DD'))
|
||||
// })
|
||||
// this.cpuAverage = this.cpuAverage.slice(0, 7)
|
||||
// // 内存平均负载 (%)
|
||||
// const ramAverage = data.find(item => item.metric_name === 'mem_avg_usage').data.result[0].values || []
|
||||
// ramAverage.forEach(element => {
|
||||
// this.ramAverage.push(((element[1] - 0) / 1024 / 1024 / 1024).toFixed(2))
|
||||
// })
|
||||
// this.ramAverage = this.ramAverage.slice(0, 7)
|
||||
})
|
||||
this.initCharts()
|
||||
},
|
||||
// 资源负载状况echart图表
|
||||
initCharts() {
|
||||
const scaleRate = window.innerHeight / 900 >= 1
|
||||
const chart = echarts.init(this.$refs.myBarEchart)
|
||||
// 把配置和数据放这里
|
||||
const legend = ['CPU整体负载', '内存整体负载', 'CPU平均负载', '内存平均负载']
|
||||
// const legend = ['CPU整体负载', '内存整体负载', 'CPU平均负载']
|
||||
chart.setOption({
|
||||
legend: {
|
||||
right: '0',
|
||||
itemWidth: 14,
|
||||
data: legend,
|
||||
itemHeight: scaleRate ? 10 : 2,
|
||||
selectedMode: false, // 是否允许点击
|
||||
textStyle: {
|
||||
color: '#FFFFFF',
|
||||
fontSize: this.fontSize(0.7)
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
right: '12%',
|
||||
bottom: '16%',
|
||||
top: scaleRate ? '25%' : '30%',
|
||||
left: '12%'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
label: {
|
||||
backgroundColor: '#000033'
|
||||
}
|
||||
},
|
||||
backgroundColor: '#000033',
|
||||
textStyle: { fontSize: this.fontSize(0.7), color: '#fff' },
|
||||
borderWidth: 0,
|
||||
formatter: (params) => {
|
||||
let val = params[0].name
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
const unit = params[i].seriesName.indexOf('CPU') > -1 ? '核' : 'GB'
|
||||
val += '<br/>' + params[i].marker + (params[i].seriesName.indexOf('平均') > -1 ? '七日' : '') + params[i].seriesName + ': ' + params[i].value + unit
|
||||
}
|
||||
return val
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: this.day.map(n => n[1]),
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
fontSize: this.fontSize(0.75),
|
||||
color: 'rgba(221, 221, 221, 1)'
|
||||
},
|
||||
interval: 0,
|
||||
margin: scaleRate ? 14 : 10
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(135, 189, 245, 0.01)'
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
name: '单位:核',
|
||||
nameTextStyle: {
|
||||
color: '#aaa',
|
||||
// padding: [0, 10, 0, 0],
|
||||
fontSize: this.fontSize(0.75),
|
||||
nameLocation: 'start'
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
fontSize: this.fontSize(0.75),
|
||||
color: 'rgba(221, 221, 221, 1)'
|
||||
},
|
||||
formatter: '{value}'
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(135, 189, 245, 0.1)'
|
||||
}},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#DDDDDD'
|
||||
}
|
||||
},
|
||||
splitNumber: 3,
|
||||
position: 'left',
|
||||
alignTicks: true
|
||||
},
|
||||
{
|
||||
name: '单位:GB',
|
||||
nameTextStyle: {
|
||||
color: '#aaa',
|
||||
// padding: [0, 10, 0, 0],
|
||||
fontSize: this.fontSize(0.75),
|
||||
nameLocation: 'start'
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
fontSize: this.fontSize(0.75),
|
||||
color: 'rgba(221, 221, 221, 1)'
|
||||
},
|
||||
formatter: '{value}'
|
||||
},
|
||||
position: 'right',
|
||||
alignTicks: true,
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(255,255,255,0.1)'
|
||||
}},
|
||||
splitNumber: 3,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#999999'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
color: '#3282CE',
|
||||
series: [
|
||||
{
|
||||
name: legend[0],
|
||||
type: 'pictorialBar',
|
||||
symbolSize: [12, 3],
|
||||
yAxisIndex: 0,
|
||||
tooltip: {
|
||||
show: false
|
||||
},
|
||||
symbolOffset: [-9, 3],
|
||||
z: 12,
|
||||
color: 'rgba(5, 155, 252, 0.8)',
|
||||
data: this.cpuLoad
|
||||
},
|
||||
{
|
||||
name: legend[0],
|
||||
type: 'pictorialBar',
|
||||
symbolSize: [16, 6],
|
||||
yAxisIndex: 0,
|
||||
tooltip: {
|
||||
show: false
|
||||
},
|
||||
symbolOffset: [-9, 6],
|
||||
z: 12,
|
||||
color: 'rgba(5, 155, 252, 0.5)',
|
||||
data: this.cpuLoad
|
||||
},
|
||||
{
|
||||
name: legend[0],
|
||||
type: 'pictorialBar',
|
||||
symbolSize: [20, 9],
|
||||
yAxisIndex: 0,
|
||||
tooltip: {
|
||||
show: false
|
||||
},
|
||||
symbolOffset: [-9, 9],
|
||||
z: 12,
|
||||
color: 'rgba(5, 155, 252, 0.25)',
|
||||
data: this.cpuLoad
|
||||
},
|
||||
{
|
||||
type: 'bar',
|
||||
name: legend[0],
|
||||
barWidth: '10',
|
||||
yAxisIndex: 0,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: 'rgba(5, 155, 252, 0)' }, { offset: 1, color: 'rgba(5, 155, 252, 1)' }])
|
||||
}
|
||||
},
|
||||
data: this.cpuLoad
|
||||
},
|
||||
{
|
||||
name: legend[1],
|
||||
yAxisIndex: 1,
|
||||
type: 'pictorialBar',
|
||||
symbolSize: [12, 3],
|
||||
tooltip: {
|
||||
show: false
|
||||
},
|
||||
symbolOffset: [9, 3],
|
||||
z: 12,
|
||||
color: 'rgba(62, 223, 252, 1)',
|
||||
data: this.ramLoad
|
||||
},
|
||||
{
|
||||
name: legend[1],
|
||||
yAxisIndex: 1,
|
||||
type: 'pictorialBar',
|
||||
symbolSize: [16, 6],
|
||||
tooltip: {
|
||||
show: false
|
||||
},
|
||||
symbolOffset: [9, 6],
|
||||
z: 12,
|
||||
color: 'rgba(62, 223, 252, 0.5)',
|
||||
data: this.ramLoad
|
||||
},
|
||||
{
|
||||
name: legend[1],
|
||||
yAxisIndex: 1,
|
||||
type: 'pictorialBar',
|
||||
symbolSize: [20, 9],
|
||||
tooltip: {
|
||||
show: false
|
||||
},
|
||||
symbolOffset: [9, 9],
|
||||
z: 12,
|
||||
color: 'rgba(62, 223, 252, 0.25)',
|
||||
data: this.ramLoad
|
||||
},
|
||||
{
|
||||
type: 'bar',
|
||||
name: legend[1],
|
||||
barWidth: '10',
|
||||
barGap: '80%',
|
||||
yAxisIndex: 1,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: 'rgba(5, 155, 252, 0)' }, { offset: 1, color: 'rgba(62, 223, 252, 1)' }])
|
||||
}
|
||||
},
|
||||
data: this.ramLoad
|
||||
},
|
||||
{
|
||||
name: legend[2],
|
||||
data: this.cpuAverage,
|
||||
type: 'line',
|
||||
showSymbol: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 8,
|
||||
itemStyle: {
|
||||
color: '#30BFB6',
|
||||
shadowColor: '#30BFB6',
|
||||
shadowBlur: 8
|
||||
},
|
||||
yAxisIndex: 0,
|
||||
lineStyle: {
|
||||
color: '#30BFB6', // 改变折线颜色
|
||||
width: 1
|
||||
},
|
||||
smooth: true
|
||||
},
|
||||
{
|
||||
name: legend[3],
|
||||
data: this.ramAverage,
|
||||
yAxisIndex: 1,
|
||||
type: 'line',
|
||||
showSymbol: true,
|
||||
symbol: 'circle',
|
||||
symbolSize: 8,
|
||||
itemStyle: {
|
||||
color: '#87BDF5',
|
||||
shadowColor: '#87BDF5',
|
||||
shadowBlur: 8
|
||||
},
|
||||
lineStyle: {
|
||||
color: '#87BDF5',
|
||||
width: 1
|
||||
},
|
||||
smooth: true
|
||||
}
|
||||
]
|
||||
})
|
||||
window.addEventListener('resize', debounce(() => {
|
||||
chart.resize()
|
||||
}, 100))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
<template>
|
||||
<!-- 存储资源用量 -->
|
||||
<div>
|
||||
<div class="unUse use">
|
||||
<div class="data">
|
||||
<p class="num">{{ storageData.storageUsing }}TB</p>
|
||||
<p class="percent"> {{ Math.round(storageData.usingRate*10000) /100 }}%</p>
|
||||
</div>
|
||||
<span class="type">未使用 </span>
|
||||
</div>
|
||||
<div class="used use">
|
||||
<span class="type"> 已使用 </span>
|
||||
<div class="data">
|
||||
<p class="num">{{ storageData.storageUsed }}TB</p>
|
||||
<p class="percent"> {{ Math.round(storageData.usageRate*10000) /100 }}%</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
storageData: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data: {
|
||||
handler(newValue, oldValue) {
|
||||
this.storageData = newValue
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.use{
|
||||
height: 8.5vh;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
margin-top: 1vh;
|
||||
position: relative;
|
||||
.data {
|
||||
width: calc(100% - 14.3vh);
|
||||
background: url(../../../assets/monitor/g-2.png) no-repeat;
|
||||
background-size: 100% 62%;
|
||||
background-position: -1vh 1.3vh;
|
||||
height: 90%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
font-family: PangMenZhengDao;
|
||||
font-weight: 400;
|
||||
.num{
|
||||
font-size: 1.875rem;
|
||||
color: #FFFFFF;
|
||||
line-height: 1.25rem;
|
||||
padding-top: 0.6rem;
|
||||
margin:0 12%;
|
||||
text-align: right;
|
||||
letter-spacing: 0.1rem;
|
||||
}
|
||||
.percent{
|
||||
// float: left;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
line-height: 7.5vh;
|
||||
letter-spacing: 0.1rem;
|
||||
margin: 0;
|
||||
text-indent: 1rem;
|
||||
font-size: 1.2rem;
|
||||
color: #3EDFFC;
|
||||
}
|
||||
// display: block;
|
||||
}
|
||||
.type {
|
||||
display: block;
|
||||
width: 14.3vh;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
background: url(../../../assets/monitor/g-1.png) no-repeat;
|
||||
background-size: auto 100%;
|
||||
text-align: right;
|
||||
line-height: 7.5vh;
|
||||
// padding: 0 10px;
|
||||
}
|
||||
}
|
||||
.unUsed{
|
||||
.type{
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
.used{
|
||||
position:relative;
|
||||
.data{
|
||||
left: 0;
|
||||
-moz-transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
-webkit-transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
-o-transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
z-index: -1;
|
||||
.num, .percent{
|
||||
-moz-transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
-webkit-transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
-o-transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
z-index: -1;
|
||||
}
|
||||
.num{
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
.type{
|
||||
text-align: left;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
background-image: url(../../../assets/monitor/b-1.png);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-table id="dbM" :data="newData" border style="width: 100%" align="center" size="mini" class="customer-table">
|
||||
<el-table-column :label="menuData[0].name" :prop="menuData[0].prop" min-width="70" :show-overflow-tooltip="true" />
|
||||
<el-table-column :label="menuData[1].name" min-width="70" align="center">
|
||||
<template slot-scope="scope">
|
||||
<div v-if="scope.row.status=='Completed'" class="other">已完成</div>
|
||||
<div v-if="scope.row.status=='Running'" class="running">运行中</div>
|
||||
<div v-if="scope.row.status=='Submitted'" class="other">已提交</div>
|
||||
<div v-if="scope.row.status=='Saved'" class="other">已保存</div>
|
||||
<div v-if="scope.row.status=='Failed'" class="pending">失败</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="menuData[2].name" :prop="menuData[2].prop" min-width="50" align="left" :show-overflow-tooltip="true" />
|
||||
<el-table-column :label="menuData[3].name" :prop="menuData[3].prop" min-width="70" align="left" :show-overflow-tooltip="true" />
|
||||
<el-table-column :label="menuData[4].name" :prop="menuData[4].prop" min-width="70" align="left" :show-overflow-tooltip="true" />
|
||||
<slot name="footerTable" />
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'DtSrcoll',
|
||||
props: {
|
||||
newData: {
|
||||
type: Array, // 表格数据
|
||||
default: () => []
|
||||
},
|
||||
menuData: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}, // 表格行内容
|
||||
lineHeight: { // 页面需要显示的行数
|
||||
type: Number,
|
||||
default: 4
|
||||
},
|
||||
rowTime: { // 每一行滚动切换等待的时间(毫秒)
|
||||
type: Number,
|
||||
default: 2000
|
||||
},
|
||||
duration: { // 过渡时间
|
||||
type: Number,
|
||||
default: 500
|
||||
},
|
||||
tableHeight: { // 行高
|
||||
type: Number,
|
||||
default: 33
|
||||
},
|
||||
isClear: { // 数据滚动到最后一行是否停止滚动
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isAgain: { // 数据滚动到最后一行是否重新开始滚动
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isScroll: { // 是否允许内容滚动
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
active: 0,
|
||||
timer: ''
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
newData: {
|
||||
handler(newValue, oldValue) {
|
||||
this.newData = newValue
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.lineHeight)
|
||||
const _this = this
|
||||
this.$nextTick(() => {
|
||||
const vh = window.innerHeight / 100
|
||||
const elwrapper = document.getElementsByClassName('el-table__body-wrapper')[0]
|
||||
elwrapper.style.height = this.lineHeight * 3.95 * 2 + 'vh'
|
||||
const elBody = document.getElementsByClassName('el-table__body')[0]
|
||||
const elRow = document.getElementsByClassName('el-table__row')
|
||||
for (const node of elRow) {
|
||||
node.style.height = '3.95vh'
|
||||
}
|
||||
elBody.style.top = 0
|
||||
elBody.style.transactionDuration = this.duration + 'ms'
|
||||
if (_this.isScroll) {
|
||||
_this.timer = setInterval(() => {
|
||||
if (_this.active < parseInt(_this.newData.length) - parseInt(_this.lineHeight)) {
|
||||
_this.active += 1
|
||||
elBody.style.top = parseInt(elBody.style.top) - parseInt(vh * 4) + 'px'
|
||||
} else {
|
||||
if (this.isClear) {
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
if (_this.isAgain) {
|
||||
_this.active = 0
|
||||
elBody.style.top = 0
|
||||
} else {
|
||||
clearInterval(_this.timer)
|
||||
}
|
||||
}
|
||||
}, _this.rowTime)
|
||||
}
|
||||
})
|
||||
},
|
||||
destroyed() {
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep{
|
||||
|
||||
.el-table__body {
|
||||
position: absolute;
|
||||
transition: all 500ms linear;
|
||||
background-color: transparent !important;
|
||||
color: #fff;
|
||||
font-size: 0.9rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.el-table,
|
||||
.el-table__expanded-cell {
|
||||
color: #fff;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.el-table th,
|
||||
.el-table tr,
|
||||
.el-table td {
|
||||
color: #fff;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
.el-table .cell{
|
||||
line-height: 3.95vh;
|
||||
}
|
||||
.el-table tr:nth-child(even) td{
|
||||
background: rgba(35,185,255,0.06) !important;
|
||||
}
|
||||
.el-table--border,
|
||||
.el-table--group {
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
.el-table td.el-table__cell,
|
||||
.el-table th.el-table__cell.is-leaf {
|
||||
background-color: transparent !important;
|
||||
border: 0px solid transparent !important;
|
||||
}
|
||||
|
||||
.el-table--border,
|
||||
.el-table--group {
|
||||
border: 0px solid transparent !important;
|
||||
}
|
||||
|
||||
.customer-table {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
.el-table__footer-wrapper,
|
||||
.el-table__header-wrapper {
|
||||
font-size: 0.9rem;
|
||||
background: rgba(35,185,255,0.12);
|
||||
}
|
||||
|
||||
.el-table--scrollable-x .el-table__body-wrapper {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 去掉表格单元格边框 */
|
||||
.customer-table th {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.customer-table td,
|
||||
.customer-table th.is-leaf {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* 表格最外边框 */
|
||||
.el-table--border,
|
||||
.el-table--group {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* 头部边框 */
|
||||
.customer-table thead tr th.is-leaf {
|
||||
border: 0px solid #EBEEF5;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.customer-table thead tr th:nth-last-of-type(2) {
|
||||
border-right: 0px solid #EBEEF5;
|
||||
}
|
||||
|
||||
/* 表格最外层边框-底部边框 */
|
||||
.el-table--border::after,
|
||||
.el-table--group::after {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.customer-table::before {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.customer-table .el-table__fixed-right::before,
|
||||
.el-table__fixed::before {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
/* 表格有滚动时表格头边框 */
|
||||
.el-table--border th.gutter:last-of-type {
|
||||
border: 1px solid #EBEEF5;
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.pending, .other, .running {
|
||||
width: 3.625rem;
|
||||
height: 1.3rem;
|
||||
line-height: 1.2rem;
|
||||
background: linear-gradient(90deg, #0BBAFB 0%, #4285EC 100%);
|
||||
border-radius: 1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,826 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="monitor">
|
||||
<div class="top-menu">
|
||||
<div class="menu">
|
||||
<a href="">首页</a>
|
||||
<!-- <a @click="viewMenu()">数算资源</a> -->
|
||||
</div>
|
||||
<!-- <div class="right">
|
||||
<a @click="viewMenu('hpc/hpcOverview')">超算资源</a>
|
||||
<a @click="toMonitor()">监控运维</a>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="top">
|
||||
<div class="top-title">
|
||||
<h1>算网融合智能协同平台</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="floatLeft">
|
||||
<div class="left">
|
||||
<div class="left_1">
|
||||
<div class="title"><p>计算域信息</p></div>
|
||||
<ComputeDomain />
|
||||
</div>
|
||||
<div class="left_2">
|
||||
<div class="title"><p>云际组件状态</p></div>
|
||||
<el-row class="taskDiv">
|
||||
<el-col v-for="(item,index) in taskDetail" :key="'task'+index" :span="12">
|
||||
<div class="num">{{ item.num }}</div>
|
||||
<div class="name">{{ item.name }}</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- <ComputingPowerTrend id="ComputingPowerTrend" :data="tendData" :config="tendConfig" /> -->
|
||||
</div>
|
||||
<div class="left_3">
|
||||
<div class="title"><p>存储资源用量</p></div>
|
||||
<StorageResourceUsage :data="powerData" />
|
||||
<!-- <ComputingPowerUse id="ComputingPowerUse" :data="centerData" :config="statusConfig" /> -->
|
||||
</div>
|
||||
<!-- <div class="left_4">
|
||||
<div class="title"><p>分布记账</p></div>
|
||||
<ChainLink :key="resizeKey" />
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="floatRight">
|
||||
<div class="right">
|
||||
<div class="right_1">
|
||||
<div class="title"> <el-button class="createBtn" type="primary" size="mini" round @click="toHashCat()"><div>典型应用验证</div></el-button><p>累计任务情况</p></div>
|
||||
<CumulativeTasks :data="taskData" />
|
||||
</div>
|
||||
<div class="right_2">
|
||||
<div class="title"><p>计算资源整体负载</p></div>
|
||||
<ResourceLoadWhole />
|
||||
</div>
|
||||
<!-- <div class="right_3">
|
||||
<div class="title"><p>计算资源平均负载</p></div>
|
||||
<ResourceLoadAverage />
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="middle">
|
||||
<ComputingPowerTotal />
|
||||
</div>
|
||||
<Earth :key="resizeKey" :center="{name: monitorSettingForm.center, longitude: Number(monitorSettingForm.centerPosition.split(',')[0]), latitude: Number(monitorSettingForm.centerPosition.split(',')[1])}" />
|
||||
</div>
|
||||
<el-dialog
|
||||
title="创建云际跨域任务"
|
||||
:visible.sync="dialogVisible"
|
||||
width="30%"
|
||||
>
|
||||
<el-upload
|
||||
action="#"
|
||||
:http-request="httpRequest"
|
||||
:limit="1"
|
||||
:on-remove="handleRemove"
|
||||
:file-list="fileList"
|
||||
>
|
||||
<el-button size="small" type="primary">点击选择yaml文件</el-button>
|
||||
</el-upload>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitFile()">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment'
|
||||
import ComputeDomain from './components/ComputeDomain.vue'
|
||||
import ComputingPowerTotal from './components/ComputingPowerTotal.vue'
|
||||
import ResourceLoadWhole from './components/ResourceLoadWhole.vue'
|
||||
import CumulativeTasks from './components/CumulativeTasks.vue'
|
||||
import StorageResourceUsage from './components/StorageResourceUsage.vue'
|
||||
import Earth from '@/views/prometheusMonitor/earthDev'
|
||||
import { getComputePower, getScreenInfo, getCPUsage } from '@/api/container/monitorSelect.js'
|
||||
import { getTaskCount, createScheduleTask } from '@/api/top-menu/TotalNum'
|
||||
import { order } from '@/utils/data-process'
|
||||
import { getMonitorSetting } from '@/api/container/monitorSelect'
|
||||
import { debounce } from '@/utils'
|
||||
export default {
|
||||
components: { ComputeDomain, ComputingPowerTotal, ResourceLoadWhole, CumulativeTasks, StorageResourceUsage, Earth },
|
||||
data() {
|
||||
return {
|
||||
monitorSettingForm: {
|
||||
'title': '广域协同智能计算系统面板',
|
||||
'titleColor': '#409EFF',
|
||||
'mainColor': '',
|
||||
'mainColor2': '',
|
||||
'textColor': '',
|
||||
'backgroundColor': '',
|
||||
'center': '',
|
||||
'centerPosition': '',
|
||||
'provinceBgColor': ''
|
||||
},
|
||||
taskDetail: [
|
||||
{
|
||||
name: 'API每秒请求数 times/s',
|
||||
num: 119.083
|
||||
},
|
||||
{
|
||||
name: 'API请求延迟 ms',
|
||||
num: 2.71
|
||||
},
|
||||
{
|
||||
name: '调度器 调度次数',
|
||||
num: 5
|
||||
},
|
||||
{
|
||||
name: '调度失败的 容器节点',
|
||||
num: 1
|
||||
}
|
||||
],
|
||||
resizeKey: 0,
|
||||
dialogVisible: false,
|
||||
rs: new FormData(),
|
||||
fileList: [],
|
||||
powerData: {},
|
||||
pageSize: 100,
|
||||
taskData: {},
|
||||
currentDate: '',
|
||||
tendData: { used: [], xData: [] },
|
||||
centerData: { used: [], xData: [] },
|
||||
tendConfig: { unit: '单位: 卡时', status: ['使用量'] },
|
||||
statusConfig: { unit: '单位: 卡时', status: ['使用量'] },
|
||||
tabLightList: [
|
||||
{
|
||||
id: 'cluster',
|
||||
title: '容器管理',
|
||||
icon: 'rongqiguanli',
|
||||
path: '/cluster/clusterMapViews'
|
||||
},
|
||||
{
|
||||
id: 'virtual',
|
||||
title: '虚拟机管理',
|
||||
icon: 'xunijiguanlimokuai',
|
||||
path: '/virtual/overview'
|
||||
},
|
||||
{
|
||||
id: 'jccSchedule',
|
||||
title: '调度中心',
|
||||
icon: 'yunweijiankongmokuai',
|
||||
path: '/jccSchedule/resourceLogicView'
|
||||
},
|
||||
{
|
||||
id: 'disk',
|
||||
title: '云际存储',
|
||||
icon: 'xunijiguanli-juan',
|
||||
path: '/disk'
|
||||
},
|
||||
{
|
||||
id: 'functions',
|
||||
title: '函数管理',
|
||||
icon: 'fuwu',
|
||||
path: '/functions/overview'
|
||||
},
|
||||
{
|
||||
id: 'blockChain',
|
||||
title: '云际记账',
|
||||
icon: 'yunjijizhang',
|
||||
path: '/blockChain/blockChainBrowser'
|
||||
},
|
||||
{
|
||||
id: 'hpc',
|
||||
title: '超算管理',
|
||||
icon: 'fuwu',
|
||||
path: '/hpc/hpcOverview'
|
||||
},
|
||||
{
|
||||
id: 'hpc',
|
||||
title: '智算管理',
|
||||
icon: 'fuwu',
|
||||
description: '智算管理描述',
|
||||
path: '/modelarts/overview'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
jcceTheme() {
|
||||
return localStorage.getItem('jcceTheme')
|
||||
},
|
||||
filteredLightTab() {
|
||||
return this.tabLightList.filter(e => this.menus.includes(e.id))
|
||||
}
|
||||
},
|
||||
created() {
|
||||
getMonitorSetting().then(e => {
|
||||
this.monitorSettingForm = e.data
|
||||
})
|
||||
this.getTend()
|
||||
this.getAccrueCenter()
|
||||
this.getTrainJob()
|
||||
this.resize()
|
||||
|
||||
window.addEventListener('resize', debounce(() => {
|
||||
this.resizeKey++
|
||||
}, 100))
|
||||
},
|
||||
mounted() {
|
||||
this.getPower()
|
||||
// this.scaleListener()
|
||||
},
|
||||
methods: {
|
||||
getPower() {
|
||||
getScreenInfo().then((res) => {
|
||||
this.powerData = res.data
|
||||
})
|
||||
},
|
||||
toMonitor() {
|
||||
window.open('http://192.168.19.164:8181/#/taskList')
|
||||
},
|
||||
toHashCat() {
|
||||
window.open('https://dev.jointcloud.net/hashcat/')
|
||||
},
|
||||
handleRemove() {
|
||||
this.rs.delete('file')
|
||||
},
|
||||
httpRequest(data) {
|
||||
const isJar = data.file.name.indexOf('.yaml') === (data.file.name.length - 5)
|
||||
if (!isJar) {
|
||||
this.$message.warning('上传文件只能是 yaml 格式!')
|
||||
} else {
|
||||
this.rs.set('file', data.file)
|
||||
}
|
||||
},
|
||||
submitFile() {
|
||||
if (!this.rs.has('file')) {
|
||||
this.$message.warning('请上传yaml文件')
|
||||
return false
|
||||
} else {
|
||||
createScheduleTask(this.rs).then(res => {
|
||||
if (res.code === 200) {
|
||||
this.$message.success('操作成功')
|
||||
this.dialogVisible = false
|
||||
this.getTrainJob()
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
viewMenu(path) {
|
||||
path ? this.$store.dispatch('user/setRouteType', path.split('/')[0]) : {}
|
||||
this.$router.push({ path: path || `/monitorSelectBk` })
|
||||
},
|
||||
// scaleListener() {
|
||||
// window.addEventListener('resize', this.resize())
|
||||
// },
|
||||
resize() {
|
||||
// 与原来 1080 的比值
|
||||
const scale = window.innerHeight / 900
|
||||
if (scale >= 1) {
|
||||
document.documentElement.style.fontSize = `${16 * scale}px`
|
||||
} else {
|
||||
document.documentElement.style.fontSize = `${14 * scale}px`
|
||||
}
|
||||
},
|
||||
getCurrentDate() {
|
||||
const date = moment().format('yyyy年MM月DD日')
|
||||
const week = moment().format('E')
|
||||
switch (week) {
|
||||
case '1':
|
||||
this.currentDate = date + ' ' + '星期一'
|
||||
break
|
||||
case '2':
|
||||
this.currentDate = date + ' ' + '星期二'
|
||||
break
|
||||
case '3':
|
||||
this.currentDate = date + ' ' + '星期三'
|
||||
break
|
||||
case '4':
|
||||
this.currentDate = date + ' ' + '星期四'
|
||||
break
|
||||
case '5':
|
||||
this.currentDate = date + ' ' + '星期五'
|
||||
break
|
||||
case '6':
|
||||
this.currentDate = date + ' ' + '星期六'
|
||||
break
|
||||
case '0':
|
||||
this.currentDate = date + ' ' + '星期日'
|
||||
break
|
||||
}
|
||||
},
|
||||
// changePage(type) {
|
||||
// if (type === 'left') {
|
||||
// // 滑动到最左
|
||||
// } else {
|
||||
// // 滑到最右
|
||||
// }
|
||||
// },
|
||||
getImg(src) {
|
||||
const srcName = src === 'disk' || src === 'jccSchedule' ? 'blockChain' : src
|
||||
return require('@/assets/img/' + srcName + '.png')
|
||||
},
|
||||
selectMonitor(monitor) {
|
||||
if (monitor === '/disk') {
|
||||
if (this.name === 'admin') {
|
||||
window.location.href = '/disk/storage/sourceSetting'
|
||||
} else {
|
||||
window.location.href = '/disk/storage/diskList'
|
||||
}
|
||||
}
|
||||
this.$store.dispatch('user/setRouteType', monitor.split('/')[1])
|
||||
this.$router.push({ path: monitor })
|
||||
},
|
||||
getTend() {
|
||||
getComputePower().then((res) => {
|
||||
this.tendData = { used: [], xData: [] }
|
||||
if (res.dailyComputerPowers !== null) {
|
||||
const timeArr = []// 最近12个月的月份
|
||||
for (let i = 0; i < 180; i++) {
|
||||
timeArr.push(
|
||||
`${moment(new Date()).subtract(i, 'days').format('YYYY-MM-DD')}`
|
||||
)
|
||||
}
|
||||
timeArr.reverse()// 时间排序
|
||||
const arr = [] // 模拟一个假数据
|
||||
for (let i = 0; i < timeArr.length; i++) {
|
||||
arr.push({ date: timeArr[i], computerPower: 0 })
|
||||
// 将真实数据塞进arr里面
|
||||
for (let j = 0; j < res.dailyComputerPowers.length; j++) {
|
||||
if (res.dailyComputerPowers[j].date === timeArr[i]) {
|
||||
arr[i] = { date: res.dailyComputerPowers[j].date, computerPower: res.dailyComputerPowers[j].computerPower }
|
||||
}
|
||||
}
|
||||
}
|
||||
arr.forEach((item) => {
|
||||
this.tendData.used.push(item.computerPower.toFixed(1))
|
||||
this.tendData.xData.push(item.date)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
getTaskTotal() {
|
||||
// getAccrueCenter().then((res) => {
|
||||
// if (res.perCenterComputerPowers) {
|
||||
// const data = res.accOtJobInfo
|
||||
// this.accrueData = {
|
||||
// config1: data.accCardRunSec,
|
||||
// config2: data.accOtJobNum,
|
||||
// config3: data.accRunSec
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
},
|
||||
getAccrueCenter() {
|
||||
getCPUsage().then((res) => {
|
||||
this.centerData = { used: [], xData: [] }
|
||||
if (res.perCenterComputerPowers) {
|
||||
const data = res.accOtJobInfo
|
||||
this.accrueData = {
|
||||
config1: data.accCardRunSec,
|
||||
config2: data.accOtJobNum,
|
||||
config3: data.accRunSec
|
||||
}
|
||||
const data1 = res.perCenterComputerPowers.filter(item => {
|
||||
if (item.computerPower !== 0) {
|
||||
return item
|
||||
}
|
||||
})
|
||||
// this.timer = setInterval(() => {
|
||||
// this.getTaskTotal()
|
||||
// }, 1000)
|
||||
data1.sort(order)
|
||||
data1.forEach((item) => {
|
||||
if (item.computerPower !== 0) {
|
||||
this.centerData.used.push(item.computerPower.toFixed(1))
|
||||
this.centerData.xData.push(item.centerName)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
getTrainJob() {
|
||||
getTaskCount().then(e => {
|
||||
this.taskData = {
|
||||
tableData: [],
|
||||
totalCount: e.data?.allJobCount || 0,
|
||||
cardTime: e.data?.allCardRunTime || 0,
|
||||
totalRunTime: e.data?.allJobRunTime || 0
|
||||
}
|
||||
e.data?.trainJobs?.forEach((item) => {
|
||||
this.taskData.tableData.push({
|
||||
name: item.name,
|
||||
status: item.status,
|
||||
strategy: item.strategy,
|
||||
serviceName: item.serviceName,
|
||||
synergyStatus: item.synergyStatus
|
||||
// undertaker: this.showUnderTaker(item)
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
showUnderTaker(item) {
|
||||
if (item.tasks == null) {
|
||||
return ''
|
||||
} else if (item.tasks.length > 2) {
|
||||
return item.tasks[0].centerName[0] + '等'
|
||||
} else {
|
||||
if (item.tasks[0].centerName == null) {
|
||||
return ''
|
||||
} else {
|
||||
return item.tasks[0].centerName[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/styles/variables.scss";
|
||||
|
||||
::v-deep {
|
||||
.el-dialog {
|
||||
background: #2c3a4e !important;
|
||||
color: white;
|
||||
}
|
||||
.el-upload-list__item-name {
|
||||
color: #ffffff;
|
||||
}
|
||||
.el-upload-list__item:hover {
|
||||
background-color: rgb(86, 90, 95)
|
||||
}
|
||||
.el-button--default {
|
||||
color: white;
|
||||
background: rgba(255,255,255,0.1);
|
||||
border-color: rgba(255,255,255,0.01);
|
||||
}
|
||||
.el-dialog__title {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
.monitor {
|
||||
background: url('../../assets/monitor/monitor_bg.jpeg') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
width: 100%;
|
||||
min-width: 1200px;
|
||||
height: 100vh;
|
||||
min-height: 900px;
|
||||
overflow: hidden;
|
||||
color: white;
|
||||
font-size: 0.8rem;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: 400;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
.top {
|
||||
width: 100%;
|
||||
height: 8vh;
|
||||
// vertical-align: baseline;
|
||||
position: absolute;
|
||||
z-index: 99;
|
||||
background: url(../../assets/monitor/top-bg.png) center top no-repeat;
|
||||
background-size: 100% 65%;
|
||||
.top-title{
|
||||
margin:0 auto;
|
||||
// font-weight: bold;
|
||||
// font-family: PangMenZhengDao;
|
||||
// float: left;
|
||||
// padding: 1rem 8rem;
|
||||
// padding-right: 0;
|
||||
height: 100%;
|
||||
background: url(../../assets/monitor/c-top.png) center no-repeat;
|
||||
background-size: 55% 10vh;
|
||||
h1{
|
||||
margin: 0;
|
||||
font-size: 2rem;
|
||||
line-height: 6vh;
|
||||
letter-spacing: 0.3rem;
|
||||
text-align: center;
|
||||
text-shadow: 3px 5px 0px rgba(17,20,22,0.22);
|
||||
background: linear-gradient(0deg, rgba(36,83,152,0.35) 0%, rgba(255,255,255,0.35) 100%);
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: #ffffff;
|
||||
// background: linear-gradient(0deg, rgba(36,83,152,0.35) 0%, rgba(255,255,255,0.35) 100%);
|
||||
// -webkit-background-clip: text;
|
||||
// -webkit-text-fill-color: transparent;
|
||||
}
|
||||
// box-shadow: 0px 20px 10px 0px #02020a96;
|
||||
}
|
||||
}
|
||||
.top-menu{
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
.menu a, .right a {
|
||||
float: left;
|
||||
font-size: 1.13rem;
|
||||
display: block;
|
||||
padding: 0.9rem 60px;
|
||||
height: 3.5rem;
|
||||
letter-spacing: 0.2rem;
|
||||
}
|
||||
.menu a, .right a{
|
||||
&:hover{
|
||||
background: url(../../assets/monitor/t-p.png) center no-repeat;
|
||||
background-size: auto 70%;
|
||||
}
|
||||
}
|
||||
.menu a:first-child{
|
||||
background: url(../../assets/monitor/t-p.png) center no-repeat;
|
||||
background-size: auto 70%;
|
||||
}
|
||||
.right {
|
||||
a { float: right;}
|
||||
// float: right;
|
||||
}
|
||||
|
||||
}
|
||||
.title{
|
||||
background: url('../../assets/monitor/title-bg.png') no-repeat left;
|
||||
background-size: 105% 100%;
|
||||
background-position: -3.5vh;
|
||||
height: 4.5vh;
|
||||
p{
|
||||
font-size: 1.4rem;
|
||||
height: 2.8rem;
|
||||
line-height: 2.3rem;
|
||||
text-indent: 2.8vw;
|
||||
margin: 0;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: bold;
|
||||
color: #FFFFFF;
|
||||
letter-spacing: 0.2rem;
|
||||
text-shadow: 0px 2px 8px rgba(5,28,55,0.42);
|
||||
|
||||
background: linear-gradient(0deg, rgba(14,197,236,1) 0%, rgba(49,190,255,1) 0%, rgba(239,252,254,1) 58.7646484375%);
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
|
||||
}
|
||||
}
|
||||
.floatLeft, .floatRight{
|
||||
margin-top: 5vh;
|
||||
}
|
||||
.middle{
|
||||
width: 38vw;
|
||||
position: absolute;
|
||||
left: 31vw;
|
||||
z-index: 99;
|
||||
margin-top: 10vh;
|
||||
}
|
||||
.floatLeft, .floatRight{
|
||||
padding: 0 1vh 0 2vh;
|
||||
padding-top: 5vh;
|
||||
padding-bottom: 4vh;
|
||||
}
|
||||
.floatLeft .left::before, .floatRight .right::after{
|
||||
// margin-top: 6vh;
|
||||
content: '';
|
||||
width: 27vw;
|
||||
height: 95vh;
|
||||
display:block;
|
||||
position: absolute;
|
||||
top: -5.2vh;
|
||||
right: -2vh;
|
||||
background: url(../../assets/monitor/left.png) no-repeat;
|
||||
background-size: 100% 98%;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.floatLeft .left:after, .floatRight .right:before{
|
||||
content: '';
|
||||
width: 2vw;
|
||||
height: 85vh;
|
||||
position: absolute;
|
||||
right: -3.5vw;
|
||||
top: 3px;
|
||||
display: block;
|
||||
background: url(../../assets/monitor/leftr.png) no-repeat;
|
||||
background-size: 100% 98%;
|
||||
}
|
||||
.floatRight .right:before{
|
||||
left: -3.5vw;
|
||||
-moz-transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
-webkit-transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
-o-transform:matrix(-1,0,0,1,0,0);
|
||||
}
|
||||
.floatLeft{
|
||||
// background: #02020a96;
|
||||
// box-shadow: 20px -30px 30px 0px #02020a96;
|
||||
width: 27vw;
|
||||
display: block;
|
||||
// overflow: hidden;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
height: 95vh;
|
||||
min-height: 800px;
|
||||
.left {
|
||||
width: 100%;
|
||||
height: 90vh;
|
||||
padding-left: 10px;
|
||||
display: block;
|
||||
position: relative;
|
||||
&:before{
|
||||
left: -2vh;
|
||||
}
|
||||
.left_1{
|
||||
height: 32vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
.left_2 {
|
||||
height: 30vh;
|
||||
.taskDiv{
|
||||
// display: flex;
|
||||
// justify-content: space-between;
|
||||
text-align: center;
|
||||
margin-bottom: 1%;
|
||||
// height: calc(100% - 190px);
|
||||
>div{
|
||||
background: url('../../assets/images/monitorSelect/data-bg.png') no-repeat center;
|
||||
background-size: auto 100%;
|
||||
height: 11vh;
|
||||
margin-top: 2vh;
|
||||
// width: 25%;
|
||||
.num{
|
||||
font-size: 1.5rem;
|
||||
font-family: Impact;
|
||||
color: #FFFFFF;
|
||||
letter-spacing: 0.1rem;
|
||||
font-family: PangMenZhengDao;
|
||||
// height: 3vh;
|
||||
// line-height: 4vh;
|
||||
height: 3vh;
|
||||
line-height: 2rem;
|
||||
margin-bottom: 1vh;
|
||||
}
|
||||
.name{
|
||||
font-size: 0.8rem;
|
||||
letter-spacing: 0.1rem;
|
||||
width: 60%;
|
||||
margin: auto;
|
||||
// font-weight: bold;
|
||||
height: 70%;
|
||||
// line-height: 300%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.left_3 {
|
||||
width: 100%;
|
||||
height: 15vh;
|
||||
}
|
||||
// .left_4{
|
||||
// height: 12vh;
|
||||
// }
|
||||
}
|
||||
}
|
||||
.floatRight {
|
||||
// background: #02020a96;
|
||||
// box-shadow: -20px -30px 30px 0px #02020a96;
|
||||
background: none;
|
||||
width: 27vw;
|
||||
display: block;
|
||||
// overflow: hidden;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
height: 95vh;
|
||||
min-height: 800px;
|
||||
padding: 0 2vh 0 1vh;
|
||||
padding-top: 5vh;
|
||||
padding-bottom: 4vh;
|
||||
.createBtn{
|
||||
height: 2.5vh;
|
||||
line-height: 2.3vh;
|
||||
margin: 0;
|
||||
padding: 0 1rem;
|
||||
position: absolute;
|
||||
top: 0.5vh;
|
||||
right: 2vh;
|
||||
div{
|
||||
font-size: 0.9rem;
|
||||
@media screen and (max-height: 900px) {
|
||||
transform: scale(0.8);
|
||||
// transform-origin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.right {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-right: 10px;
|
||||
display: block;
|
||||
position: relative;
|
||||
&:after{
|
||||
// padding: 0 20px 0 10px;
|
||||
-moz-transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
-webkit-transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
-o-transform:matrix(-1,0,0,1,0,0);
|
||||
z-index: -1;
|
||||
// padding-top: 50px;
|
||||
// padding-bottom: 40px;
|
||||
}
|
||||
.right_1{
|
||||
height: 50vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
.right_2{
|
||||
// height: 31%;
|
||||
height: 40vh;
|
||||
}
|
||||
.right_3{
|
||||
height: 21vh;
|
||||
// height: 27%;
|
||||
}
|
||||
}
|
||||
}
|
||||
// .fixedBottom {
|
||||
// width:50vw;
|
||||
// bottom: 0;
|
||||
// display: block;
|
||||
// position: absolute;
|
||||
// z-index: 10;
|
||||
// height: 13vh;
|
||||
// left: 25vw;
|
||||
// .el-row{position:relative; height: 100%}
|
||||
// .lightLeft{
|
||||
// font-size: 30px;
|
||||
// position: absolute;
|
||||
// left: -20px;
|
||||
// top: 3vh;
|
||||
// z-index: 10;
|
||||
// color: #DDD;
|
||||
// }
|
||||
// .lightRight{
|
||||
// font-size: 30px;
|
||||
// position: absolute;
|
||||
// right: -20px;
|
||||
// top: 3vh;
|
||||
// z-index: 10;
|
||||
// color: #DDD;
|
||||
// }
|
||||
// // display:flex 样式
|
||||
// .div-block{
|
||||
// display: flex;
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
// overflow: hidden;
|
||||
// .monitorSelectDiv{
|
||||
// display: block;
|
||||
// height: 100%;
|
||||
// width: 8.33vw;
|
||||
// }
|
||||
// > div{
|
||||
// display: block;
|
||||
// width: 100%;
|
||||
// max-width: 8.5vw;
|
||||
// font-size: 20px;
|
||||
// color: #ffffff;
|
||||
// height: 100vh;
|
||||
// position: relative;
|
||||
// text-align: center;
|
||||
// &:hover{
|
||||
// color: #3182CE;
|
||||
// }
|
||||
// .svg-icon {
|
||||
// font-size: 80px;
|
||||
// margin: 0 auto;
|
||||
// }
|
||||
// .selectTitle {
|
||||
// margin-bottom: 24px;
|
||||
// font-size: 16px;
|
||||
// }
|
||||
// span{
|
||||
// display: block;
|
||||
// padding: 0 100px;
|
||||
// font-size: 14px;
|
||||
// line-height: 24px;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// @media screen and (min-width: 1921px) {
|
||||
// .monitor {
|
||||
// font-size: 16px;
|
||||
// .top {
|
||||
// .top-title {
|
||||
// font-size: 32px;
|
||||
// padding: 10px 100px;
|
||||
// img{
|
||||
// top: 35px;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// .title{
|
||||
// font-size: 20px;
|
||||
// height: 70px;
|
||||
// }
|
||||
// .middle, .floatLeft, .floatRight{
|
||||
// margin-top: 110px;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
</style>
|
||||
|
||||
<style lang="less" rel="stylesheet/less">
|
||||
@import "../../common/font/font.css";
|
||||
</style>
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
<!-- 算力中心总数 -->
|
||||
<div>
|
||||
<div class="two">
|
||||
<div v-for="(item, index) in dataArray" :key="'data'+index">
|
||||
<div v-for="(item, index) in dataArray" :key="'data'+index" style="cursor: pointer;" @click="item.path && viewMenu(item.path)">
|
||||
<p class="title">{{ item.name }}</p>
|
||||
<div class="num">{{ item.value }}</div>
|
||||
</div>
|
||||
|
|
@ -23,11 +23,13 @@ export default {
|
|||
dataArray: [
|
||||
{
|
||||
name: '算力中心总数(计算域)',
|
||||
value: '-'
|
||||
value: '-',
|
||||
path: 'resourceList'
|
||||
},
|
||||
{
|
||||
name: '已接入算力 POps@FP16',
|
||||
value: '-'
|
||||
value: '-',
|
||||
path: 'resourceList'
|
||||
},
|
||||
{
|
||||
name: '接入集群数',
|
||||
|
|
@ -47,7 +49,10 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
viewMenu(path) {
|
||||
path ? this.$store.dispatch('user/setRouteType', path.split('/')[0]) : {}
|
||||
this.$router.push({ path: path || `/monitorSelectBk` })
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,198 @@
|
|||
<template>
|
||||
<transition name="el-zoom-in-center">
|
||||
<div class="transition-box province">
|
||||
<province v-model="third" :map-type="9" :cluster="provinceClusters" @selectedCity="selectCity" />
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
import province from './provinceDev.vue'
|
||||
import dataCenter from './dataCenter'
|
||||
|
||||
export default {
|
||||
components: { province },
|
||||
props: {
|
||||
center: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
name: '鹏城云脑',
|
||||
longitude: 114.057868,
|
||||
latitude: 22.543099
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataCenter,
|
||||
loading: true,
|
||||
provinceType: 5,
|
||||
third: false,
|
||||
provinceClusters: [],
|
||||
mapCount: {},
|
||||
selectCity: ''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.provinceClusters = dataCenter.centerList
|
||||
this.third = true
|
||||
},
|
||||
beforeDestroy() {
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.loading {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: block;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: rgba(#071b45, 0.8);
|
||||
}
|
||||
.circle-breath {
|
||||
background: #3EDFFC;
|
||||
box-shadow: 0 0 0 0 rgb(250, 249, 250);
|
||||
height: 10vh;
|
||||
width: 10vh;
|
||||
margin: 40vh auto;
|
||||
// display: block;
|
||||
border-radius: 50%;
|
||||
animation: donghua 2.4s infinite;
|
||||
.loadingGlobe{
|
||||
font-size: 10vh;
|
||||
animation: zhuan 3s linear infinite;
|
||||
}
|
||||
}
|
||||
@keyframes zhuan {
|
||||
0% {transform: rotateZ(0deg)}
|
||||
25% {transform: rotateZ(90deg)}
|
||||
50% {
|
||||
transform: rotateZ(180deg)
|
||||
}
|
||||
75% {
|
||||
transform: rotateZ(270deg)
|
||||
}
|
||||
100% {
|
||||
transform: rotateZ(360deg)
|
||||
}
|
||||
}
|
||||
@keyframes donghua {
|
||||
0% {
|
||||
transform: scale(0.60);
|
||||
/* 注意rgba中的a的设置 */
|
||||
box-shadow: 0 0 0 0 rgba(73, 171, 204, 0.6);
|
||||
}
|
||||
|
||||
60% {
|
||||
transform: scale(1);
|
||||
box-shadow: 0 0 0 36px rgba(73, 182, 204, 0);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(0.60);
|
||||
box-shadow: 0 0 0 0 rgba(73, 167, 204, 0);
|
||||
}
|
||||
}
|
||||
.province{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: url('../../assets/monitor/province-bg.png') center no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
.switchBtn {
|
||||
font-size: 2.5rem;
|
||||
position: absolute;
|
||||
bottom: 6.5vh;
|
||||
right: 30vw;
|
||||
z-index: 100;
|
||||
color: #fff;
|
||||
}
|
||||
.toChina{
|
||||
bottom: 2.3vh;
|
||||
}
|
||||
.activeBtn{
|
||||
color: #3EDFFC
|
||||
}
|
||||
.chinaDetail{
|
||||
position:absolute;
|
||||
bottom: 80px;
|
||||
right: 28vw;
|
||||
z-index: 100;
|
||||
width: 140px;
|
||||
.el-button,.el-button + .el-button{
|
||||
margin: 0;
|
||||
margin-bottom: 5px;
|
||||
padding: 5px 15px;
|
||||
width: 100%;
|
||||
background-color: #b3afaf33;
|
||||
color: #fff;
|
||||
border-radius: 0;
|
||||
text-align: left;
|
||||
border: 0;
|
||||
line-height: 2rem;
|
||||
.svg-icon{
|
||||
font-size: 1.4rem;
|
||||
margin-right: 0.6rem;
|
||||
}
|
||||
}
|
||||
.svg-icon{
|
||||
font-size: 2rem;
|
||||
margin-right: 0.6rem;
|
||||
}
|
||||
.active{
|
||||
background-color: #ffffff6b!important;
|
||||
}
|
||||
}
|
||||
.provinceDetail{
|
||||
position:absolute;
|
||||
bottom: 90px;
|
||||
left: 30vw;
|
||||
z-index: 100;
|
||||
width: 400px;
|
||||
height: auto;
|
||||
// background-color: #cbdae51a;
|
||||
}
|
||||
.switchDataBtn{
|
||||
position: absolute;
|
||||
bottom: 3vh;
|
||||
right: 35vw;
|
||||
.el-button,.el-button + .el-button{
|
||||
width: 10vw;
|
||||
margin-bottom: 5px;
|
||||
padding: 5px 15px;
|
||||
// width: 100%;
|
||||
// background-color: #24253a;
|
||||
background-image: url('../../assets/images/monitorSelect/btn.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
border-radius: 0;
|
||||
font-size: 1.2rem;
|
||||
font-family: Source Han Sans CN;
|
||||
font-weight: bold;
|
||||
letter-spacing: 0.2rem;
|
||||
// text-align: left;
|
||||
border: 0;
|
||||
line-height: 3rem;
|
||||
}
|
||||
.el-button--default{
|
||||
color: #91d4fe;
|
||||
}
|
||||
.active{
|
||||
color: #ffffff;
|
||||
background-image: url('../../assets/images/monitorSelect/btn-p.png')!important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
@ -0,0 +1,552 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="top">
|
||||
<div class="canvasBox">
|
||||
<canvas id="container" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="spin">
|
||||
<div class="circle circle1">
|
||||
<div class="turnAround" />
|
||||
</div>
|
||||
<div class="circle circle2">
|
||||
<div class="turnAround" />
|
||||
</div>
|
||||
<div class="circle circle3">
|
||||
<div class="turnAround" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import guangdongJson from './geoJson/guangdong.json'
|
||||
import guangdongOutline from './geoJson/guangdongOutline.json'
|
||||
import chuanyuJson from './geoJson/chuanyu.json'
|
||||
import gansuJson from './geoJson/gansu.json'
|
||||
import guizhouJson from './geoJson/guizhou.json'
|
||||
import jingjinjiJson from './geoJson/jingjinji.json'
|
||||
import neimengguJson from './geoJson/neimenggu.json'
|
||||
import ningxiaJson from './geoJson/ningxia.json'
|
||||
import changsanjiaoJson from './geoJson/changsanjiao.json'
|
||||
import hunanJson from './geoJson/hunan.json'
|
||||
import hunanOutline from './geoJson/hunanOutline.json'
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
mapType: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
// count: {
|
||||
// type: Object,
|
||||
// default: () => { return { ys: 0, zs: 0, cs: 0 } }
|
||||
// },
|
||||
cluster: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedCity: '',
|
||||
allJSON: {
|
||||
guangdongJson,
|
||||
chuanyuJson,
|
||||
gansuJson,
|
||||
guizhouJson, jingjinjiJson, neimengguJson, ningxiaJson, changsanjiaoJson,
|
||||
guangdongOutline, hunanJson, hunanOutline
|
||||
},
|
||||
currentIndex: 0,
|
||||
interval: undefined,
|
||||
img: undefined,
|
||||
activeTab: '',
|
||||
scale: 1,
|
||||
geoCenter: {},
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
eventType: '',
|
||||
cursorFlag: false,
|
||||
mapMap: {
|
||||
1: 'ningxia',
|
||||
2: 'neimenggu',
|
||||
3: 'gansu',
|
||||
4: 'guizhou',
|
||||
5: 'guangdong',
|
||||
6: 'chuanyu',
|
||||
7: 'changsanjiao',
|
||||
8: 'jingjinji',
|
||||
9: 'hunan'
|
||||
},
|
||||
mapName: {
|
||||
1: '宁夏回族自治区',
|
||||
2: '内蒙古自治区',
|
||||
3: '甘肃省',
|
||||
4: '贵州省',
|
||||
5: '粤港澳大湾区',
|
||||
6: '川渝地区',
|
||||
7: '长三角地区',
|
||||
8: '京津冀地区',
|
||||
9: '湖南省'
|
||||
}
|
||||
// geoCenterY: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
dialogVisible: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(value) {
|
||||
this.$emit('input', value)
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
mapType(val) {
|
||||
if (val) {
|
||||
this.getBoxArea()
|
||||
this.drawMap()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getBoxArea()
|
||||
this.$nextTick(() => {
|
||||
this.img = new Image()
|
||||
this.img.src = process.env.VUE_APP_PUBLIC_SOURCE_API + '/click-point.svg'
|
||||
this.img.addEventListener('load', () => {
|
||||
this.setDataRoll()
|
||||
})
|
||||
const canvas = document.querySelector('#container')
|
||||
|
||||
// 鼠标移动事件
|
||||
canvas.addEventListener('mousemove', (event) => {
|
||||
this.offsetX = event.offsetX / 0.55
|
||||
this.offsetY = event.offsetY / 0.65
|
||||
this.eventType = 'mousemove'
|
||||
this.drawMap()
|
||||
})
|
||||
|
||||
// 鼠标点击事件
|
||||
canvas.addEventListener('click', (event) => {
|
||||
this.offsetX = event.offsetX / 0.55
|
||||
this.offsetY = event.offsetY / 0.65
|
||||
this.eventType = 'click'
|
||||
clearInterval(this.interval)
|
||||
this.drawMap()
|
||||
})
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
setDataRoll() {
|
||||
clearInterval(this.interval)
|
||||
this.interval = setInterval(() => {
|
||||
this.currentIndex = (this.currentIndex + 1) % this.cluster.length// 更新当前索引
|
||||
this.drawMap()
|
||||
}, 4000)
|
||||
},
|
||||
clickback() {
|
||||
this.dialogVisible = false
|
||||
},
|
||||
filterData(data) {
|
||||
this.selectedCity = data
|
||||
if (data === '') {
|
||||
this.setDataRoll()
|
||||
}
|
||||
this.$emit('selectedCity', data)
|
||||
},
|
||||
drawMap() {
|
||||
const canvas = document.querySelector('#container')
|
||||
const ctx = canvas.getContext('2d')
|
||||
ctx.clearRect(0, 0, window.innerWidth, window.innerHeight)
|
||||
this.initOutline()
|
||||
this.initMap()
|
||||
this.setPoint()
|
||||
},
|
||||
setPoint() {
|
||||
const canvas = document.querySelector('#container')
|
||||
const ctx = canvas.getContext('2d')
|
||||
ctx.beginPath()
|
||||
this.cluster.forEach((e, i) => {
|
||||
const position = this.toScreenPosition(e.longitude, e.latitude)
|
||||
if (this.currentIndex === i) {
|
||||
ctx.drawImage(this.img, position.x - 40, position.y - 55, 80, 80)
|
||||
ctx.fillStyle = 'rgba(255, 197, 39, 1)'
|
||||
ctx.font = '30px PangMenZhengDao'
|
||||
ctx.fillText(e.name, position.x - e.name.length / 2 * 35, position.y - 55)
|
||||
|
||||
ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'
|
||||
const txtlength = e.name.length > e.address.length ? e.name.length : e.address.length
|
||||
ctx.fillRect(position.x + 20, position.y + 5, txtlength * 27, 90)
|
||||
ctx.strokeStyle = '#3EDFFC'
|
||||
ctx.strokeRect(position.x + 20, position.y + 5, txtlength * 27, 90)
|
||||
ctx.fillStyle = '#FFFFFF'
|
||||
ctx.font = '20px Arial'
|
||||
ctx.fillText('名称:' + e.name, position.x + 20 + 20, position.y + 5 + 40)
|
||||
ctx.fillText('地址:' + e.address || '-', position.x + 20 + 20, position.y + 5 + 70)
|
||||
} else {
|
||||
ctx.beginPath()
|
||||
ctx.arc(position.x, position.y, 5, 0, Math.PI * 2) // 画一个半径为5的圆
|
||||
ctx.fillStyle = '#ffffff' // 设置填充颜色
|
||||
ctx.fill()
|
||||
ctx.closePath()
|
||||
}
|
||||
})
|
||||
ctx.stroke()
|
||||
ctx.restore()
|
||||
},
|
||||
getBoxArea() {
|
||||
const canvasW = window.innerWidth
|
||||
const canvasH = window.innerHeight
|
||||
let N = -90; let S = 90; let W = 180; let E = -180
|
||||
this.allJSON[this.mapMap[this.mapType] + 'Json'].features.forEach(item => {
|
||||
if (item.geometry.type === 'Polygon') {
|
||||
item.geometry.coordinates = [item.geometry.coordinates]
|
||||
}
|
||||
item.geometry.coordinates.forEach(area => {
|
||||
area[0].forEach(elem => {
|
||||
if (elem[0] < W) {
|
||||
W = elem[0]
|
||||
}
|
||||
if (elem[0] > E) {
|
||||
E = elem[0]
|
||||
}
|
||||
if (elem[1] > N) {
|
||||
N = elem[1]
|
||||
}
|
||||
if (elem[1] < S) {
|
||||
S = elem[1]
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
var wScale = canvasW / Math.abs(E - W)
|
||||
var hScale = canvasH / Math.abs(N - S)
|
||||
this.scale = (wScale > hScale ? hScale : wScale) * 0.9
|
||||
this.geoCenter = {
|
||||
W: W,
|
||||
N: N,
|
||||
xoffset: canvasW / 2 - Math.abs(E - W) / 2 * this.scale,
|
||||
yoffset: canvasH / 2 - Math.abs(N - S) / 2 * this.scale
|
||||
}
|
||||
},
|
||||
toScreenPosition(longitude, latitude) {
|
||||
return {
|
||||
x: (longitude - this.geoCenter.W) * this.scale + this.geoCenter.xoffset,
|
||||
y: (this.geoCenter.N - latitude) * this.scale + this.geoCenter.yoffset
|
||||
}
|
||||
},
|
||||
initMap() {
|
||||
const canvas = document.querySelector('#container')
|
||||
const ctx = canvas.getContext('2d')
|
||||
this.cursorFlag = false
|
||||
ctx.beginPath()
|
||||
ctx.strokeStyle = '#3EDFFC'
|
||||
ctx.lineWidth = 1
|
||||
|
||||
this.allJSON[this.mapMap[this.mapType] + 'Json'].features.forEach(elem => {
|
||||
const coordinates = elem.geometry.coordinates
|
||||
coordinates.forEach(multiPolygon => {
|
||||
multiPolygon.forEach(polygon => {
|
||||
ctx.save()
|
||||
ctx.beginPath()
|
||||
// ctx.translate(0, 0)
|
||||
for (let i = 0; i < polygon.length; i++) {
|
||||
const position = this.toScreenPosition(polygon[i][0], polygon[i][1])
|
||||
if (i === 0) {
|
||||
ctx.moveTo(position.x, position.y - 5)
|
||||
} else {
|
||||
ctx.lineTo(position.x, position.y - 5)
|
||||
}
|
||||
}
|
||||
ctx.closePath()
|
||||
ctx.strokeStyle = '#34CEE9'
|
||||
ctx.lineWidth = 1
|
||||
if (ctx.isPointInPath(this.offsetX, this.offsetY)) {
|
||||
this.cursorFlag = true
|
||||
ctx.fillStyle = '#a2f7ff'
|
||||
if (this.eventType === 'click') {
|
||||
this.filterData(elem.properties.name)
|
||||
// 输出市级名称
|
||||
}
|
||||
} else {
|
||||
if (this.eventType === 'mousemove' && this.selectedCity === '') ctx.fillStyle = 'transparent'
|
||||
}
|
||||
if (this.selectedCity === elem.properties.name) ctx.fillStyle = '#00eaff'
|
||||
|
||||
ctx.fill()
|
||||
ctx.stroke()
|
||||
ctx.restore()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
if (this.cursorFlag) {
|
||||
canvas.style.cursor = 'pointer'
|
||||
} else {
|
||||
canvas.style.cursor = 'default'
|
||||
}
|
||||
},
|
||||
initOutline() {
|
||||
const canvas = document.querySelector('#container')
|
||||
const ctx = canvas.getContext('2d')
|
||||
const canvasW = canvas.width = window.innerWidth
|
||||
const canvasH = canvas.height = window.innerHeight
|
||||
ctx.clearRect(0, 0, canvasW, canvasH)
|
||||
ctx.fillStyle = 'transparent'
|
||||
ctx.fillRect(0, 0, canvasW, canvasH)
|
||||
ctx.beginPath()
|
||||
ctx.strokeStyle = '#3EDFFC'
|
||||
ctx.lineWidth = 1
|
||||
this.allJSON[this.mapMap[this.mapType] + 'Outline'].features.forEach(elem => {
|
||||
const coordinates = elem.geometry.coordinates
|
||||
ctx.save()
|
||||
coordinates.forEach(multiPolygon => {
|
||||
multiPolygon.forEach(polygon => {
|
||||
for (let i = 0; i < polygon.length; i++) {
|
||||
const position = this.toScreenPosition(polygon[i][0], polygon[i][1])
|
||||
if (i === 0) {
|
||||
ctx.moveTo(position.x, position.y + 5)
|
||||
} else {
|
||||
ctx.lineTo(position.x, position.y + 5)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
ctx.closePath()
|
||||
if (!ctx.isPointInPath(this.offsetX, this.offsetY)) {
|
||||
if (this.eventType === 'click') {
|
||||
this.filterData('')
|
||||
// 输出市级名称
|
||||
}
|
||||
}
|
||||
ctx.fillStyle = '#3edffc'
|
||||
var grd = ctx.createLinearGradient(0, 0, 1500, 0)
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
grd.addColorStop(i / 1000, 'white')
|
||||
grd.addColorStop(i / 1000 + 0.001, '#059BFC')
|
||||
}
|
||||
ctx.fillStyle = grd
|
||||
// ctx.shadowColor = '#3EDFFC'
|
||||
// ctx.shadowBlur = 0
|
||||
// // ctx.shadowOffsetX = 50
|
||||
// ctx.shadowOffsetY = 20
|
||||
ctx.fill()
|
||||
ctx.stroke()
|
||||
ctx.restore()
|
||||
|
||||
ctx.beginPath()
|
||||
this.allJSON[this.mapMap[this.mapType] + 'Outline'].features.forEach(elem => {
|
||||
const coordinates = elem.geometry.coordinates
|
||||
ctx.save()
|
||||
coordinates.forEach(multiPolygon => {
|
||||
multiPolygon.forEach(polygon => {
|
||||
for (let i = 0; i < polygon.length; i++) {
|
||||
const position = this.toScreenPosition(polygon[i][0], polygon[i][1])
|
||||
if (i === 0) {
|
||||
ctx.moveTo(position.x, position.y - 5)
|
||||
} else {
|
||||
ctx.lineTo(position.x, position.y - 5)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
ctx.closePath()
|
||||
var g = ctx.createRadialGradient(700, 600, 50, 1000, 600, 600)
|
||||
g.addColorStop(0, '#29a0ee')
|
||||
g.addColorStop(1, '#0b4eaf')
|
||||
ctx.fillStyle = g
|
||||
ctx.fill()
|
||||
ctx.stroke()
|
||||
ctx.restore()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.back{
|
||||
position:absolute;
|
||||
top: 20vh;
|
||||
left: 31vw;
|
||||
z-index: 99;
|
||||
}
|
||||
.data-view {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
border: 1px solid #3EDFFC;
|
||||
padding: 0 10px;
|
||||
margin: 10px;
|
||||
background-color: #1a2d47ad;
|
||||
bottom: 0;
|
||||
font-size: 0.8rem;
|
||||
p{
|
||||
color: #DDDDDD;
|
||||
text-indent: 1rem;
|
||||
position: relative;
|
||||
}
|
||||
p:before{
|
||||
content: '';
|
||||
display: block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 8px;
|
||||
background-color: #0fe765;
|
||||
position: absolute;
|
||||
left: 3px;
|
||||
top: 3px;
|
||||
}
|
||||
p:nth-child(3):before{
|
||||
background-color: #3EDFFC;
|
||||
}
|
||||
p:nth-child(4):before{
|
||||
background-color: #f3ca45;
|
||||
}
|
||||
h5{font-weight: bold; font-size: 1rem; margin: 1rem 0}
|
||||
}
|
||||
.top{
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
display: block;
|
||||
height: 60vh;
|
||||
z-index: 8;
|
||||
|
||||
}
|
||||
.center{
|
||||
position:absolute;
|
||||
bottom: 11vh;
|
||||
right: 30vw;
|
||||
z-index: 100;
|
||||
width: 20vh;
|
||||
.el-button,.el-button + .el-button{
|
||||
margin: 0;
|
||||
// margin-bottom: 10px;
|
||||
// padding: 10px 15px;
|
||||
padding: 0.5vh 2rem;
|
||||
height: 5vh;
|
||||
width: 100%;
|
||||
background: url(../../assets/monitor/b.png) left no-repeat;
|
||||
background-size: 100% 100%;
|
||||
font-weight: 500;
|
||||
font-style: italic;
|
||||
color: #FFFFFF;
|
||||
text-shadow: 0px 2px 6px rgba(19,23,27,0.31);
|
||||
border-radius: 0;
|
||||
text-align: left;
|
||||
border: 0;
|
||||
// line-height: 4vh;
|
||||
div{
|
||||
font-size: 1.2rem;
|
||||
@media screen and (max-height: 900px) {
|
||||
// transform: scale(0.8);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
.active{
|
||||
background: url(../../assets/monitor/b-p.png) left no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
.canvasBox{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
#container {
|
||||
width: 55vw;
|
||||
height: 65vh;
|
||||
margin: auto;
|
||||
margin-top: 18vh;
|
||||
display: block;
|
||||
}
|
||||
.spin{
|
||||
width: 100%;
|
||||
height: 30vh;
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
perspective: 200vh;
|
||||
z-index: 0;
|
||||
// animation: rotate 13s linear infinite;
|
||||
.circle {
|
||||
width: 50vw;
|
||||
height: 30vh;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: -49vh;
|
||||
display: block;
|
||||
// border: 1px solid #ffffff;
|
||||
}
|
||||
.circle1{
|
||||
width: 28vw;
|
||||
height: 80vh;
|
||||
top: -25.5vh;
|
||||
left: 36vw;
|
||||
transform: rotateX(80deg);
|
||||
.turnAround{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
animation: rotate 8s linear infinite;
|
||||
background: url('../../assets/monitor/circle1.png') center no-repeat;
|
||||
background-size: 80% auto;
|
||||
}
|
||||
}
|
||||
|
||||
.circle2{
|
||||
width: 54vw;
|
||||
height: 99vh;
|
||||
left: 23vw;
|
||||
top: -34vh;
|
||||
transform: rotateX(80deg);
|
||||
.turnAround{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
animation: backRotate 15s linear infinite;
|
||||
background: url('../../assets/monitor/circle2.png') center no-repeat;
|
||||
background-size: 80% auto;
|
||||
}
|
||||
}
|
||||
|
||||
.circle3{
|
||||
width: 46vw;
|
||||
height: 80vh;
|
||||
left: 27vw;
|
||||
top: -25vh;
|
||||
transform: rotateX(80deg);
|
||||
.turnAround{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
animation: rotate 10s linear infinite;
|
||||
background: url('../../assets/monitor/circle3.png') center no-repeat;
|
||||
background-size: 80% auto;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
0% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes backRotate {
|
||||
0% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
<template>
|
||||
<div>
|
||||
<h3> {{ $t('page.createVaspTask') }} </h3>
|
||||
<el-form
|
||||
ref="formData"
|
||||
class="form-wrap"
|
||||
label-position="left"
|
||||
:model="formData"
|
||||
:rules="formDataRules"
|
||||
>
|
||||
<el-form-item :label="$t('page.taskName')" prop="name">
|
||||
<el-input
|
||||
v-model="formData.name"
|
||||
:placeholder="$t('page.inputWarn')"
|
||||
:max-length="30"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('page.partition')" prop="partition">
|
||||
<el-input
|
||||
v-model="formData.partition"
|
||||
:max-length="30"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('page.nodeNum')" prop="nNode">
|
||||
<el-input
|
||||
v-model="formData.nNode"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('page.commandContent')" prop="cmdScript">
|
||||
<el-input
|
||||
v-model="formData.cmdScript"
|
||||
type="textarea"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('page.workMenu')" prop="workDir">
|
||||
<el-input
|
||||
v-model="formData.workDir"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('page.fileUpload')">
|
||||
<!-- <el-input v-model="taskInput" type="textarea" rows="10" /> -->
|
||||
<el-upload
|
||||
ref="upload"
|
||||
class="upload-demo"
|
||||
:file-list="fileList"
|
||||
:auto-upload="false"
|
||||
action="#"
|
||||
:multiple="true"
|
||||
>
|
||||
<el-button slot="trigger" size="small">选取文件</el-button>
|
||||
<!-- <el-button size="small" type="primary" @click="confirmUpload">确认上传</el-button> -->
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import generate from 'nanoid/generate'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
formData: {
|
||||
'name': 'vasptask-' + generate('abcdefghijklmnopqrstuvwxyz', 12),
|
||||
'partition': 'C64T1',
|
||||
'nNode': '1',
|
||||
'workDir': '/vasp',
|
||||
'cmdScript': '#!/bin/bash\n sbatch vasp.sh'
|
||||
},
|
||||
fileList: [],
|
||||
settingFlag: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
formDataRules() {
|
||||
return {
|
||||
name: [
|
||||
{ required: true, message: this.$t('check.input') + this.$t('message.name') },
|
||||
{
|
||||
pattern: /^[a-z]([-a-z0-9]*[a-z0-9])?$/,
|
||||
message: this.$t('check.inputInvalid')
|
||||
}
|
||||
// { validator: this.nameValidator }
|
||||
],
|
||||
partition: [
|
||||
{ required: true, message: this.$t('check.input') + this.$t('page.partition') }
|
||||
],
|
||||
cmdScript: [
|
||||
{ required: true, message: this.$t('check.input') + this.$t('page.cmdScript') }
|
||||
],
|
||||
workDir: [
|
||||
{ required: true, message: this.$t('check.input') + this.$t('page.workMenu') }
|
||||
],
|
||||
nNode: [
|
||||
{ required: true, message: this.$t('check.input') + this.$t('page.nodeNum') }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitUpload() {
|
||||
// console.log(formData)
|
||||
|
||||
// 阻止默认上传行为
|
||||
return false
|
||||
},
|
||||
checkForm() {
|
||||
let returnVal
|
||||
this.$refs.formData.validate((valid) => {
|
||||
if (valid) {
|
||||
const form = new FormData()
|
||||
this.$refs.upload.uploadFiles.forEach((file, index) => {
|
||||
form.append(`files`, file.raw)
|
||||
})
|
||||
form.set('clusterId', '1830873903296155648')
|
||||
form.set('workDir', this.formData.workDir)
|
||||
// uploadVaspContent(form).then((e) => {
|
||||
// if (e.code === 0) {
|
||||
// this.$message.success(this.$t('page.uploadSuccess'))
|
||||
const params = {
|
||||
...this.formData,
|
||||
fileData: form
|
||||
}
|
||||
returnVal = params
|
||||
// } else {
|
||||
// this.$message.error(e.data)
|
||||
// // this.submitLoading = false
|
||||
// }
|
||||
// }).catch(e => {
|
||||
// // this.submitLoading = false
|
||||
// })
|
||||
} else {
|
||||
returnVal = false
|
||||
}
|
||||
})
|
||||
return returnVal
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.form-wrap .el-form-item__label-wrap .el-form-item__label{
|
||||
text-indent: -1rem!important;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -43,7 +43,8 @@
|
|||
<div class="taskForm">
|
||||
<div v-show="!selectCluster&&!strategySetting">
|
||||
<application-form v-show="cpType === 'cloud'&&taskType === 'application'" ref="application" />
|
||||
<hpc-create v-if="cpType === 'hpc'" ref="hpcBase" />
|
||||
<hpc-create v-if="cpType === 'hpc'&&taskType === 'hpcBase'" ref="hpcBase" />
|
||||
<vasp-create v-if="cpType === 'hpc'&&taskType === 'hpcVasp'" ref="hpcVasp" />
|
||||
<ai-create v-if="cpType === 'ai'&&taskType!=='deductive'" ref="aiBase" :type="taskType" :adapter-id="formData.adapterId" />
|
||||
<vm-form v-if="taskType === 'virtualmachine'" ref="virtualmachine" />
|
||||
<deductive-form v-if="taskType === 'deductive'" ref="deductive" :adapter-id="formData.adapterId" />
|
||||
|
|
@ -203,11 +204,11 @@
|
|||
<el-row type="flex" justify="end">
|
||||
<el-col :span="2.5">
|
||||
<el-button size="medium" @click="goBack">{{ $t("message.cancel") }}</el-button>
|
||||
<el-button v-if="!selectCluster&&!strategySetting&&taskType!=='aiCard'&&taskType!=='deductive'" size="medium" type="primary" @click="next">{{ $t('message.next') }}</el-button>
|
||||
<el-button v-if="!selectCluster&&!strategySetting&&taskType!=='aiCard'&&taskType!=='deductive'&&taskType!=='hpcVasp'" size="medium" type="primary" @click="next">{{ $t('message.next') }}</el-button>
|
||||
<el-button v-if="selectCluster" size="medium" type="primary" @click="selectCluster=false">{{ $t('message.before') }}</el-button>
|
||||
<el-button v-if="selectCluster&&!strategySetting&&taskType!=='aiCard'&&taskType!=='deductive'" size="medium" type="primary" @click="setStrategy">{{ $t('message.next') }}</el-button>
|
||||
<el-button v-if="strategySetting" size="medium" type="primary" @click="strategySetting=false;selectCluster=true">{{ $t('message.before') }}</el-button>
|
||||
<el-button v-if="strategySetting || taskType==='aiCard' || taskType==='deductive'" v-loading="submitLoading" size="medium" type="primary" @click="saveForm">{{ $t('message.create') }}</el-button>
|
||||
<el-button v-if="strategySetting || taskType==='aiCard' || taskType==='deductive' || taskType==='hpcVasp'" v-loading="submitLoading" size="medium" type="primary" @click="saveForm">{{ $t('message.create') }}</el-button>
|
||||
<!-- <el-button size="medium" type="primary" @click="saveForm">{{ $t("message.easyCreate") }}</el-button> -->
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
|
@ -216,9 +217,10 @@
|
|||
|
||||
<script>
|
||||
import List from '@/components/list'
|
||||
import { addApp, addHpcTask, addAITask, addVirtualMachine, getBalanceById, addDeductiveImageTask, addDeductiveTextTask } from '@/api/task/task'
|
||||
import { addApp, addHpcTask, addAITask, addVirtualMachine, getBalanceById, addDeductiveImageTask, addDeductiveTextTask, uploadVaspContent } from '@/api/task/task'
|
||||
import applicationForm from './components/applicationForm'
|
||||
import hpcCreate from './components/hpcCreate.vue'
|
||||
import vaspCreate from './components/hpcVasp.vue'
|
||||
import { getClusterList } from '@/api/container/cluster'
|
||||
import aiCreate from './components/aiCreate.vue'
|
||||
import { getAdapterList } from '@/api/pcm/adapter'
|
||||
|
|
@ -228,7 +230,7 @@ import { mapGetters } from 'vuex'
|
|||
|
||||
// import jobForm from './components/jobForm.vue'
|
||||
export default {
|
||||
components: { applicationForm, List, hpcCreate, aiCreate, vmForm, deductiveForm },
|
||||
components: { applicationForm, List, hpcCreate, aiCreate, vmForm, deductiveForm, vaspCreate },
|
||||
data() {
|
||||
return {
|
||||
getClusterList,
|
||||
|
|
@ -255,7 +257,8 @@ export default {
|
|||
'virtualmachine': 'createVirtualmachine'
|
||||
},
|
||||
'hpc': {
|
||||
'hpcBase': 'createHpcbase'
|
||||
'hpcBase': 'createHpcbase',
|
||||
'hpcVasp': 'createVasp'
|
||||
},
|
||||
'ai': {
|
||||
'aiBase': 'createAibase',
|
||||
|
|
@ -373,6 +376,10 @@ export default {
|
|||
list[i] = e.data.list.filter(r => r.type === '2')
|
||||
break
|
||||
}
|
||||
case 'hpcVasp': {
|
||||
list[i] = e.data.list.filter(r => r.id === '1830873578531196928')
|
||||
break
|
||||
}
|
||||
case 'aiBase': {
|
||||
list[i] = e.data.list.filter(r => r.type === '1')
|
||||
break
|
||||
|
|
@ -396,7 +403,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
getCluster() {
|
||||
const query = { 'type': this.taskType === 'application' ? '0' : (this.taskType === 'aiBase' || this.taskType === 'aiCard') ? '1' : this.taskType === 'hpcBase' ? '2' : '0', 'adapterId': this.formData.adapterId, pageNum: 1, pageSize: 1000 }
|
||||
const query = { 'type': this.taskType === 'application' ? '0' : (this.taskType === 'aiBase' || this.taskType === 'aiCard') ? '1' : (this.taskType === 'hpcBase' || this.taskType === 'hpcVasp') ? '2' : '0', 'adapterId': this.formData.adapterId, pageNum: 1, pageSize: 1000 }
|
||||
this.getClusterList(query).then(e => {
|
||||
this.currentClusterList = e.data.list || []
|
||||
})
|
||||
|
|
@ -498,6 +505,29 @@ export default {
|
|||
})
|
||||
break
|
||||
}
|
||||
case 'hpcVasp': {
|
||||
delete formHook.adapterIds
|
||||
delete formHook.aiClusterIds
|
||||
formHook.clusterId = '1830873903296155648'
|
||||
uploadVaspContent(formHook.fileData).then((e) => {
|
||||
if (e.code === 0) {
|
||||
// this.$message.success(this.$t('page.uploadSuccess'))
|
||||
delete formHook.fileData
|
||||
addHpcTask(formHook).then(() => {
|
||||
this.$message.success(this.$t('page.createdSuccess'))
|
||||
this.$router.push({ path: '/taskManagement/taskList' })
|
||||
}).catch(e => {
|
||||
this.submitLoading = false
|
||||
})
|
||||
} else {
|
||||
this.$message.error(e.data)
|
||||
this.submitLoading = false
|
||||
}
|
||||
}).catch(() => {
|
||||
this.submitLoading = false
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'aiBase': {
|
||||
formHook.adapterId = formHook.adapterIds[0]
|
||||
delete formHook.adapterIds
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
</el-tab-pane> -->
|
||||
<el-tab-pane v-if="formData.clusterInfos && formData.taskTypeDict !== '11' && formData.taskTypeDict !== '12'" :label="$t('page.taskLog')">
|
||||
<el-select v-model="cluster" style="width:70%" @change="selectCluster(cluster)">
|
||||
<el-select v-if="!formData.subTaskInfos[0].workDir" v-model="cluster" style="width:70%" @change="selectCluster(cluster)">
|
||||
<el-option
|
||||
v-for="item in formData.clusterInfos"
|
||||
:key="item.id"
|
||||
|
|
@ -89,7 +89,7 @@
|
|||
<script>
|
||||
import List from '@/components/list'
|
||||
import { FormData } from '@/components/FormData'
|
||||
import { getTaskDetail, getTaskLog, getDeductiveDetail } from '@/api/task/task'
|
||||
import { getTaskDetail, getTaskLog, getDeductiveDetail, downloadVaspContent } from '@/api/task/task'
|
||||
import { mapGetters } from 'vuex'
|
||||
import bootChart from './components/boot'
|
||||
|
||||
|
|
@ -168,6 +168,11 @@ export default {
|
|||
if (this.formData.taskTypeDict === '12') {
|
||||
this.inferId = this.formData.subTaskInfos[0].id
|
||||
}
|
||||
if (res.data.subTaskInfos[0].workDir) {
|
||||
downloadVaspContent({ workDir: res.data.subTaskInfos[0].workDir, fileName: 'demo.out', clusterId: this.formData.clusterInfos[0].id }).then(e => {
|
||||
this.log = e
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
|
|
|||
|
|
@ -63,6 +63,12 @@ module.exports = {
|
|||
changeOrigin: true,
|
||||
secure: false
|
||||
},
|
||||
'^/ai4m': {
|
||||
ws: false,
|
||||
target: 'https://ai4m.jointcloud.net:443/',
|
||||
changeOrigin: true,
|
||||
secure: false
|
||||
},
|
||||
'^/auth': {
|
||||
ws: false,
|
||||
target: 'https://comnet.jointcloud.net/',
|
||||
|
|
|
|||
Loading…
Reference in New Issue