jcce样式: 项目列表 工作负载列表

接口:容器概览节点用量接口对接
This commit is contained in:
jhnine 2022-04-05 22:46:59 +08:00
parent 8610f1032d
commit 7b0be632c7
12 changed files with 452 additions and 170 deletions

View File

@ -43,7 +43,6 @@
"script-loader": "0.7.2",
"sortablejs": "1.8.4",
"three": "^0.126.1",
"tui-editor": "1.3.3",
"vue": "2.6.10",
"vue-codemirror": "^4.0.6",
"vue-count-to": "1.0.13",

View File

@ -31,3 +31,12 @@ export function getNodeBriefMessage(url) {
method: 'get'
})
}
// 容器概览页面--节点用量 新
export function getNodeMessageTop(url) {
return request({
url: '/jcc-extend/container/node/' + url + '/getClusterNode',
method: 'get'
})
}

View File

@ -1,9 +1,21 @@
<template>
<div class="topList">
<div v-for="(node, index) in nodeMessage" :key="index">
<p>{{ node.node }} <span>{{ node.role }}</span></p>
<el-progress :stroke-width="8" :percentage="Number(parseFloat(node.cpu).toFixed(2)) > 100 ? 100 : Number(parseFloat(node.cpu).toFixed(2))" />
</div>
<table>
<tr v-for="(node, index) in nodeMessage" :key="index">
<td width="5%">
<div class="num">{{ index + 1 }}</div>
</td>
<td width="35%">
<p>{{ node.node }}<span>({{ node.ip }})</span></p>
<p>
<span class="role">{{ node.role }}</span>
</p>
</td>
<td width="60%">
<el-progress :stroke-width="8" :percentage="Number(parseFloat(node.cpu).toFixed(2)) > 100 ? 100 : Number(parseFloat(node.cpu).toFixed(2))" />
</td>
</tr>
</table>
</div>
</template>
@ -51,7 +63,8 @@ export default {
ip = response['results'][index]['data']['result'][l]['metric']['host_ip']
role = response['results'][index]['data']['result'][l]['metric']['role']
cpu = (parseFloat(response['results'][index]['data']['result'][l]['value'][1]) * 100).toFixed(2)
obj.node = name + ' (' + ip + ')'
obj.node = name
obj.ip = ip
if (role === 'master') { obj.role = role } else { obj.role = 'node' }
obj.cpu = cpu
data[l] = obj
@ -66,29 +79,45 @@ export default {
</script>
<style lang="scss" scoped>
.topList{
>div{margin-bottom: 10px;}
p{
margin:0;
.topList {
> div {
margin-bottom: 10px;
}
.num{
width: 42px;
height: 42px;
line-height: 42px;
background: #454B53;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.25);
border-radius: 10px;
color: white;
text-align:center;
margin: 8px 20px 14px 0;
}
p {
margin: 0;
font-weight: bold;
font-size: 0.8rem;
font-size: 0.85rem;
margin-bottom: 5px;
span{
color:#999999;
font-weight: 500;
}
.role {
display: inline-block;
// float: left;
color: blue;
background-color: #e6ebf5;
border-radius: 20px;
padding: 1px 8px;
font-weight: 200;
color: #3182CE;
background: #E1E7F8;
border-radius: 12px;
padding: 5px 11px;
margin-top: 5px;
font-size: 0.7rem;
margin-left: 15px;
}
}
}
</style>
<style lang="scss">
.topList .el-progress-bar__inner{
background-image: linear-gradient(90deg, #419eff, #00d9a6)
background-image: linear-gradient(90deg, #419eff, #00d9a6);
}
</style>

View File

@ -0,0 +1,225 @@
<template>
<div id="barChart" ref="barChart" />
</template>
<script>
import * as echarts from 'echarts'
import { getNodeMessageTop } from '@/api/one-class-page/overview'
export default {
name: 'NodeMessageBar',
data() {
return {
data: [7, 5, 3, 2, 2],
data2: [11, 6, 4, 3, 1]
}
},
computed: {
clusterName() {
return localStorage.getItem('clusterName')
}
},
mounted() {
return new Promise(() => {
getNodeMessageTop(this.clusterName).then(res => {
if (res.data?.[0]?.node_cpu_utilisation) {
this.xAxis = Object.keys(res.data?.[0]?.node_cpu_utilisation)
this.data = Object.values(res.data?.[0]?.node_cpu_utilisation)?.map(n => (parseFloat(n.value) * 100).toFixed(0))
}
if (res.data?.[0]?.node_load1) {
this.data2 = Object.values(res.data?.[0]?.node_load1)?.map(n => (parseFloat(n.value) * 100).toFixed(0))
}
this.drawChart()
}).catch(error => {
console.log(error)
})
})
},
methods: {
drawChart() {
const axisLabel = {
textStyle: {
color: '#333333',
fontSize: 12
},
interval: 'auto',
formatter: '{value} %'
}
const option = {
type: 'value',
axisLine: {
show: false
},
axisTick: {
show: false
},
splitLine: {
show: false
}
}
const legend = ['按照CPU使用率', '按照CPU平均负载']
//
const barChart = echarts.init(this.$refs.barChart)
const loadOption = {
grid: {
left: '0%',
right: '0%',
top: '15%',
bottom: '10%',
containLabel: true
},
tooltip: {
trigger: 'axis'
},
legend: {
data: legend,
textStyle: {
color: '#999999',
fontSize: 12
}
},
xAxis: [
{
...option,
type: 'category',
data: this.xAxis
}
],
yAxis: [
{
name: '',
...option,
axisLabel
},
{
name: '',
...option,
axisLabel
}
],
series: [
{
name: legend[0],
type: 'pictorialBar',
symbolSize: [20, 7],
symbolOffset: [-12, -5],
symbolPosition: 'end',
z: 12,
tooltip: {
show: false
},
color: '#3182CE',
data: this.data
},
{
name: legend[0],
type: 'pictorialBar',
symbolSize: [20, 6],
tooltip: {
show: false
},
symbolOffset: [-12, 5],
z: 12,
color: 'rgba(49, 130, 206, 0.4)',
data: this.data
},
{
type: 'bar',
name: legend[0],
barWidth: '20',
yAxisIndex: 0,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: '#3182CE'
},
{
offset: 1,
color: 'rgba(49, 130, 206, 0.25)'
}
],
false
),
opacity: 1
}
},
data: this.data
},
{
name: legend[1],
type: 'pictorialBar',
symbolSize: [20, 10],
symbolOffset: [12, -5],
symbolPosition: 'end',
z: 12,
tooltip: {
show: false
},
color: '#30BFB7',
data: this.data2
},
{
name: legend[1],
type: 'pictorialBar',
symbolSize: [20, 7],
tooltip: {
show: false
},
symbolOffset: [12, 6],
z: 12,
color: 'rgba(48, 191, 183, 0.4)',
data: this.data2
},
{
type: 'bar',
name: legend[1],
barWidth: '20',
yAxisIndex: 1,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: '#30C0B7'
},
{
offset: 1,
color: 'rgba(48, 191, 183, 0.25)'
}
],
false
),
opacity: 1
}
},
data: this.data2
}
]
}
barChart.setOption(loadOption)
window.addEventListener('resize', function() {
barChart.resize()
})
}
}
}
</script>
<style lang="scss" scoped>
#barChart {
width: 100%;
height: 216px;
}
</style>

