图书馆综合管理系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

302 lines
8.8 KiB

<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>