-
11src/api/deviceVI/index.js
-
BINsrc/assets/images/serve1-1.png
-
BINsrc/assets/images/serve1-2.png
-
BINsrc/assets/images/serve1-3.png
-
BINsrc/assets/images/serve1.png
-
BINsrc/assets/images/ter1-1.png
-
BINsrc/assets/images/ter1.png
-
BINsrc/assets/images/ter2-1.png
-
BINsrc/assets/images/ter2.png
-
BINsrc/assets/images/ter3-1.png
-
BINsrc/assets/images/ter3.png
-
BINsrc/assets/images/ter4-1.png
-
BINsrc/assets/images/ter4.png
-
BINsrc/assets/images/ter5-1.png
-
BINsrc/assets/images/ter5.png
-
220src/views/components/echarts/serverGpu.vue
-
237src/views/components/echarts/serverGpuOther.vue
-
219src/views/components/echarts/serverGpuUse.vue
-
8src/views/components/echarts/serverProgress.vue
-
275src/views/components/echarts/serverProgress2.vue
-
15src/views/components/hkVideo.vue
-
302src/views/components/serveTerminal.vue
-
108src/views/home.vue
-
5src/views/visualCheck/venueDevice/bookshelfPosition/index.vue
-
15src/views/visualCheck/venueDevice/device/index.vue
After Width: 200 | Height: 200 | Size: 3.5 KiB |
After Width: 200 | Height: 200 | Size: 3.1 KiB |
After Width: 200 | Height: 200 | Size: 4.8 KiB |
After Width: 200 | Height: 200 | Size: 3.5 KiB |
After Width: 200 | Height: 200 | Size: 3.3 KiB |
After Width: 200 | Height: 200 | Size: 3.3 KiB |
After Width: 222 | Height: 200 | Size: 3.8 KiB |
After Width: 222 | Height: 200 | Size: 3.8 KiB |
After Width: 200 | Height: 200 | Size: 5.0 KiB |
After Width: 200 | Height: 200 | Size: 4.9 KiB |
After Width: 203 | Height: 200 | Size: 3.2 KiB |
After Width: 203 | Height: 200 | Size: 3.2 KiB |
After Width: 200 | Height: 200 | Size: 2.8 KiB |
After Width: 200 | Height: 200 | Size: 2.8 KiB |
@ -0,0 +1,220 @@ |
|||
<template> |
|||
<div id="main" :style="{height:height,width:width}" style="margin-top: -20px;" /> |
|||
</template> |
|||
|
|||
<script> |
|||
import * as echarts from 'echarts' |
|||
import resize from '@/views/dashboard/mixins/resize' |
|||
|
|||
export default { |
|||
name: 'EchartsComponent', |
|||
mixins: [resize], |
|||
props: { |
|||
temperature: { |
|||
type: Number, |
|||
require: true, |
|||
default: function() { |
|||
return 0 |
|||
} |
|||
}, |
|||
width: { |
|||
type: String, |
|||
default: '50%' |
|||
}, |
|||
height: { |
|||
type: String, |
|||
default: '100%' |
|||
} |
|||
}, |
|||
watch: { |
|||
'temperature': { |
|||
handler(val) { |
|||
setTimeout(() => { |
|||
this.initChart() |
|||
}, 100) |
|||
}, |
|||
immediate: true, |
|||
deep: true |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.initChart() |
|||
window.addEventListener('resize', this.__resizeHandler) |
|||
}, |
|||
methods: { |
|||
initChart() { |
|||
const chartDom = document.getElementById('main') |
|||
const myChart = echarts.init(chartDom) |
|||
|
|||
const axisLineHandler = (value) => { |
|||
const ratio = Number(value / 100) |
|||
if (ratio <= 0.7) { |
|||
return [ |
|||
[ratio, '#56BC91'], // 进度色 |
|||
[1, 'rgba(216, 216, 216, 1)'] // 背景色 |
|||
] |
|||
} else if (ratio <= 0.9) { |
|||
return [ |
|||
[ratio, '#FF973E'], // 进度色 |
|||
[1, 'rgba(216, 216, 216, 1)'] // 背景色 |
|||
] |
|||
} else if (ratio <= 1) { |
|||
return [ |
|||
[ratio, '#fd666d'], // 进度色 |
|||
[1, 'rgba(216, 216, 216, 1)'] // 背景色 |
|||
] |
|||
} |
|||
} |
|||
|
|||
const itemStyleHandler = (value) => { |
|||
if (value <= 70) { |
|||
return `#56BC91` |
|||
} else if (value <= 90) { |
|||
return `#FF973E` |
|||
} else if (value <= 100) { |
|||
return `#fd666d` |
|||
} |
|||
return '' |
|||
} |
|||
|
|||
// const dataNameHandler = (value) => { |
|||
// if (value <= 60) { |
|||
// return value + '°C' |
|||
// } else if (value <= 80) { |
|||
// return value + '°C' |
|||
// } else if (value <= 100) { |
|||
// return value + '°C' |
|||
// } |
|||
// return '' |
|||
// } |
|||
|
|||
const option = { |
|||
series: [ |
|||
{ |
|||
type: 'gauge', |
|||
center: ['40%', '38%'], |
|||
radius: 60, |
|||
startAngle: 200, |
|||
endAngle: -20, |
|||
min: 0, |
|||
max: 100, |
|||
splitNumber: 10, |
|||
itemStyle: { |
|||
color: itemStyleHandler(this.temperature) |
|||
}, |
|||
progress: { |
|||
show: true, |
|||
width: 20 |
|||
}, |
|||
pointer: { |
|||
show: false |
|||
}, |
|||
axisLine: { |
|||
lineStyle: { |
|||
width: 14, |
|||
color: axisLineHandler(this.temperature) |
|||
} |
|||
}, |
|||
axisTick: { |
|||
show: false, |
|||
distance: -35, |
|||
splitNumber: 5, |
|||
lineStyle: { |
|||
width: 2, |
|||
color: 'auto' |
|||
} |
|||
}, |
|||
splitLine: { |
|||
show: false, |
|||
distance: -42, |
|||
length: 14, |
|||
lineStyle: { |
|||
width: 3, |
|||
color: 'auto' |
|||
} |
|||
}, |
|||
axisLabel: { |
|||
show: false, |
|||
distance: -40, |
|||
color: 'inherit', |
|||
fontSize: 14 |
|||
}, |
|||
anchor: { |
|||
show: false |
|||
}, |
|||
title: { |
|||
show: true, |
|||
offsetCenter: [0, '50%'], |
|||
fontSize: 14, |
|||
color: '#000' |
|||
}, |
|||
detail: { |
|||
valueAnimation: true, |
|||
width: '60%', |
|||
lineHeight: 40, |
|||
borderRadius: 8, |
|||
offsetCenter: [0, '0'], |
|||
fontSize: 26, |
|||
fontWeight: 'bolder', |
|||
formatter: '{value} °C', |
|||
color: 'auto' |
|||
}, |
|||
data: [ |
|||
{ |
|||
value: this.temperature, |
|||
// name: dataNameHandler(dataValue) |
|||
name: '温度' |
|||
} |
|||
] |
|||
}, |
|||
// 最外侧 |
|||
{ |
|||
type: 'gauge', |
|||
radius: 66, // 半径 |
|||
center: ['40%', '38%'], // 位置 |
|||
min: 0, |
|||
max: 100, |
|||
startAngle: 200, |
|||
endAngle: -20, |
|||
axisLine: { |
|||
show: false, |
|||
lineStyle: { |
|||
width: 2, |
|||
color: '#999' |
|||
} |
|||
}, |
|||
axisTick: { |
|||
show: true, |
|||
splitNumber: 7, |
|||
length: 2, |
|||
lineStyle: { |
|||
width: 1, |
|||
color: '#999' |
|||
} |
|||
}, |
|||
splitLine: { |
|||
show: false |
|||
}, |
|||
axisLabel: { |
|||
show: false |
|||
}, |
|||
pointer: { |
|||
show: false |
|||
}, |
|||
detail: { |
|||
show: false |
|||
} |
|||
} |
|||
] |
|||
} |
|||
|
|||
if (option) { |
|||
myChart.setOption(option) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
</style> |
@ -0,0 +1,237 @@ |
|||
<template> |
|||
<div id="mainOther" :style="{height:height,width:width}" style="margin-top: -20px;" /> |
|||
</template> |
|||
|
|||
<script> |
|||
import * as echarts from 'echarts' |
|||
import resize from '@/views/dashboard/mixins/resize' |
|||
|
|||
export default { |
|||
name: 'EchartsComponent', |
|||
mixins: [resize], |
|||
props: { |
|||
memoryTotal: { |
|||
type: Number, |
|||
require: true, |
|||
default: function() { |
|||
return 0 |
|||
} |
|||
}, |
|||
memoryFree: { |
|||
type: Number, |
|||
require: true, |
|||
default: function() { |
|||
return 0 |
|||
} |
|||
}, |
|||
width: { |
|||
type: String, |
|||
default: '50%' |
|||
}, |
|||
height: { |
|||
type: String, |
|||
default: '100%' |
|||
} |
|||
}, |
|||
watch: { |
|||
'memoryTotal': { |
|||
handler(val) { |
|||
setTimeout(() => { |
|||
this.initChart() |
|||
}, 100) |
|||
}, |
|||
immediate: true, |
|||
deep: true |
|||
}, |
|||
'memoryFree': { |
|||
handler(val) { |
|||
setTimeout(() => { |
|||
this.initChart() |
|||
}, 100) |
|||
}, |
|||
immediate: true, |
|||
deep: true |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.initChart() |
|||
// window.addEventListener('resize', this.__resizeHandler) |
|||
}, |
|||
methods: { |
|||
initChart() { |
|||
const chartDom = document.getElementById('mainOther') |
|||
const myChart = echarts.init(chartDom) |
|||
|
|||
const dataValue = this.memoryTotal === 0 ? 0 : ((this.memoryTotal - this.memoryFree) / this.memoryTotal * 100).toFixed(0) |
|||
|
|||
const axisLineHandler = (value) => { |
|||
const ratio = Number(value / 100) |
|||
if (ratio <= 0.7) { |
|||
return [ |
|||
[ratio, '#56BC91'], // 进度色 |
|||
[1, 'rgba(216, 216, 216, 1)'] // 背景色 |
|||
] |
|||
} else if (ratio <= 0.9) { |
|||
return [ |
|||
[ratio, '#FF973E'], // 进度色 |
|||
[1, 'rgba(216, 216, 216, 1)'] // 背景色 |
|||
] |
|||
} else if (ratio <= 1) { |
|||
return [ |
|||
[ratio, '#fd666d'], // 进度色 |
|||
[1, 'rgba(216, 216, 216, 1)'] // 背景色 |
|||
] |
|||
} |
|||
} |
|||
|
|||
const itemStyleHandler = (value) => { |
|||
if (value <= 70) { |
|||
return `#56BC91` |
|||
} else if (value <= 90) { |
|||
return `#FF973E` |
|||
} else if (value <= 100) { |
|||
return `#fd666d` |
|||
} |
|||
return '' |
|||
} |
|||
|
|||
// const dataNameHandler = (value) => { |
|||
// if (value <= 60) { |
|||
// return value + '°C' |
|||
// } else if (value <= 80) { |
|||
// return value + '°C' |
|||
// } else if (value <= 100) { |
|||
// return value + '°C' |
|||
// } |
|||
// return '' |
|||
// } |
|||
|
|||
const option = { |
|||
series: [ |
|||
{ |
|||
type: 'gauge', |
|||
center: ['40%', '38%'], |
|||
radius: 60, |
|||
startAngle: 200, |
|||
endAngle: -20, |
|||
min: 0, |
|||
max: 100, |
|||
splitNumber: 10, |
|||
itemStyle: { |
|||
color: itemStyleHandler(dataValue) |
|||
}, |
|||
progress: { |
|||
show: true, |
|||
width: 20 |
|||
}, |
|||
pointer: { |
|||
show: false |
|||
}, |
|||
axisLine: { |
|||
lineStyle: { |
|||
width: 14, |
|||
color: axisLineHandler(dataValue) |
|||
} |
|||
}, |
|||
axisTick: { |
|||
show: false, |
|||
distance: -35, |
|||
splitNumber: 5, |
|||
lineStyle: { |
|||
width: 2, |
|||
color: 'auto' |
|||
} |
|||
}, |
|||
splitLine: { |
|||
show: false, |
|||
distance: -42, |
|||
length: 14, |
|||
lineStyle: { |
|||
width: 3, |
|||
color: 'auto' |
|||
} |
|||
}, |
|||
axisLabel: { |
|||
show: false, |
|||
distance: -40, |
|||
color: 'inherit', |
|||
fontSize: 14 |
|||
}, |
|||
anchor: { |
|||
show: false |
|||
}, |
|||
title: { |
|||
show: true, |
|||
offsetCenter: [0, '50%'], |
|||
fontSize: 14, |
|||
color: '#000' |
|||
}, |
|||
detail: { |
|||
valueAnimation: true, |
|||
width: '60%', |
|||
lineHeight: 40, |
|||
borderRadius: 8, |
|||
offsetCenter: [0, '0'], |
|||
fontSize: 26, |
|||
fontWeight: 'bolder', |
|||
formatter: '{value} %', |
|||
color: 'auto' |
|||
}, |
|||
data: [ |
|||
{ |
|||
value: dataValue, |
|||
name: ((this.memoryTotal - this.memoryFree) / 1024).toFixed(2) + 'G' + ' / ' + (this.memoryTotal / 1024).toFixed(0) + 'G' |
|||
} |
|||
] |
|||
}, |
|||
// 最外侧 |
|||
{ |
|||
type: 'gauge', |
|||
radius: 66, // 半径 |
|||
center: ['40%', '38%'], // 位置 |
|||
min: 0, |
|||
max: 100, |
|||
startAngle: 200, |
|||
endAngle: -20, |
|||
axisLine: { |
|||
show: false, |
|||
lineStyle: { |
|||
width: 1, |
|||
color: '#999' |
|||
} |
|||
}, |
|||
axisTick: { |
|||
show: true, |
|||
splitNumber: 8, |
|||
length: 2, |
|||
lineStyle: { |
|||
width: 1, |
|||
color: '#999' |
|||
} |
|||
}, |
|||
splitLine: { |
|||
show: false |
|||
}, |
|||
axisLabel: { |
|||
show: false |
|||
}, |
|||
pointer: { |
|||
show: false |
|||
}, |
|||
detail: { |
|||
show: false |
|||
} |
|||
} |
|||
] |
|||
} |
|||
|
|||
if (option) { |
|||
myChart.setOption(option) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
</style> |
@ -0,0 +1,219 @@ |
|||
<template> |
|||
<div id="mainUse" :style="{height:height,width:width}" /> |
|||
</template> |
|||
|
|||
<script> |
|||
import * as echarts from 'echarts' |
|||
import resize from '@/views/dashboard/mixins/resize' |
|||
|
|||
export default { |
|||
name: 'EchartsComponent', |
|||
mixins: [resize], |
|||
props: { |
|||
utilization: { |
|||
type: Number, |
|||
require: true, |
|||
default: function() { |
|||
return 0 |
|||
} |
|||
}, |
|||
width: { |
|||
type: String, |
|||
default: '50%' |
|||
}, |
|||
height: { |
|||
type: String, |
|||
default: '100%' |
|||
} |
|||
}, |
|||
watch: { |
|||
'utilization': { |
|||
handler(val) { |
|||
setTimeout(() => { |
|||
this.initChart() |
|||
}, 100) |
|||
}, |
|||
immediate: true, |
|||
deep: true |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.initChart() |
|||
// window.addEventListener('resize', this.__resizeHandler) |
|||
}, |
|||
methods: { |
|||
initChart() { |
|||
const chartDom = document.getElementById('mainUse') |
|||
const myChart = echarts.init(chartDom) |
|||
|
|||
const axisLineHandler = (value) => { |
|||
const ratio = Number(value / 100) |
|||
if (ratio <= 0.7) { |
|||
return [ |
|||
[ratio, '#56BC91'], // 进度色 |
|||
[1, 'rgba(216, 216, 216, 1)'] // 背景色 |
|||
] |
|||
} else if (ratio <= 0.9) { |
|||
return [ |
|||
[ratio, '#FF973E'], // 进度色 |
|||
[1, 'rgba(216, 216, 216, 1)'] // 背景色 |
|||
] |
|||
} else if (ratio <= 1) { |
|||
return [ |
|||
[ratio, '#fd666d'], // 进度色 |
|||
[1, 'rgba(216, 216, 216, 1)'] // 背景色 |
|||
] |
|||
} |
|||
} |
|||
|
|||
const itemStyleHandler = (value) => { |
|||
if (value <= 70) { |
|||
return `#56BC91` |
|||
} else if (value <= 90) { |
|||
return `#FF973E` |
|||
} else if (value <= 100) { |
|||
return `#fd666d` |
|||
} |
|||
return '' |
|||
} |
|||
|
|||
// const dataNameHandler = (value) => { |
|||
// if (value <= 60) { |
|||
// return value + '°C' |
|||
// } else if (value <= 80) { |
|||
// return value + '°C' |
|||
// } else if (value <= 100) { |
|||
// return value + '°C' |
|||
// } |
|||
// return '' |
|||
// } |
|||
|
|||
const option = { |
|||
series: [ |
|||
{ |
|||
type: 'gauge', |
|||
center: ['40%', '38%'], |
|||
radius: 120, |
|||
startAngle: 200, |
|||
endAngle: -20, |
|||
min: 0, |
|||
max: 100, |
|||
splitNumber: 10, |
|||
itemStyle: { |
|||
color: itemStyleHandler(this.utilization) |
|||
}, |
|||
progress: { |
|||
show: true, |
|||
width: 20 |
|||
}, |
|||
pointer: { |
|||
show: false |
|||
}, |
|||
axisLine: { |
|||
lineStyle: { |
|||
width: 26, |
|||
color: axisLineHandler(this.utilization) |
|||
} |
|||
}, |
|||
axisTick: { |
|||
show: false, |
|||
distance: -35, |
|||
splitNumber: 5, |
|||
lineStyle: { |
|||
width: 2, |
|||
color: 'auto' |
|||
} |
|||
}, |
|||
splitLine: { |
|||
show: false, |
|||
distance: -42, |
|||
length: 14, |
|||
lineStyle: { |
|||
width: 3, |
|||
color: 'auto' |
|||
} |
|||
}, |
|||
axisLabel: { |
|||
show: false, |
|||
distance: -40, |
|||
color: 'inherit', |
|||
fontSize: 14 |
|||
}, |
|||
anchor: { |
|||
show: false |
|||
}, |
|||
title: { |
|||
show: true, |
|||
offsetCenter: [0, '40%'], |
|||
fontSize: 18, |
|||
color: '#000' |
|||
}, |
|||
detail: { |
|||
valueAnimation: true, |
|||
width: '60%', |
|||
lineHeight: 40, |
|||
borderRadius: 8, |
|||
offsetCenter: [0, '0'], |
|||
fontSize: 40, |
|||
fontWeight: 'bolder', |
|||
formatter: '{value} %', |
|||
color: 'auto' |
|||
}, |
|||
data: [ |
|||
{ |
|||
value: this.utilization, |
|||
name: '占用率' |
|||
} |
|||
] |
|||
}, |
|||
// 最外侧 |
|||
{ |
|||
type: 'gauge', |
|||
radius: 130, // 半径 |
|||
center: ['40%', '38%'], // 位置 |
|||
min: 0, |
|||
max: 100, |
|||
startAngle: 200, |
|||
endAngle: -20, |
|||
axisLine: { |
|||
show: false, |
|||
lineStyle: { |
|||
width: 1, |
|||
color: '#999' |
|||
} |
|||
}, |
|||
axisTick: { |
|||
show: true, |
|||
splitNumber: 8, |
|||
length: 2, |
|||
lineStyle: { |
|||
width: 1, |
|||
color: '#999' |
|||
} |
|||
}, |
|||
splitLine: { |
|||
show: false |
|||
}, |
|||
axisLabel: { |
|||
show: false |
|||
}, |
|||
pointer: { |
|||
show: false |
|||
}, |
|||
detail: { |
|||
show: false |
|||
} |
|||
} |
|||
] |
|||
} |
|||
|
|||
if (option) { |
|||
myChart.setOption(option) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
</style> |
@ -1,275 +0,0 @@ |
|||
<template> |
|||
<div id="main4" :style="{height:height}" /> |
|||
</template> |
|||
|
|||
<script> |
|||
import echarts from 'echarts' |
|||
require('echarts/theme/macarons') |
|||
import resize from '@/views/dashboard/mixins/resize' |
|||
// const gaugeData = [ |
|||
// { |
|||
// value: 20, |
|||
// name: 'Perfect', |
|||
// title: { |
|||
// offsetCenter: ['0%', '-30%'] |
|||
// }, |
|||
// detail: { |
|||
// valueAnimation: true, |
|||
// offsetCenter: ['0%', '-20%'] |
|||
// } |
|||
// }, |
|||
// { |
|||
// value: 40, |
|||
// name: 'Good', |
|||
// title: { |
|||
// offsetCenter: ['0%', '0%'] |
|||
// }, |
|||
// detail: { |
|||
// valueAnimation: true, |
|||
// offsetCenter: ['0%', '10%'] |
|||
// } |
|||
// }, |
|||
// { |
|||
// value: 60, |
|||
// name: 'Commonly', |
|||
// title: { |
|||
// offsetCenter: ['0%', '30%'] |
|||
// }, |
|||
// detail: { |
|||
// valueAnimation: true, |
|||
// offsetCenter: ['0%', '40%'] |
|||
// } |
|||
// } |
|||
// ] |
|||
// var ROOT_PATH = 'https://echarts.apache.org/examples/data/asset/img/custom-gauge-panel.png' |
|||
// var _panelImageURL = ROOT_PATH + '/data/asset/img/custom-gauge-panel.png' |
|||
// var _animationDuration = 1000 |
|||
// var _animationDurationUpdate = 1000 |
|||
// var _animationEasingUpdate = 'quarticInOut' |
|||
// var _valOnRadianMax = 80 |
|||
// var _outerRadius = 80 |
|||
// var _innerRadius = 50 |
|||
// var _pointerInnerRadius = 50 |
|||
// var _insidePanelRadius = 30 |
|||
|
|||
// var _currentDataIndex = 0 |
|||
export default { |
|||
name: 'AcrossEcharts', |
|||
mixins: [resize], |
|||
props: { |
|||
addArcivesData: { |
|||
type: Object, |
|||
require: true, |
|||
default: function() { |
|||
return {} |
|||
} |
|||
}, |
|||
width: { |
|||
type: String, |
|||
default: '100%' |
|||
}, |
|||
height: { |
|||
type: String, |
|||
default: '100%' |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
chart: null, |
|||
panelImageURL: 'https://echarts.apache.org/examples/data/asset/img/custom-gauge-panel.png', |
|||
animationDuration: 1000, |
|||
animationDurationUpdate: 1000, |
|||
animationEasingUpdate: 'quarticInOut', |
|||
valOnRadianMax: 200, |
|||
outerRadius: 200, |
|||
innerRadius: 170, |
|||
pointerInnerRadius: 40, |
|||
insidePanelRadius: 140 |
|||
} |
|||
}, |
|||
watch: { |
|||
// 'addArcivesData': { |
|||
// handler(val) { |
|||
// setTimeout(() => { |
|||
// this.drawChart() |
|||
// }, 100) |
|||
// }, |
|||
// immediate: true, |
|||
// deep: true |
|||
// } |
|||
}, |
|||
mounted() { |
|||
this.drawChart() |
|||
window.addEventListener('resize', this.__resizeHandler) |
|||
}, |
|||
methods: { |
|||
renderItem(params, api) { |
|||
var valOnRadian = api.value(1) |
|||
var coords = api.coord([api.value(0), valOnRadian]) |
|||
var polarEndRadian = coords[3] |
|||
var imageStyle = { |
|||
image: this.panelImageURL, |
|||
x: params.coordSys.cx - this.outerRadius, |
|||
y: params.coordSys.cy - this.outerRadius, |
|||
width: this.outerRadius * 2, |
|||
height: this.outerRadius * 2 |
|||
} |
|||
return { |
|||
type: 'group', |
|||
children: [ |
|||
{ |
|||
type: 'image', |
|||
style: imageStyle, |
|||
clipPath: { |
|||
type: 'sector', |
|||
shape: { |
|||
cx: params.coordSys.cx, |
|||
cy: params.coordSys.cy, |
|||
r: this.uterRadius, |
|||
r0: this.innerRadius, |
|||
startAngle: 0, |
|||
endAngle: -polarEndRadian, |
|||
transition: 'endAngle', |
|||
enterFrom: { endAngle: 0 } |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
type: 'image', |
|||
style: imageStyle, |
|||
clipPath: { |
|||
type: 'polygon', |
|||
shape: { |
|||
points: this.makePionterPoints(params, polarEndRadian) |
|||
}, |
|||
extra: { |
|||
polarEndRadian: polarEndRadian, |
|||
transition: 'polarEndRadian', |
|||
enterFrom: { polarEndRadian: 0 } |
|||
}, |
|||
during: function(apiDuring) { |
|||
apiDuring.setShape( |
|||
'points', |
|||
this.makePionterPoints(params, apiDuring.getExtra('polarEndRadian')) |
|||
) |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
type: 'circle', |
|||
shape: { |
|||
cx: params.coordSys.cx, |
|||
cy: params.coordSys.cy, |
|||
r: this.insidePanelRadius |
|||
}, |
|||
style: { |
|||
fill: '#fff', |
|||
shadowBlur: 25, |
|||
shadowOffsetX: 0, |
|||
shadowOffsetY: 0, |
|||
shadowColor: 'rgba(76,107,167,0.4)' |
|||
} |
|||
}, |
|||
{ |
|||
type: 'text', |
|||
extra: { |
|||
valOnRadian: valOnRadian, |
|||
transition: 'valOnRadian', |
|||
enterFrom: { valOnRadian: 0 } |
|||
}, |
|||
style: { |
|||
text: this.makeText(valOnRadian), |
|||
fontSize: 30, |
|||
fontWeight: 700, |
|||
x: params.coordSys.cx, |
|||
y: params.coordSys.cy, |
|||
fill: 'rgb(0,50,190)', |
|||
align: 'center', |
|||
verticalAlign: 'middle', |
|||
enterFrom: { opacity: 0 } |
|||
}, |
|||
during: function(apiDuring) { |
|||
apiDuring.setStyle( |
|||
'text', |
|||
this.makeText(apiDuring.getExtra('valOnRadian')) |
|||
) |
|||
} |
|||
} |
|||
] |
|||
} |
|||
}, |
|||
makeText(valOnRadian) { |
|||
// Validate additive animation calc. |
|||
if (valOnRadian < -10) { |
|||
alert('illegal during val: ' + valOnRadian) |
|||
} |
|||
return ((valOnRadian / this.valOnRadianMax) * 100).toFixed(0) + '%' |
|||
}, |
|||
convertToPolarPoint(renderItemParams, radius, radian) { |
|||
return [ |
|||
Math.cos(radian) * radius + renderItemParams.coordSys.cx, |
|||
-Math.sin(radian) * radius + renderItemParams.coordSys.cy |
|||
] |
|||
}, |
|||
makePionterPoints(renderItemParams, polarEndRadian) { |
|||
return [ |
|||
this.convertToPolarPoint(renderItemParams, this.outerRadius, polarEndRadian), |
|||
this.convertToPolarPoint( |
|||
renderItemParams, |
|||
this.outerRadius, |
|||
polarEndRadian + Math.PI * 0.03 |
|||
), |
|||
this.convertToPolarPoint(renderItemParams, this.pointerInnerRadius, polarEndRadian) |
|||
] |
|||
}, |
|||
drawChart() { |
|||
const chartDom = document.getElementById('main4') |
|||
this.chart = echarts.init(chartDom) |
|||
let option = null |
|||
option = { |
|||
animationEasing: this.animationEasingUpdate, |
|||
animationDuration: this.animationDuration, |
|||
animationDurationUpdate: this.animationDurationUpdate, |
|||
animationEasingUpdate: this.animationEasingUpdate, |
|||
dataset: { |
|||
source: [[1, 156]] |
|||
}, |
|||
tooltip: {}, |
|||
angleAxis: { |
|||
type: 'value', |
|||
startAngle: 0, |
|||
show: false, |
|||
min: 0, |
|||
max: this.valOnRadianMax |
|||
}, |
|||
radiusAxis: { |
|||
type: 'value', |
|||
show: false |
|||
}, |
|||
polar: {}, |
|||
series: [ |
|||
{ |
|||
type: 'custom', |
|||
coordinateSystem: 'polar', |
|||
renderItem: this.renderItem |
|||
} |
|||
] |
|||
} |
|||
var _this = this |
|||
setInterval(function() { |
|||
var nextSource = [[1, Math.round(Math.random() * this.valOnRadianMax)]] |
|||
_this.chart.setOption({ |
|||
dataset: { |
|||
source: nextSource |
|||
} |
|||
}) |
|||
}, 3000) |
|||
option && this.chart.setOption(option) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
|
|||
</style> |
@ -0,0 +1,302 @@ |
|||
<template> |
|||
<div class="service-all"> |
|||
<div v-if="serviceTop" class="service-top-text" :class="!serviceTop ? 'false-active' : 'true-active'">AI处理终端</div> |
|||
<!-- <i class="iconfont icon-zhongduanjiankong" />终端连接正常 --> |
|||
<ul v-if="serviceTop" class="service-list"> |
|||
<li v-for="(item, index) in serviceItems" :key="index"> |
|||
<p :class="index <= currentIndex && item.status === 'running'? 'true-active' : 'false-active' "> |
|||
{{ item.serviceName }} |
|||
</p> |
|||
<!-- {{ item.serviceName }} --> |
|||
<!-- <i v-if="index <= currentIndex && item.status === 'running'" class="iconfont icon-shi" /> |
|||
<i v-else-if="index <= currentIndex" class="iconfont icon-cuowu1" /> --> |
|||
</li> |
|||
</ul> |
|||
<div v-if="servicesDisplayed && isAllServicesRunning" class="service-bottom-text" :class="{ 'fade-in': servicesDisplayed && isAllServicesRunning }" style="color: rgb(18, 196, 122);">所有服务均正常运行,请放心使用</div> |
|||
<div v-else-if="servicesDisplayed && !isAllServicesRunning" class="service-bottom-text" :class="{ 'fade-in': servicesDisplayed &&!isAllServicesRunning }" style="color: #ED4A41;">请尽快联系系统维护人员进行恢复</div> |
|||
<div v-if="!serviceTop" class="tip-service" :class="{ 'fade-in': !serviceTop }"> |
|||
<i class="iconfont icon-lianjieduankai" /> |
|||
<div class="tip-service-content"> |
|||
<p>AI处理终端连接超时,请检查配置是否正确或终端是否运行成功!</p> |
|||
<p>请尽快联系系统维护人员进行恢复</p> |
|||
</div> |
|||
</div> |
|||
</div></template> |
|||
|
|||
<script> |
|||
import crudStockTask, { FetchAITerminalStatusQuery } from '@/api/stockTask/index' |
|||
import { mapGetters } from 'vuex' |
|||
export default { |
|||
name: 'ServeTerminal', |
|||
components: { }, |
|||
props: { |
|||
}, |
|||
data() { |
|||
return { |
|||
service: { |
|||
'service_imgCamera': { 'last_heartbeat': 1736496962.2368362, 'status': '' }, |
|||
'service_imgProcess': { 'last_heartbeat': 1736496960.8598323, 'status': '' }, |
|||
'service_imgYolo': { 'last_heartbeat': 1736496961.953832, 'status': '' }, |
|||
'service_imgOcr': { 'last_heartbeat': 1736496961.6238313, 'status': '' }, |
|||
'service_imgResult': { 'last_heartbeat': 1736496963.4378026, 'status': '' } |
|||
}, |
|||
serviceItems: [], |
|||
currentIndex: -1, |
|||
timer: null, |
|||
servicesDisplayed: false, |
|||
serviceTop: false |
|||
} |
|||
}, |
|||
computed: { |
|||
...mapGetters([ |
|||
'baseApi' |
|||
]), |
|||
isAllServicesRunning() { |
|||
return Object.values(this.service).every(service => service.status === 'running') |
|||
} |
|||
}, |
|||
mounted() { |
|||
}, |
|||
methods: { |
|||
initData() { |
|||
crudStockTask.FetchInitSetting().then(res => { |
|||
if (res) { |
|||
this.handleService(res.ip) |
|||
} |
|||
}).catch(() => { |
|||
}) |
|||
}, |
|||
handleService(ip) { |
|||
this.servicesDisplayed = false |
|||
FetchAITerminalStatusQuery({ 'ip': ip }).then(res => { |
|||
// { |
|||
// "service_imgCamera":{"last_heartbeat":1736496962.2368362,"status":"running"}, |
|||
// "service_imgProcess":{"last_heartbeat":1736496960.8598323,"status":"running"}, |
|||
// "service_imgYolo":{"last_heartbeat":1736496961.953832,"status":"running"} |
|||
// "service_imgOcr":{"last_heartbeat":1736496961.6238313,"status":"running"}, |
|||
// "service_imgResult":{"last_heartbeat":1736496963.4378026,"status":"running"}, |
|||
// } |
|||
if (res) { |
|||
this.serviceTop = true |
|||
this.service = JSON.parse(res) |
|||
this.serviceItems = [] |
|||
const keysOrder = ['service_imgCamera', 'service_imgProcess', 'service_imgYolo', 'service_imgOcr', 'service_imgResult'] |
|||
keysOrder.forEach(key => { |
|||
let serviceName = '' |
|||
switch (key) { |
|||
case 'service_imgCamera': |
|||
serviceName = '图像采集' |
|||
break |
|||
case 'service_imgProcess': |
|||
serviceName = '图像处理' |
|||
break |
|||
case 'service_imgYolo': |
|||
serviceName = '图像识别' |
|||
break |
|||
case 'service_imgOcr': |
|||
serviceName = '文字识别' |
|||
break |
|||
case 'service_imgResult': |
|||
serviceName = '同步服务' |
|||
break |
|||
} |
|||
this.serviceItems.push({ |
|||
serviceName: serviceName, |
|||
status: this.service[key].status |
|||
}) |
|||
}) |
|||
this.showServicesSequentially() |
|||
} else { |
|||
this.serviceTop = false |
|||
} |
|||
}).catch(() => { |
|||
}) |
|||
}, |
|||
showServicesSequentially() { |
|||
let index = 0 |
|||
const interval = 300 |
|||
this.timer = setInterval(() => { |
|||
this.currentIndex = index |
|||
index++ |
|||
if (index >= this.serviceItems.length) { |
|||
clearInterval(this.timer) |
|||
setTimeout(() => { |
|||
this.servicesDisplayed = true |
|||
}, 500) |
|||
} |
|||
}, interval) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.tip-service{ |
|||
display: flex; |
|||
justify-content: center; |
|||
color: #0C0E1E; |
|||
font-size: 16px; |
|||
line-height: 40px; |
|||
padding: 40px 0; |
|||
.iconfont{ |
|||
font-size: 30px; |
|||
margin-right: 10px; |
|||
color: #ED4A41; |
|||
} |
|||
p{ |
|||
&:first-child{ |
|||
color: #ED4A41; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.service-all{ |
|||
position: relative; |
|||
height: 230px; |
|||
color: #0C0E1E; |
|||
} |
|||
.service-top-text{ |
|||
position: relative; |
|||
font-size: 12px; |
|||
margin: 0 65px; |
|||
height: 72px; |
|||
text-align: center; |
|||
background: url('~@/assets/images/serve1.png') no-repeat center center; |
|||
background-size: 40px auto; |
|||
&.false-active{ |
|||
background: url('~@/assets/images/serve1-1.png') no-repeat center center; |
|||
background-size: 40px auto; |
|||
} |
|||
&.true-active{ |
|||
&::before{ |
|||
content: ""; |
|||
position: absolute; |
|||
left: 50%; |
|||
bottom: -10px; |
|||
width: 1px; |
|||
height: 16px; |
|||
background-color:#9098a4; |
|||
margin-left: -1px; |
|||
} |
|||
&::after{ |
|||
content: ""; |
|||
position: absolute; |
|||
left: 0; |
|||
bottom: -10px; |
|||
width: 100%; |
|||
height: 1px; |
|||
background-color: #9098a4; |
|||
margin-left: -1px; |
|||
} |
|||
} |
|||
} |
|||
.service-list{ |
|||
display: flex; |
|||
justify-content: space-between; |
|||
padding: 30px 40px 10px 40px; |
|||
li{ |
|||
position: relative; |
|||
&::before{ |
|||
content: ""; |
|||
position: absolute; |
|||
left: 50%; |
|||
top: -20px; |
|||
width: 1px; |
|||
height: 10px; |
|||
background-color: #9098a4; |
|||
margin-left: -1px; |
|||
} |
|||
p{ |
|||
width: 50px; |
|||
height: 70px; |
|||
font-size: 12px; |
|||
} |
|||
&:nth-child(1){ |
|||
p{ |
|||
&.false-active{ |
|||
background: url('~@/assets/images/ter1-1.png') no-repeat center center; |
|||
background-size: 36px auto; |
|||
} |
|||
&.true-active{ |
|||
background: url('~@/assets/images/ter1.png') no-repeat center center; |
|||
background-size: 36px auto; |
|||
} |
|||
} |
|||
} |
|||
&:nth-child(2){ |
|||
p{ |
|||
&.false-active{ |
|||
background: url('~@/assets/images/ter2-1.png') no-repeat center center; |
|||
background-size: 32px auto; |
|||
} |
|||
&.true-active{ |
|||
background: url('~@/assets/images/ter2.png') no-repeat center center; |
|||
background-size: 32px auto; |
|||
} |
|||
} |
|||
} |
|||
&:nth-child(3){ |
|||
p{ |
|||
&.false-active{ |
|||
background: url('~@/assets/images/ter3-1.png') no-repeat center center; |
|||
background-size: 36px auto; |
|||
} |
|||
&.true-active{ |
|||
background: url('~@/assets/images/ter3.png') no-repeat center center; |
|||
background-size: 36px auto; |
|||
} |
|||
} |
|||
} |
|||
&:nth-child(4){ |
|||
p{ |
|||
&.false-active{ |
|||
background: url('~@/assets/images/ter4-1.png') no-repeat center center; |
|||
background-size: 36px auto; |
|||
} |
|||
&.true-active{ |
|||
background: url('~@/assets/images/ter4.png') no-repeat center center; |
|||
background-size: 36px auto; |
|||
} |
|||
} |
|||
} |
|||
&:nth-child(5){ |
|||
p{ |
|||
&.false-active{ |
|||
background: url('~@/assets/images/ter5-1.png') no-repeat center center; |
|||
background-size: 36px auto; |
|||
} |
|||
&.true-active{ |
|||
background: url('~@/assets/images/ter5.png') no-repeat center center; |
|||
background-size: 36px auto; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.service-bottom-text{ |
|||
font-size: 12px; |
|||
text-align: center; |
|||
} |
|||
.fade-enter-active, |
|||
.fade-leave-active { |
|||
transition: all 0.5s ease; |
|||
} |
|||
.fade-enter, |
|||
.fade-leave-to { |
|||
opacity: 0; |
|||
transform: translateY(20px); |
|||
} |
|||
.fade-in { |
|||
animation: fadeIn 0.5s ease; |
|||
} |
|||
@keyframes fadeIn { |
|||
from { |
|||
opacity: 0; |
|||
transform: translateY(20px); |
|||
} |
|||
to { |
|||
opacity: 1; |
|||
transform: translateY(0); |
|||
} |
|||
} |
|||
</style> |