cepianyi-ui/src/views/equipment/equipmentDetails.vue
2025-06-05 16:33:14 +08:00

990 lines
28 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="equipment-container">
<div class="data-overview">
<div class="data-left">
<div class="equipment-name">{{ deviceInfo?.deviceName }}{{deviceInfo?.deviceCode}}</div>
<el-button type="info" size="small" v-if="deviceShowStatus">{{deviceShowStatus}}</el-button>
<!-- <div style="margin-left:16px;color:#606266">时间显示</div>-->
</div>
<div class="action-buttons">
<div class="button-group">
<!-- <el-button-->
<!-- type="primary"-->
<!-- link-->
<!-- @click="handleShowImage()"-->
<!-- >-->
<!-- {{proxy.$t('equipment.imagePage')}}-->
<!-- </el-button>-->
<el-button
:type="mode === 'fast' ? 'primary' : ''"
@click="handleModeChange()"
>
<el-icon><Timer /></el-icon>
{{modeTypeMap[deviceMode]}}
</el-button>
<el-button
plain
:type="xRayStatus ? 'danger' : 'success'"
@click="handleXRayToggle"
>
X{{proxy.$t('equipment.Ray')}}{{ xRayStatus ? proxy.$t('common.open') : proxy.$t('common.close') }}
</el-button>
<el-button
type="primary"
plain
@click="handleGenerateReport"
>
{{proxy.$t('equipment.reporting')}}
</el-button>
<el-button
type="success"
plain
@click="handleDeviceShare"
>
{{proxy.$t('equipment.deviceShare')}}
</el-button>
</div>
</div>
</div>
<div class="chart-container">
<div class="chart-box">
<el-tabs
v-model="activeName"
type="card"
class="demo-tabs"
@tab-click="handleClick"
>
<el-tab-pane label="数据组1" name="first">
<div class="card-container">
<div class="card-list">
<div class="eccentricity-card" v-for="(item, index) in cardList" :key="index">
<div class="card-header">
<span class="title">{{item.title}}</span>
<el-icon class="close-icon" @click="deleteCard(index)"><Close /></el-icon>
</div>
<div class="card-content">
<div class="card-text">
<div>
<div class="difference">
<span class="plus">收缩率</span>
<span class="label">9%</span>
</div>
<div class="difference">
<span class="plus">+</span>
<span class="label">公差</span>
</div>
</div>
<div class="value">
21.15<span class="unit">%</span>
</div>
</div>
<div class="tolerance-section">
<el-button
type="primary"
plain
class="switch-btn left"
@click="handlePrevious"
>
<el-icon><ArrowLeft /></el-icon>
</el-button>
<div class="tolerance-text">
偏心度公差 {{ toleranceList[currentIndex] }}
</div>
<el-button
type="primary"
plain
class="switch-btn right"
@click="handleNext"
>
<el-icon><ArrowRight /></el-icon>
</el-button>
</div>
</div>
</div>
<div class="eccentricity-card" @click="openDialog">
<div style="display: flex;justify-content: center;align-content: center;cursor: pointer">
<el-icon style="font-size: 50px;color:red"><Plus></Plus></el-icon>
</div>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="数据组2" name="second">数据组2</el-tab-pane>
<el-tab-pane label="数据组3" name="third">数据组3</el-tab-pane>
</el-tabs>
</div>
</div>
<div class="chart-container">
<div class="chart-box">
<el-tabs
v-model="activeTwoName"
type="card"
class="demo-tabs"
@tab-click="handleClick"
>
<el-tab-pane :label="proxy.$t('equipment.sketch')" name="first">
<div class="detection-section">
<el-radio-group v-model="selectedLayer" class="layer-select">
<el-radio label="outer">外屏蔽层</el-radio>
<el-radio label="middle">绝缘层</el-radio>
<el-radio label="inner">内屏蔽层</el-radio>
</el-radio-group>
<!-- <CircleDetectionChart-->
<!-- :inner-data="innerLayerData"-->
<!-- :middle-data="middleLayerData"-->
<!-- :outer-data="outerLayerData"-->
<!-- />-->
<CircleDetectionChart :selected-layer="selectedLayer" />
<!-- <CircleDetectionChart :eccentricity="0.08" :thickness="20" />-->
<div class="history-content">
<div>左边指南针</div>
<div class="history-right">
<div>
<el-button v-if="showHistory" type="primary" @click="showHistoryDialog">选择历史数据</el-button>
<el-switch
v-model="showHistory"
size="large"
style="margin-left: 6px"
:inactive-text="proxy.$t('equipment.historyData')"
/>
</div>
<div class="scanItem">扫描时间2025/01/07 04:34:8</div>
<div class="scanItem">2025-01-07_04_30_34_866_direction_1_device2.json</div>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane :label="proxy.$t('equipment.deviceInfo')" name="second">
<div class="device-status">
<DeviceStatus :status-data="deviceStatus" />
<!-- <DeviceSetting v-if="showBtn" @update="handleSettingUpdate" />-->
</div>
</el-tab-pane>
</el-tabs>
<!-- <div class="btn" v-if="activeTwoName === 'second'">-->
<!-- <el-button v-if="!showBtn" type="primary" @click="paramsHandle">{{proxy.$t('equipment.paramsSetting')}}</el-button>-->
<!-- <el-button v-if="showBtn" type="primary" @click="paramsHandle">{{proxy.$t('button.return')}}</el-button>-->
<!-- </div>-->
</div>
</div>
<div class="chart-container" style="margin-top: 14px">
<div class="chart-box">
<el-tabs
v-model="activeThreeName"
type="card"
class="demo-tabs"
@tab-click="handleClick"
>
<el-tab-pane :label="proxy.$t('equipment.deviceTemperature')" name="first">
<TemperatureChart :chart-data="temperatureData"></TemperatureChart>
</el-tab-pane>
<el-tab-pane :label="proxy.$t('equipment.warningInfo')" name="second">
<div class="warning-container">
<div class="warning-item" v-for="(item, index) in warningList" :key="index">
<template v-if="item.info">
{{item.label}}:{{item.info}}
</template>
</div>
</div>
</el-tab-pane>
<el-tab-pane :label="proxy.$t('equipment.imageView')" name="third">
<div class="controls">
<el-button-group>
<el-button
type="primary"
plain
class="switch-btn right"
@click="handleImagePrev"
>
<el-icon><ArrowLeft /></el-icon>
</el-button>
<el-button
type="primary"
plain
class="switch-btn right switch"
@click="handleImageNext"
>
<el-icon><ArrowRight /></el-icon>
</el-button>
</el-button-group>
</div>
<div style="display: flex">
<div v-if="showRed">
<CurveChart ref="bowlCurveRef" :title="chartTitle.left" :color="colorRed"/>
<CurveChart ref="bowlCurveRef" :title="chartTitle.right" :color="colorRed"/>
</div>
<div v-if="showGreen">
<CurveChart ref="bowlCurveRef" :title="chartTitle.left" :color="colorGreen"/>
<CurveChart ref="bowlCurveRef" :title="chartTitle.right" :color="colorGreen"/>
</div>
<div v-if="showRedGreen">
<DualChannelChart
title="扫描臂1"
ref="dualChart1Ref"
:chart-data="arm1ChartData"
/>
<DualChannelChart
title="扫描臂2"
ref="dualChart2Ref"
:chart-data="arm2ChartData"
/>
</div>
</div>
</el-tab-pane>
<el-tab-pane :label="proxy.$t('equipment.trendChart')" name="four">
<RealtimeChart ref="realtimeChartRef" :real-data="trendData" v-if="activeThreeName === 'four'"/>
</el-tab-pane>
</el-tabs>
</div>
</div>
<!-- 历史数据弹框-->
<HistoryDataDialog
ref="historyDialogRef"
@confirm="handleHistoryConfirm"
@cancel="handleHistoryCancel"
/>
<!-- 添加数据弹框-->
<AddMonitorData ref="addMonitorRef" @confirm="handleDataConfirm" />
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import {getDeviceDetailApi} from "@/api/equipment/index.js";
import {Close, ArrowLeft, ArrowRight, Timer, Refresh, Plus} from '@element-plus/icons-vue'
import TemperatureChart from './common/TemperatureChart.vue'
import RealtimeChart from './common/RealtimeChart.vue';
import DeviceStatus from './common/DeviceStatus.vue';
import DeviceSetting from './common/DeviceSetting.vue';
import DualChannelChart from './common/DualChannelChart.vue';
import CurveChart from './common/CurveChart.vue';
import CircleDetectionChart from "./common/CircleDetectionChart.vue";
import HistoryDataDialog from './common/HistoryDataDialog.vue';
import {ElMessageBox, ElMessage} from "element-plus";
import { useMqtt } from '@/utils/mqttClient.js';
import {useRoute} from 'vue-router';
import AddMonitorData from './common/AddMonitorData.vue';
import { base64Decode, base64Encode } from '@/utils/base64'
import { timestampArrayToTime } from '@/utils/time'
const deviceShowStatus = ref('')
const {
connected,
messageData,
connect,
subscribe,
disconnect,
publish
} = useMqtt()
// const clientId = ref('lkk' + Math.random().toString(16).substring(2, 8))
const clientId = ref('lkk40a9bc')
const deviceInfo = ref({})
const deviceData = ref(null)
const deviceMode = ref(null)
const xRayStatus = ref(null)
const { proxy } = getCurrentInstance();
const route = useRoute()
const deviceId = ref(null)
const selectedLayer = ref('outer')
const toleranceList = ['15%', '20%', '25%']
const showRed = ref(true)
const showGreen = ref(false)
const showRedGreen = ref(false)
const showImagePageRed = ref(true)
const showImagePageGreen = ref(false)
const showImagePageRedGreen = ref(false)
const colorRed = ref('#ff4444')
const colorGreen = ref('#67c23a')
const currentIndex = ref(0)
const showHistory = ref(false)
const mode = ref('normal')
const realtimeChartRef = ref(null)
const trendData = ref({
datetime:[],
WtOSC: [],
WtINS:[],
WtISC: [],
EccentricityINS: [],
EccentricityOSC: [],
EccentricityISC: [],
DmCORE: [],
DmALL: []
})
const dualChart1Ref = ref(null)
const dualChart2Ref = ref(null)
const dualChart1PageRef = ref(null)
const dualChart2PageRef = ref(null)
const bowlCurvePageRef = ref(null)
const activeName = ref('first')
const activeTwoName = ref('first')
const activeThreeName = ref('first')
const bowlCurveRef = ref(null)
const showBtn = ref(false)
const historyDialogRef = ref(null)
const currentTime = ref('2021-02-11 13:23:39')
const chartTitle = ref({
left: '扫描臂1 曲线',
right: '扫描臂2 曲线'
})
const modeTypeMap = {
'fast':'快速模式',
'normal':'正常速度',
'slow':'慢速模式'
};
const cardList = ref([
{ title: '外屏层偏心度' },
{ title: '内屏层偏心度' },
{ title: '绝缘层偏心度' },
{ title: '外屏层厚度' },
{ title: '内屏层厚度' },
// { title: '绝缘层厚度' }
])
const warningList = ref([])
const warningInserted = ref(false)
// 示意图数据
const innerLayerData = ref([0.68, 0.85, 1.07, 1.18, 1.13, 0.97, 0.67, 0.98])
const middleLayerData = ref([9.52, 9.95, 10.53, 11.04, 11.34, 11.15, 9.66, 10.40])
const outerLayerData = ref([1.15, 1.19, 1.21, 1.17, 1.05, 0.96, 1.06, 0.79])
// 温度数据
const temperatureData = ref({
SCANNER1: [],
SCANNER2: [],
datetime: []
})
const deviceStatus = ref({})
const addMonitorRef = ref(null)
// 表格数据
const tableData = ref([
{ name: '射线电源反馈电压[V]', arm1: '15', arm2: '0' },
{ name: '射线电源设定电压[V]', arm1: '55000', arm2: '55000' },
// ... 其他数据
])
// 图表数据
const arm1ChartData = ref({
a: Array.from({ length: 100 }, () => Math.random() * 9000),
b: Array.from({ length: 100 }, () => Math.random() * 9000)
})
const arm2ChartData = ref({
a: Array.from({ length: 100 }, () => Math.random() * 9000),
b: Array.from({ length: 100 }, () => Math.random() * 9000)
})
// 打开新增设备弹框
const openDialog = () => {
addMonitorRef.value.showDialog()
}
const handleDataConfirm = (dataType) => {
console.log('选择的数据项:', dataType)
// 这里处理选择的数据项
}
// mqtt连接
const mqttConnect = () => {
console.log(clientId.value)
connect('ws://123.57.81.127:8085/mqtt', { // 添加 /mqtt 路径
clientId: clientId.value,
username: 'cepianyi',
password: 'cpy123',
protocol: 'ws',
protocolVersion: 4,
keepalive: 60,
reconnectPeriod: 1000,
connectTimeout: 30 * 1000,
path: '/mqtt'// 指定 WebSocket 路径
})
}
const deleteCard = (index) => {
ElMessageBox.confirm(
'确认删除该卡片吗?',
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
cardList.value.splice(index, 1)
ElMessage.success('删除成功')
}).catch(() => {
// 用户取消删除
})
}
// 打开历史数据弹窗
const showHistoryDialog = () => {
historyDialogRef.value.show()
}
const handleHistoryConfirm = (data) => {
console.log('选择的历史数据:', data)
}
const handleHistoryCancel = () => {
console.log('取消选择')
}
// 图像预览
const handleImageNext = () => {
if (showRedGreen.value) {
showRedGreen.value = false
showRed.value = true
showGreen.value = false
} else if (showRed.value) {
showRedGreen.value = false
showRed.value = false
showGreen.value = true
} else if (showGreen.value) {
showRedGreen.value = true
showRed.value = false
showGreen.value = false
}
}
const handleImagePrev = () => {
if (showRedGreen.value) {
showRedGreen.value = false
showRed.value = false
showGreen.value = true
} else if (showGreen.value) {
showRedGreen.value = false
showRed.value = true
showGreen.value = false
} else if (showRed.value) {
showRedGreen.value = true
showRed.value = false
showGreen.value = false
}
}
const generateData = (type) => {
const data = []
for (let i = 0; i <= 90; i++) {
let value
if (i < 45) {
value = type === 'a' ? 8500 : 7500
} else if (i >= 45 && i < 60) {
value = 8500 - ((i - 45) * 500)
} else if (i >= 60 && i < 75) {
value = 1000 + ((i - 60) * 500)
} else {
value = type === 'a' ? 8500 : 7500
}
data.push([i, value])
}
arm1ChartData.value = data
}
// 标签页切换
const handleClick = (tab, event) => {
console.log(deviceStatus.value,'===')
nextTick(async() => {
if(tab.props.label === '趋势图') {
await sendDeviceTrend()
realtimeChartRef.value?.resize()
}
if(tab.props.label === '图像预览') {
bowlCurveRef.value?.resize()
}
})
}
const handlePrevious = () => {
if (currentIndex.value > 0) {
currentIndex.value--
}
}
const handleNext = () => {
if (currentIndex.value < toleranceList.length - 1) {
currentIndex.value++
}
}
// 图像预览
const handleDataUpdate = (data) => {
console.log('数据更新:', data)
}
// 快速模式
const handleModeChange = () => {
ElMessageBox.confirm(
'是否确认切换模式?',
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(async() => {
try {
await publish(`v1/cpy/${deviceInfo.value.deviceCode}/control`, JSON.stringify({
method: 'devinput',
cid: clientId.value, // guid
scanner: "global_dev",
dev: 'device', // 高压源power电机 motor 采集板acquisition_board 射线xray 其他设备 device
key: 'sports_mode',
value: '' // 运动模式 fast快速 normal正常速度 slow慢速
}))
ElMessage.success('发送命令成功')
initSubscribe()
} catch (error) {
ElMessage.error('发送命令失败')
}
}).catch(() => {
// 用户取消操作
})
}
//x射线
const handleXRayToggle = () => {
ElMessageBox.confirm(
'是否确认切换X射线状态',
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
).then(async() => {
try {
// 这里可以调用接口来切换X射线状态
await publish(`v1/cpy/${deviceInfo.value.deviceCode}/control`, JSON.stringify({
method: 'devinput',
cid:clientId.value,
scanner:'scanner1',
dev:'xray',
key: "switch",
value:"1" // 1开 0关
}))
await publish(`v1/cpy/${deviceInfo.value.deviceCode}/control`, JSON.stringify({
method: 'devinput',
cid:clientId.value,
scanner:'scanner2',
dev:'xray',
key: "switch",
value:"1" // 1开 0关
}))
ElMessage.success('发送命令成功')
initSubscribe()
} catch (error) {
ElMessage.error('发送命令失败')
}
}).catch(() => {
// 用户取消操作
})
}
// 生成报告
const handleGenerateReport = () => {
}
// 设备分享
const handleDeviceShare = () => {
}
const initSubscribe = () => {
// 设备信息
subscribe(`v1/cpy/${deviceInfo.value?.deviceCode}/infos`, (message) => {
console.log('设备信息消息:', message)
// deviceData.value = message
if(message){
deviceMode.value = message.global_dev.device.sports_mode
xRayStatus.value = message.scanner1.xray.enable_status
deviceStatus.value = { ...message }
if (!warningInserted.value) {
warningList.value.push(
{label:'scanner1采集板故障信息', info: message.scanner1.acquisition_board.failure_info},
{label:'scanner1电源故障信息', info: message.scanner1.power.failure_info},
{label:'scanner1射线故障信息', info: message.scanner1.xray.failure_info},
{label:'scanner1电机通信状态', info: message.scanner1.motor.failure_info},
{label:'scanner2采集板故障信息', info: message.scanner2.acquisition_board.failure_info},
{label:'scanner2电源故障信息', info: message.scanner2.power.failure_info},
{label:'scanner2射线故障信息', info: message.scanner2.xray.failure_info},
{label:'scanner2电机通信状态', info: message.scanner2.motor.failure_info}
)
warningInserted.value = true
}
}})
// 设备状态
subscribe(`v1/cpycal/${deviceInfo.value?.deviceCode}/status`, (message) => {
// console.log('设备状态消息:', message)
if(message && message.running) {
deviceShowStatus.value = proxy.$t('common.online')
} else {
deviceShowStatus.value = proxy.$t('common.offline')
}
})
// 计算数据
subscribe(`v1/cpy/${deviceInfo.value?.deviceCode}/calculation`, (message) => {
console.log('计算数据:', message)
// deviceData.value = message
// if(message){
// deviceMode.value = message.global_dev.device.sports_mode
// console.log(deviceMode.value)
// xRayStatus.value = message.scanner1.xray.enable_status
// }
})
//图像预览
subscribe(`v1/cpy/${deviceInfo.value?.deviceCode}/collect`, (message) => {
console.log('图像预览数据:', message)
// deviceData.value = message
// if(message){
// deviceMode.value = message.global_dev.device.sports_mode
// console.log(deviceMode.value)
// xRayStatus.value = message.scanner1.xray.enable_status
// }
})
}
// 设备温度
const sendDeviceTemperature = async () => {
try {
await publish(`v1/cpy/1/request`, JSON.stringify({
method: 'temperature',
cid: clientId.value,
duration: 60,
}))
ElMessage.success('发送命令成功')
subscribe(`v1/cpy/${clientId.value}/receive`, (message) => {
console.log('设备温度:', message)
if(message.method === 'temperature') {
temperatureData.value.SCANNER1 = base64Decode(message.SCANNER1,true)
temperatureData.value.SCANNER2 = base64Decode(message.SCANNER1,true)
temperatureData.value.datetime = timestampArrayToTime(base64Decode(message.datetime,true))
}
})
} catch (error) {
ElMessage.error('发送命令失败')
}
}
// 趋势图
const sendDeviceTrend = async () => {
try {
await publish(`v1/cpy/1/request`, JSON.stringify({
method: 'trend',
cid: clientId.value,
duration: 30,
filters:'WtOSC'
}))
ElMessage.success('发送命令成功')
subscribe(`v1/cpy/${clientId.value}/receive`, (message) => {
console.log('趋势数据:', message)
if(message.method === 'trend') {
trendData.value.datetime = base64Decode(message.datetime,true)
trendData.value.WtOSC = base64Decode(message.WtOSC,true)
trendData.value.WtINS = base64Decode(message.WtINS,true)
trendData.value.WtISC = base64Decode(message.WtISC,true)
trendData.value.EccentricityINS = base64Decode(message.EccentricityINS,true)
trendData.value.EccentricityOSC = base64Decode(message.EccentricityOSC,true)
trendData.value.EccentricityISC = base64Decode(message.EccentricityISC,true)
trendData.value.DmCORE = base64Decode(message.DmCORE,true)
trendData.value.DmALL = base64Decode(message.DmALL,true)
console.log(trendData.value,'==')
}
})
} catch (error) {
ElMessage.error('发送命令失败')
}
}
// 获取设备详细信息
const getDeviceDetail = async () => {
try {
const res = await getDeviceDetailApi(deviceId.value)
deviceInfo.value = res.data
initSubscribe()
} catch (error) {
ElMessage.error(error.message)
}
}
onMounted(async() => {
mqttConnect()
if(route.query.id) {
deviceId.value= route.query.id;
await getDeviceDetail()
}
await sendDeviceTemperature()
await sendDeviceTrend()
generateData()
})
onBeforeUnmount(() => {
disconnect()
})
</script>
<style scoped lang="scss">
.equipment-container {
padding: 20px;
h3 {
margin: 0 0 20px;
font-size: 16px;
font-weight: 500;
}
.data-overview {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
.data-left {
display: flex;
align-items: center;
}
}
.data-card {
flex: 1;
display: flex;
padding: 20px;
background: #fff;
border-radius: 4px;
align-items: center;
box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
.img-icon {
border:1px dashed #ccc;
margin-right: 10px;
}
.number {
font-size: 28px;
font-weight: bold;
margin-bottom: 10px;
color:#333333;
}
.label {
color: #999;
font-size: 14px;
}
}
.chart-container {
display: flex;
gap: 20px;
.chart-box {
flex:1;
position: relative;
padding: 14px;
background: #fff;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
.btn {
position: absolute;
top:14px;
right: 14px;
}
}
}
}
.action-buttons {
padding: 10px 0;
.button-group {
display: flex;
gap: 10px;
.el-button {
display: flex;
align-items: center;
gap: 5px;
&.el-button--danger {
background-color: #f56c6c;
border-color: #f56c6c;
color: #fff;
&:hover {
background-color: #f78989;
border-color: #f78989;
}
}
}
}
}
.demo-tabs > .el-tabs__content {
padding: 32px;
color: #6b778c;
font-size: 32px;
font-weight: 600;
}
.eccentricity-card {
background-color: #F5F7FA;
border-radius: 4px;
padding: 14px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 10px;
border-bottom:1px solid #ccc;
margin-bottom: 10px;
.title {
font-size: 14px;
color: #333;
font-weight: 600;
}
.close-icon {
cursor: pointer;
color: #999;
}
}
.card-content {
.card-text {
display: flex;
justify-content: space-between;
}
.difference {
margin-bottom: 6px;
font-size: 14px;
.plus {
color: #f56c6c;
margin-right: 5px;
}
.label {
color: #f56c6c;
}
}
.value {
font-size: 32px;
font-weight: bold;
color: red;
margin-bottom: 15px;
.unit {
font-size: 16px;
margin-left: 5px;
}
}
.tolerance-section {
display: flex;
align-items: center;
justify-content: space-between;
background: #E5ECF6 ;
padding: 8px;
border-radius: 4px;
.tolerance-text {
color: #666;
font-size: 14px;
}
}
}
}
.card-container {
.card-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 15px;
border-radius: 4px;
}
}
.chart-bottom-left {
width:38%;
}
.chart-bottom-right {
flex:1
}
.warning-container {
padding-left:10px;
.warning-item {
color:red;
margin-bottom: 10px;
}
}
.device-status {
background: #fff;
border-radius: 4px;
height: 346px;
overflow-y: scroll;
:deep(.el-table) {
.el-tag {
width: 100%;
justify-content: center;
&.el-tag--danger {
background-color: #fef0f0;
}
}
.cell {
padding: 8px 0;
}
}
}
.header {
//display: flex;
//justify-content: space-between;
//align-items: center;
//margin-bottom: 14px;
.time {
font-size: 14px;
color: #606266;
margin-left: 6px;
}
}
.imagePage-container {
display: flex;
.imagePage-left {
width: 52%;
}
}
.charts {
//display: flex;
//gap: 20px;
padding: 0 6px;
flex:1;
//
//> div {
// flex: 1;
//}
}
.controls {
display: flex;
justify-content: flex-end;
.switch {
margin-left: 5px;
}
}
.switch-btn {
padding: 5px;
//&:hover {
// background: #f0f9eb;
//}
}
.detection-section {
padding: 20px;
background: #fff;
border-radius: 4px;
}
.history-content {
display: flex;
justify-content: space-between;
align-items: center;
.history-right {
display: flex;
flex-direction: column;
align-items: flex-end;
}
.scanItem {
color:#666;
font-size: 12px;
margin-bottom: 6px;
}
}
</style>