feat: websocket展示资源利用率

This commit is contained in:
zy7y 2022-09-17 01:10:33 +08:00
parent 8e725d3f78
commit 29c6e368ae
9 changed files with 240 additions and 9 deletions

View File

@ -1 +1,2 @@
VITE_BASE_URL = /api
VITE_WEBSOCKET = /socket

View File

@ -1 +1,2 @@
VITE_BASE_URL = http://127.0.0.1:8000/api/
VITE_BASE_URL = http://127.0.0.1:8000/api
VITE_WEBSOCKET = ws://localhost:8000/ws

View File

@ -10,6 +10,7 @@
"dependencies": {
"ant-design-vue": "^3.2.12",
"axios": "^0.27.2",
"echarts": "^5.3.3",
"moment": "^2.29.4",
"normalize.css": "^8.0.1",
"pinia": "^2.0.21",
@ -807,6 +808,15 @@
"resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz",
"integrity": "sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w=="
},
"node_modules/echarts": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/echarts/-/echarts-5.3.3.tgz",
"integrity": "sha512-BRw2serInRwO5SIwRviZ6Xgm5Lb7irgz+sLiFMmy/HOaf4SQ+7oYqxKzRHAKp4xHQ05AuHw1xvoQWJjDQq/FGw==",
"dependencies": {
"tslib": "2.3.0",
"zrender": "5.3.2"
}
},
"node_modules/esbuild": {
"version": "0.15.7",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.7.tgz",
@ -2628,6 +2638,11 @@
"node": ">=8.0"
}
},
"node_modules/tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
},
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@ -2928,6 +2943,14 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/zrender": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.3.2.tgz",
"integrity": "sha512-8IiYdfwHj2rx0UeIGZGGU4WEVSDEdeVCaIg/fomejg1Xu6OifAL1GVzIPHg2D+MyUkbNgPWji90t0a8IDk+39w==",
"dependencies": {
"tslib": "2.3.0"
}
}
},
"dependencies": {
@ -3536,6 +3559,15 @@
"resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz",
"integrity": "sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w=="
},
"echarts": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/echarts/-/echarts-5.3.3.tgz",
"integrity": "sha512-BRw2serInRwO5SIwRviZ6Xgm5Lb7irgz+sLiFMmy/HOaf4SQ+7oYqxKzRHAKp4xHQ05AuHw1xvoQWJjDQq/FGw==",
"requires": {
"tslib": "2.3.0",
"zrender": "5.3.2"
}
},
"esbuild": {
"version": "0.15.7",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.7.tgz",
@ -4726,6 +4758,11 @@
"is-number": "^7.0.0"
}
},
"tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
},
"type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@ -4911,6 +4948,14 @@
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true
},
"zrender": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.3.2.tgz",
"integrity": "sha512-8IiYdfwHj2rx0UeIGZGGU4WEVSDEdeVCaIg/fomejg1Xu6OifAL1GVzIPHg2D+MyUkbNgPWji90t0a8IDk+39w==",
"requires": {
"tslib": "2.3.0"
}
}
}
}

View File

