microFactory/src/views/screen/devItem/index.vue

458 lines
17 KiB
Vue
Raw Normal View History

2025-02-25 09:06:35 +00:00
<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">
2025-02-27 01:14:31 +00:00
<div class="ltl-item-box">
<div class="label">名称</div>
<div class="value">{{ deviceInfo.name }}</div>
</div>
2025-02-25 09:06:35 +00:00
</div>
<div class="ltl-box">
2025-02-27 01:14:31 +00:00
<div class="ltl-item-box">
<div class="label">编号</div>
<div class="value">{{ deviceInfo.code }}</div>
</div>
2025-02-25 09:06:35 +00:00
</div>
<div class="ltl-box">
2025-02-27 01:14:31 +00:00
<div class="ltl-item-box">
<div class="label">负责人</div>
<div class="value">{{ deviceInfo.director }}</div>
</div>
2025-02-25 09:06:35 +00:00
</div>
<div class="ltl-box">
2025-02-27 01:14:31 +00:00
<div class="ltl-item-box">
<div class="label">所在位置</div>
<div class="value">{{ deviceInfo.deviceLocation }}</div>
</div>
2025-02-25 09:06:35 +00:00
</div>
</div>
</Card>
2025-02-27 01:14:31 +00:00
<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>
2025-02-25 09:06:35 +00:00
</div>
<div class="ltr-plane">
2025-02-27 01:14:31 +00:00
<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>
2025-02-25 09:06:35 +00:00
<div class="c-item c-top">
2025-02-27 01:14:31 +00:00
<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>
2025-02-25 09:06:35 +00:00
</div>
<div class="c-item c-center">
2025-02-27 01:14:31 +00:00
<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>
2025-02-25 09:06:35 +00:00
</div>
<div class="c-item c-bottom">
2025-02-27 01:14:31 +00:00
<div class="item-box">故障时长{{ devStatus.faultTime }}min</div>
<div class="item-box">待机时长{{ devStatus.waitTime }}min</div>
2025-02-25 09:06:35 +00:00
</div>
</div>
</div>
<Card class="lb-plane" title="设备状态分析">
2025-02-27 01:14:31 +00:00
<StackBarChart :data="deviceStatusChartData"></StackBarChart>
2025-02-25 09:06:35 +00:00
</Card>
</div>
<div class="right-plane">
2025-02-27 01:14:31 +00:00
<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>
2025-02-25 09:06:35 +00:00
2025-02-27 01:14:31 +00:00
<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>
2025-02-25 09:06:35 +00:00
2025-02-27 01:14:31 +00:00
<Card class="right-item3" title="设备用电量分析">
<LineChart :data="deviceElectChartData"></LineChart>
</Card>
2025-02-25 09:06:35 +00:00
</div>
</div>
</div>
</template>
<script setup>
2025-02-27 01:14:31 +00:00
import 'element-plus/theme-chalk/dark/css-vars.css'
import { onMounted, ref } from 'vue';
2025-02-25 09:06:35 +00:00
import Card from './component/card.vue';
import StackBarChart from './component/stackBarChart.vue';
2025-02-27 01:14:31 +00:00
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()
});
2025-02-25 09:06:35 +00:00
</script>
<style lang="scss" scoped>
2025-02-27 01:14:31 +00:00
::v-deep(.table_header th) {
background-color: transparent !important;
color: #21dadb;
text-align: center;
}
2025-02-25 09:06:35 +00:00
.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;
2025-02-27 01:14:31 +00:00
2025-02-25 09:06:35 +00:00
.label {
width: 50%;
text-wrap: nowrap;
text-align: left;
}
}
}
}
}
.ltl-item2 {
width: 100%;
height: 360px;
margin-top: 15px;
}
}
.ltr-plane {
2025-02-27 01:14:31 +00:00
position: relative;
2025-02-25 09:06:35 +00:00
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;
2025-02-27 01:14:31 +00:00
.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;
}
}
2025-02-25 09:06:35 +00:00
.c-top,
.c-bottom {
width: 70%;
2025-02-27 01:14:31 +00:00
height: 150px;
2025-02-25 09:06:35 +00:00
}
.c-center {
width: 85%;
2025-02-27 01:14:31 +00:00
flex: 1;
2025-02-25 09:06:35 +00:00
}
.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>