microFactory/src/views/screen/devItem/index.vue
2025-02-27 09:14:31 +08:00

458 lines
17 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="container">
<div class="header">
<div class="title">微工厂设备详情</div>
</div>
<div class="content">
<div class="left-plane">
<div class="lt-plane">
<div class="ltl-plane">
<Card class="ltl-item1" title="设备详情">
<div class="ltl-content">
<div class="ltl-box">
<div class="ltl-item-box">
<div class="label">名称</div>
<div class="value">{{ deviceInfo.name }}</div>
</div>
</div>
<div class="ltl-box">
<div class="ltl-item-box">
<div class="label">编号</div>
<div class="value">{{ deviceInfo.code }}</div>
</div>
</div>
<div class="ltl-box">
<div class="ltl-item-box">
<div class="label">负责人</div>
<div class="value">{{ deviceInfo.director }}</div>
</div>
</div>
<div class="ltl-box">
<div class="ltl-item-box">
<div class="label">所在位置</div>
<div class="value">{{ deviceInfo.deviceLocation }}</div>
</div>
</div>
</div>
</Card>
<Card class="ltl-item2" title="设备利用率">
<div style="width: 100%;height: 100%;display: flex;flex-direction: column;justify-content: space-around;align-items: center;">
<Progress :mdoelValue1="item" v-for="item in deviceRateChartData"></Progress>
</div>
</Card>
</div>
<div class="ltr-plane">
<div class="tip-type">
<div class="tip-type-item">
<svg-icon icon-class="run" class="el-input__icon" style="width: 26px;height: 26px;" />
<div class="tip-type-item-text">工作</div>
</div>
<div class="tip-type-item">
<svg-icon icon-class="wait" class="el-input__icon" style="width: 26px;height: 26px;" />
<div class="tip-type-item-text">待机</div>
</div>
<div class="tip-type-item">
<svg-icon icon-class="stop" class="el-input__icon" style="width: 26px;height: 26px;" />
<div class="tip-type-item-text">停机</div>
</div>
<div class="tip-type-item">
<svg-icon icon-class="repair" class="el-input__icon"
style="width: 26px;height: 26px;" />
<div class="tip-type-item-text">维修</div>
</div>
<div class="tip-type-item">
<svg-icon icon-class="alarm" class="el-input__icon" style="width: 26px;height: 26px;" />
<div class="tip-type-item-text">故障</div>
</div>
</div>
<div class="c-item c-top">
<div class="item-box">当前状态:
<svg-icon v-if="devStatus.state == 0" icon-class="stop"
class="el-input__icon input-icon" />
<svg-icon v-else-if="devStatus.state == 1" icon-class="wait"
class="el-input__icon input-icon" />
<svg-icon v-else-if="devStatus.state == 2" icon-class="run"
class="el-input__icon input-icon" />
<svg-icon v-else-if="devStatus.state == 4" icon-class="alarm"
class="el-input__icon input-icon" />
</div>
<div class="item-box">运行时长:{{ devStatus.runTime }}min</div>
</div>
<div class="c-item c-center">
<div class="item-box">停机时长:{{ devStatus.stopTime }}min</div>
<el-image :src="baseUrl + deviceInfo.file"
style="height: 100%;position: relative;top: -30px;" />
<div class="item-box">工作时长:{{ devStatus.workTime }}min</div>
</div>
<div class="c-item c-bottom">
<div class="item-box">故障时长:{{ devStatus.faultTime }}min</div>
<div class="item-box">待机时长:{{ devStatus.waitTime }}min</div>
</div>
</div>
</div>
<Card class="lb-plane" title="设备状态分析">
<StackBarChart :data="deviceStatusChartData"></StackBarChart>
</Card>
</div>
<div class="right-plane">
<Card class="right-item1" title="设备维修记录">
<el-table :data="repairData" v-if="repairData.length > 0" v-tableAutoScroll="{ delay: 15 }"
header-row-class-name="table_header" style="width: 100%;height: 100%;">
<el-table-column prop="devCode" label="编码" width="90" />
<el-table-column prop="name" label="设备名称" />
<el-table-column prop="runTime" label="报警内容" />
<el-table-column prop="person" label="负责人" />
<el-table-column prop="time" label="报警时间" />
</el-table>
<el-empty v-else description="暂无记录" />
</Card>
<Card class="right-item2" title="设备保养记录">
<el-table :data="remindData" v-if="remindData.length > 0" v-tableAutoScroll="{ delay: 15 }"
header-row-class-name="table_header" style="width: 100%;height: 100%;">
<el-table-column prop="devCode" label="编码" width="90" />
<el-table-column prop="name" label="设备名称" />
<el-table-column prop="runTime" label="保养内容" />
<el-table-column prop="person" label="负责人" />
<el-table-column prop="time" label="保养时间" />
</el-table>
<el-empty v-else description="暂无记录" />
</Card>
<Card class="right-item3" title="设备用电量分析">
<LineChart :data="deviceElectChartData"></LineChart>
</Card>
</div>
</div>
</div>
</template>
<script setup>
import 'element-plus/theme-chalk/dark/css-vars.css'
import { onMounted, ref } from 'vue';
import Card from './component/card.vue';
import StackBarChart from './component/stackBarChart.vue';
import Progress from './component/Progress.vue';
import LineChart from './component/lineChart.vue';
import { useRoute } from 'vue-router';
import { listDevice, deviceCheck, deviceRepair, deviceStatusById, deviceStatusChart,deviceRateChart,deviceElectChart } from '@/api/screen/micro'
const route = useRoute();
let id = ref(0)
const baseUrl = import.meta.env.VITE_APP_BASE_API;
let deviceInfo = ref({})
//获取设备列表
function getListDevice() {
listDevice(id.value).then(res => {
deviceInfo.value = res.data
})
}
let remindData = ref([])
//获取保养记录
const getDeviceCheck = async () => {
const res = await deviceCheck(id.value);
remindData.value = res.data;
}
let repairData = ref([])
//获取维修记录
const getDeviceRepair = async () => {
const res = await deviceRepair(id.value);
repairData.value = res.data;
}
let devStatus = ref({
"deviceCode": null,
"onlineTime": null,
"realTime": null,
"deviceId": null,
"workTime": null,
"runTime": null,
"waitTime": null,
"stopTime": null,
"faultTime": null,
"ts": null,
"state": null,
})
//单设备运行状态
const getDeviceStatus = async () => {
const res = await deviceStatusById(id.value);
devStatus.value = res.data;
}
let deviceStatusChartData = reactive({
xAxis: [],
series: []
})
//设备状态图表
const getDeviceStatusChart = async () => {
const res = await deviceStatusChart(id.value);
deviceStatusChartData.xAxis = res.data.dates;
deviceStatusChartData.series.push({
name: '工作',
data: res.data.work
})
deviceStatusChartData.series.push({
name: '待机',
data: res.data.wait
})
deviceStatusChartData.series.push({
name: '停机',
data: res.data.stop
})
deviceStatusChartData.series.push({
name: '故障',
data: res.data.fault
})
}
//设备利用率
let deviceRateChartData = ref([])
const getDeviceRateChart = async () => {
const res = await deviceRateChart(id.value);
deviceRateChartData.value = res.data;
}
//单设备用电量图表
let deviceElectChartData = reactive({
xAxis: [],
series: []
})
function getdeviceElectChart() {
deviceElectChart(id.value).then(res => {
deviceElectChartData.xAxis = res.data.dates;
deviceElectChartData.series = res.data.elects;
})
}
onMounted(() => {
id.value = route.params.id;
getDeviceCheck();
getDeviceRepair();
getListDevice()
getDeviceStatus()
getDeviceStatusChart()
getDeviceRateChart()
getdeviceElectChart()
});
</script>
<style lang="scss" scoped>
::v-deep(.table_header th) {
background-color: transparent !important;
color: #21dadb;
text-align: center;
}
.container {
width: 1920px;
height: 1080px;
position: relative;
// display: flex;
// justify-content: center;
align-items: center;
background-image: url('/src/assets/images/screen-bg.png');
background-repeat: no-repeat;
/* 如果你不想让背景平铺 */
background-size: cover;
/* 或者其他你需要的大小设置 */
background-position: center;
.header {
width: 100%;
height: 89px;
background-image: url('/src/assets/images/screen-header-bg1.png');
background-size: 100% 100%;
.title {
width: 100%;
height: 89px;
font-size: 36px;
color: #f9f8f4;
text-align: center;
line-height: 89px;
font-weight: 700;
}
}
.content {
width: 100%;
height: 975px;
display: flex;
justify-content: space-around;
align-items: center;
box-sizing: border-box;
padding: 20px 0;
.right-plane {
width: 488px;
height: 100%;
.right-item1 {
width: 100%;
height: 280px;
}
.right-item2 {
width: 100%;
height: 280px;
margin: 10px 0;
}
.right-item3 {
width: 100%;
height: 395px;
}
}
.left-plane {
width: 1400px;
height: 100%;
.lt-plane {
width: 100%;
height: 635px;
display: flex;
justify-content: space-between;
align-items: center;
.ltl-plane {
width: 488px;
height: 100%;
.ltl-item1 {
width: 100%;
height: 260px;
.ltl-content {
width: 100%;
height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
.ltl-box {
width: 48%;
height: 50%;
display: flex;
justify-content: flex-start;
align-items: center;
box-sizing: border-box;
.ltl-item-box {
height: 60px;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(2, 48, 87, 0.5);
border: #2A80B8 2px solid;
padding: 0 10px;
color: #f9f8f4;
font-size: 20px;
font-weight: 500;
text-align: center;
.label {
width: 50%;
text-wrap: nowrap;
text-align: left;
}
}
}
}
}
.ltl-item2 {
width: 100%;
height: 360px;
margin-top: 15px;
}
}
.ltr-plane {
position: relative;
width: 892px;
height: 100%;
background: url('./image/center-bg.png') no-repeat;
background-size: 38% auto;
background-position: 50% 70%;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
.tip-type {
position: absolute;
top: -15px;
left: 50%;
transform: translateX(-50%);
width: 260px;
height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 14px;
font-weight: 700;
.tip-type-item {
width: 33%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
}
.c-top,
.c-bottom {
width: 70%;
height: 150px;
}
.c-center {
width: 85%;
flex: 1;
}
.c-item {
display: flex;
justify-content: space-between;
align-items: center;
.item-box {
background-color: rgba(2, 48, 87, 0.5);
border: #2A80B8 2px solid;
padding: 15px;
color: #f9f8f4;
font-size: 22px;
font-weight: 500;
text-align: center;
}
}
}
}
.lb-plane {
width: 100%;
height: 340px;
}
}
}
}
</style>