@ -11,6 +11,7 @@
"dependencies": {
"ant-design-vue": "^3.2.12",
"axios": "^0.27.2",
"echarts": "^5.3.3",
"moment": "^2.29.4",
"normalize.css": "^8.0.1",
"pinia": "^2.0.21",

View File

@ -0,0 +1,107 @@
<script setup>
import Echart from './echart.vue'
import { computed } from 'vue'
const props = defineProps({
cpuValue: {
type: String,
require: true
},
memoryValue: {
type: String,
require: true
},
diskValue: {
type: String,
require: true
},
style: {
type: Object
}
})
const options = computed(() => {
const gaugeData = [
{
value: props.cpuValue,
name: 'CPU',
title: {
offsetCenter: ['-60%', '80%']
},
detail: {
offsetCenter: ['-60%', '95%']
}
},
{
value: props.memoryValue,
name: 'MEMORY',
title: {
offsetCenter: ['0%', '80%']
},
detail: {
offsetCenter: ['0%', '95%']
}
},
{
value: props.diskValue,
name: 'DISK',
title: {
offsetCenter: ['60%', '80%']
},
detail: {
offsetCenter: ['60%', '95%']
}
}
]
return {
series: [
{
type: 'gauge',
anchor: {
show: true,
showAbove: true,
size: 18,
itemStyle: {
color: '#FAC858'
}
},
pointer: {
icon: 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z',
width: 8,
length: '80%',
offsetCenter: [0, '8%']
},
progress: {
show: true,
overlap: true,
roundCap: true
},
axisLine: {
roundCap: true
},
data: gaugeData,
title: {
fontSize: 14
},
detail: {
width: 40,
height: 14,
fontSize: 14,
color: '#fff',
backgroundColor: 'auto',
borderRadius: 3,
formatter: '{value}%'
}
}
]
}
})
</script>
<template>
<div class="system-info">
<Echart :options="options" :style="style" />
</div>
</template>
<style scoped></style>

View File

@ -0,0 +1,38 @@
<script setup>
import { ref, onMounted, watchEffect } from 'vue'
import * as echarts from 'echarts'
const props = defineProps({
options: {
type: Object,
require: true
},
style: {
type: Object,
default: () => ({
width: '100%',
height: '360px'
})
}
})
const echartRef = ref()
onMounted(() => {
const instance = echarts.init(echartRef.value)
// props
watchEffect(() => {
console.log('eachart 基础组件')
instance.setOption(props.options)
})
})
</script>
<template>
<div class="echart">
<div ref="echartRef" :style="style"></div>
</div>
</template>
<style scoped></style>

View File

@ -1,7 +1,46 @@
<script setup></script>
<script setup>
import { onUnmounted, ref } from 'vue'
import EchartSystemInfo from '@/components/echart/echart-system-info.vue'
/** websocket */
let ws = new WebSocket('ws://localhost:8000/ws')
const wsData = ref()
ws.onmessage = (e) => {
//
wsData.value = JSON.parse(e.data)
}
onUnmounted(() => {
ws.close()
})
</script>
<template>
<div>about</div>
<div class="about">
<a-card class="system">
<template #title> 资源使用率(虚拟数据) </template>
<EchartSystemInfo
:cpu-value="wsData?.usage.cpu"
:disk-value="wsData?.usage.disk"
:memory-value="wsData?.usage.memory"
:style="{ width: '100%', height: '300px' }"
/>
</a-card>
</div>
</template>
<style scoped></style>
<style scoped>
.about {
width: 100%;
height: 100%;
}
.system {
width: 50%;
}
.header .ant-card {
width: 40%;
}
</style>

View File

@ -6,7 +6,6 @@ import { PlusOutlined } from '@ant-design/icons-vue'
import { getRoles, queryRole, delRole, putRole, addRole } from '@/service/role'
import { getMenus } from '@/service/menu'
import { columns, rules, treeFieldNames } from './conf'
import { formatTime } from '@/utils/format'
import { message } from 'ant-design-vue'
import { getMenus as getRoleMenu } from '@/service/user'
@ -239,10 +238,10 @@ watch(
</a-tag>
</template>
<template v-else-if="column.key === 'created'">
{{ formatTime(record.created) }}
{{ $$formatTime(record.created) }}
</template>
<template v-else-if="column.key === 'modified'">
{{ formatTime(record.modified) }}
{{ $$formatTime(record.modified) }}
</template>
<template v-else-if="column.key === 'action'">
<span>

View File

@ -26,8 +26,8 @@ export default defineConfig({
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
},
'/socket.io': {
target: 'ws://localhost:5000',
'/socket': {
target: 'ws://localhost:8000/ws',
ws: true
}
}