View File

@ -125,10 +125,6 @@ export default {
</script>
<style lang="scss">
.el-table .cell {
text-align: center;
white-space: pre-line;/*保留换行符*/
}
.node-name{
background: url('../../assets/images/node_name.png') no-repeat;
background-size: 32px 37px;

View File

@ -182,14 +182,13 @@ export default {
show: true,
areaStyle: {
color: ['#F4F7FE']
//
}},
}
},
splitLine: {
show: true,
lineStyle: {
width: 1,
color: ['#E8E9ED']
// 线
}
},
indicator: [

View File

@ -1,82 +1,82 @@
<template>
<div>
<el-form v-if="filterMap" :inline="true" class="demo-form-inline">
<el-form-item
v-for="(item, key) in filterMap"
:key="key"
:label="item.label+':'"
>
<RenderCell
v-if="item.render"
:render="item.render"
:item-key="key"
:filter-data="filterData"
/>
<template v-else>
<el-select
v-if="item.type === 'select'"
v-model="filterData[key]"
size="medium"
>
<el-option v-for="(it,idx) in item.dataSource" :key="key+idx" :label="it.label" :value="it.value" />
</el-select>
<el-datepicker
v-else-if="item.type === 'date'"
v-model="filterData[key]"
type="date"
<div class="list-btns">
<el-form v-if="filterMap" :inline="true" class="demo-form-inline">
<el-form-item
v-for="(item, key) in filterMap"
:key="key"
:label="item.label+':'"
>
<RenderCell
v-if="item.render"
:render="item.render"
:item-key="key"
:filter-data="filterData"
/>
<template
v-else-if="item.type === 'dateRange'"
>
<el-date-picker
<template v-else>
<el-select
v-if="item.type === 'select'"
v-model="filterData[key]"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
size="medium"
>
<el-option v-for="(it,idx) in item.dataSource" :key="key+idx" :label="it.label" :value="it.value" />
</el-select>
<el-datepicker
v-else-if="item.type === 'date'"
v-model="filterData[key]"
type="date"
/>
<template
v-else-if="item.type === 'dateRange'"
>
<el-date-picker
v-model="filterData[key]"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
<!-- <el-datepicker
v-model="filterData[item.key1]"
type="date"
:clearable="false"
:format='item.format'>
</el-datepicker>
-
<el-datepicker
v-model="filterData[item.key2]"
type="date"
:clearable="false"
:format='item.format'>
</el-datepicker> -->
</template>
<el-input
v-else
v-model="filterData[key]"
size="medium"
@enter="onSearchClick"
/>
<!-- <el-datepicker
v-model="filterData[item.key1]"
type="date"
:clearable="false"
:format='item.format'>
</el-datepicker>
-
<el-datepicker
v-model="filterData[item.key2]"
type="date"
:clearable="false"
:format='item.format'>
</el-datepicker> -->
</template>
<el-input
v-else
v-model="filterData[key]"
</el-form-item>
<el-form-item>
<el-button
size="medium"
@enter="onSearchClick"
/>
</template>
</el-form-item>
<el-form-item>
<el-button
size="medium"
type="info"
@click="onSearchClick"
>
查询
</el-button>
</el-form-item>
<el-form-item>
<el-button
size="medium"
@click="resetSearch"
>
重置
</el-button>
</el-form-item>
</el-form>
<!-- {{tableData}}-->
<slot name="filterBtns" />
type="info"
@click="onSearchClick"
>
查询
</el-button>
<el-button
size="medium"
@click="resetSearch"
>
重置
</el-button>
</el-form-item>
</el-form>
<!-- {{tableData}}-->
<slot name="filterBtns" />
</div>
<el-table
v-if="tableData.length>0"
ref="multipleTable"
@ -249,6 +249,18 @@ export default {
</script>
<style lang="scss" scoped>
.list-btns{
display: flex;
width: 100%;
background: #F7F7F7;
margin-bottom: 24px;
align-items: flex-start;
padding: 18px 20px 0;
margin-bottom: 24px;
.demo-form-inline{
flex: 1;
}
}
.filter-field{
margin-bottom: 20px;
// font-size: 0.9rem;

View File

@ -235,40 +235,29 @@ span.title-tips {
height: 260px;
}
.el-table{
// border: 1px solid #eeeeee;
// border-bottom: 0px;
th {
background: #f5f5f5;
}
}
.el-table::before{
height: 0;
}
.table{
width: 100%;
font-size: 0.8rem;
border-top: 1px solid #eeeeee;
border-left: 1px solid #eeeeee;
border-spacing: 0;
font-size: 14px;
color: #333333;
th{
font-weight: normal;
text-align: left;
background-color: #f5f5f5;
padding: 12px 10px;
line-height: 23px;
}
th,td{
border-right: 1px solid #eeeeee;
border-bottom: 1px solid #eeeeee;
margin: 0;
padding: 0 10px;
line-height: 2rem;
text-align: center;
}
td{
color: #999999;
padding: 10px;
line-height: 20px;
border-bottom: 1px solid #eeeeee;
}
}
@ -349,43 +338,59 @@ span.title-tips {
// }
// 2022-03-30 样式改造 jh
.el-button--default{
color: #666666;
}
.el-button--info{
color: white;
background: #454B53;
box-shadow: 0px 5px 8px 0px rgba(51, 51, 51, 0.25);
border-radius: 4px;
.el-button{
&--medium {
padding: 10px 35px;
}
&--default{
color: #666666;
}
&--info{
color: white;
background: #454B53;
box-shadow: 0px 5px 8px 0px rgba(51, 51, 51, 0.25);
border-radius: 4px;
}
&--mini{
&.is-circle {
padding: 6px;
}
}
}
.el-pagination.is-background .el-pager li:not(.disabled).active {
background-color: $subMenuActiveText;
}
.el-button--medium {
padding: 10px 35px;
}
.el-table thead {
color: #333333;
font-size: 16px;
}
.el-table{
color: #333333;
}
.el-table--medium th {
padding: 17px 0;
}
.el-table th {
background: #F7F7F7;
&::before{
height: 0;
}
&--medium {
th{
padding: 12px 0;
}
}
thead {
color: #333333;
font-size: 16px;
}
th{
background: #F7F7F7;
}
td{
.cell{
line-height: 20px;
}
}
.cell {
text-align: center;
white-space: pre-line;/*保留换行符*/
}
}
.el-submenu .el-menu-item {
height: 58px;
line-height: 58px;
}
.demo-form-inline{
padding: 26px 20px 8px;
background: #F7F7F7;
margin-bottom: 24px;
}
span.round{
display: inline-block;
width: 8px;

View File

@ -28,15 +28,15 @@
<el-col :span="24">
<el-card shadow="never">
<div slot="header" class="clearfix">
<span>CPU节点用量 Top5</span>
<span>CPU节点用量</span>
</div>
<!-- <TotalLoadChart id="loadChart" :data="dataBar" :data2="dataBar2" /> -->
<NodeMessageBar />
</el-card>
</el-col>
<el-col :span="24">
<el-card shadow="never">
<div slot="header" class="clearfix">
<span>节点用量 Top5本地内存</span>
<span>节点用量 Top5内存占比</span>
</div>
<NodeMessage />
</el-card>
@ -50,11 +50,11 @@ import ClusterMessage from '@/components/ClusterManagement/clusterMessage'
import ComponentStatus from '@/components/ClusterManagement/componentStatus'
import NodeMessage from '@/components/ClusterManagement/nodeMessage'
import ResourceUsage from '@/components/ClusterManagement/resourceUsage'
// import TotalLoadChart from '@/components/ClusterManagement/TotalLoadChart'
import NodeMessageBar from '@/components/ClusterManagement/nodeMessageBar'
export default {
components: {
ClusterMessage, ComponentStatus, ResourceUsage, NodeMessage
ClusterMessage, ComponentStatus, ResourceUsage, NodeMessage, NodeMessageBar
}
}
</script>

View File

@ -1,15 +1,14 @@
<template>
<div class="projectInfo">
<el-card class="basicInfo" shadow="never">
<img src="@/assets/img/project.png" class="sidebar-logo">
<img src="@/assets/images/node.png" class="sidebar-logo" alt="项目">
<h4>项目</h4>
<span class="tips">
<span class="tips title-tips">
将根据项目资源进行分组, 可以按项目对资源进行查看管理</span>
<el-button v-if="activeName ==='0'" class="create-btn" type="primary" @click="createFormVisible = true">创建</el-button>
</el-card>
<BaseInfoForm v-model="dialogFormVisible" :data="editInfoForm" @getList="getList" />
<el-card shadow="never">
<el-tabs v-model="activeName" @tab-click="switchTab">
<el-tabs v-model="activeName" type="card" @tab-click="switchTab">
<el-tab-pane key="userProject" label="用户项目">
<List
ref="multipleTable1"
@ -20,7 +19,11 @@
:filter-map="filterMap"
:pagination="true"
tooltip-effect="dark"
/>
>
<template v-slot:filterBtns>
<el-button v-if="activeName ==='0'" size="medium" type="primary" @click="createFormVisible = true">创建</el-button>
</template>
</List>
</el-tab-pane>
<el-tab-pane key="systemProject" label="系统项目">
<List
@ -156,8 +159,4 @@ export default {
.projectInfo{
text-align: left;
}
.create-btn{
float: right;
margin-top: -35px;
}
</style>

View File

@ -1,15 +1,14 @@
<template>
<div class="workloadsInfo">
<el-card class="basicInfo" shadow="never">
<img src="@/assets/img/workLoad.png" class="sidebar-logo">
<el-button type="primary" class="floatRight" @click="createFormVisible = true">创建</el-button>
<img src="@/assets/images/node.png" class="sidebar-logo" alt="工作负载">
<h4>工作负载</h4>
<span class="tips">
<span class="tips title-tips">
工作负载 (Workload) 通常是访问服务的实际载体, 也是对节点日志收集监控等系统应用的实际运行载体是对一组容器组 (Pod) 的抽象模型</span>
</el-card>
<BaseInfoForm v-model="dialogFormVisible" :data="editInfoForm" :classification="tabList[activeName]" @getList="getList" />
<el-card shadow="never">
<el-tabs v-model="activeName" @tab-click="switchTab">
<el-tabs v-model="activeName" type="card" @tab-click="switchTab">
<el-tab-pane key="deployments" label="部署">
<List
v-if="activeName==='0'"
@ -21,7 +20,11 @@
:cluster-name="clusterName"
:pagination="true"
tooltip-effect="dark"
/>
>
<template v-slot:filterBtns>
<el-button size="medium" type="primary" @click="createFormVisible = true">创建</el-button>
</template>
</List>
</el-tab-pane>
<el-tab-pane key="statefulsets" label="有状态副本集">
<List
@ -34,7 +37,11 @@
:cluster-name="clusterName"
:pagination="true"
tooltip-effect="dark"
/>
>
<template v-slot:filterBtns>
<el-button size="medium" type="primary" @click="createFormVisible = true">创建</el-button>
</template>
</List>
</el-tab-pane>
<el-tab-pane key="daemonsets" label="守护进程集">
<List
@ -47,7 +54,11 @@
:cluster-name="clusterName"
:pagination="true"
tooltip-effect="dark"
/>
>
<template v-slot:filterBtns>
<el-button size="medium" type="primary" @click="createFormVisible = true">创建</el-button>
</template>
</List>
</el-tab-pane>
</el-tabs>
</el-card>
@ -187,10 +198,4 @@ export default {
}
</script>
<style lang="scss" scoped>
.workloadsInfo {
.floatRight {
margin: 30px 15px;
float: right;
}
}
</style>

View File

@ -93,6 +93,10 @@ module.exports = {
target: 'https://jointcloud.net/prod-api/'/* Host */
// changeOrigin: true,
},
'^/jcc-extend/': {
ws: false,
target: 'http://10.101.15.6:8000/' /* Host */
},
'^/virtual': {
ws: false,
target: 'https://106.53.150.192/',