From c45cbdd1fb5e1c491a58f24be403b97999c1a9ec Mon Sep 17 00:00:00 2001
From: web <candymxq888@outlook.com>
Date: 星期四, 17 七月 2025 17:31:59 +0800
Subject: [PATCH] fix:shuju

---
 src/views/screen/device.vue |  459 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 444 insertions(+), 15 deletions(-)

diff --git a/src/views/screen/device.vue b/src/views/screen/device.vue
index 6e39e63..c6b2541 100644
--- a/src/views/screen/device.vue
+++ b/src/views/screen/device.vue
@@ -4,31 +4,133 @@
             <div class="left">
                 <div class="left-item">
                     <div class="item-t">设备时长</div>
-                    <div class="item-c"></div>
+                    <div class="item-c">
+                        <el-table 
+                            :data="facityWarnTable" 
+                            :header-cell-style="headerStyle"
+                            :cell-style="rowStyle"
+                            style="height: 100%;"
+                        >
+                            <el-table-column prop="pointName" label="异常监测点" />
+                            <el-table-column prop="facilityName" label="异常设备" />
+                            <el-table-column prop="description" label="报警内容" />
+                            <el-table-column prop="alarmTime" label="报警时长" />
+                        </el-table>
+                    </div>
                 </div>
                 <div class="left-item">
-                    <div class="item-t">风机管理</div>
-                    <div class="item-c"></div>
+                    <div class="item-t">
+                        <div class="title-left">风机管理</div>
+                        <div class="title-right">
+                            <el-select
+                                v-model="typeValue.fengji"
+                                size="small"
+                                style="width: 8rem"
+                                @change="getFanList"
+                            >
+                                <el-option
+                                v-for="item in fengjiOption"
+                                :key="item.value"
+                                :label="item.label"
+                                :value="item.value"
+                                />
+                            </el-select>
+                            <el-button type="success" size="small">一键启动</el-button>
+                        </div>
+                    </div>
+                    <div class="item-c">
+                        <div class="fengji">
+                            <div class="fengjiItem" v-for="(item, index) in fengjiList" :key="index">
+                                <div class="fengji-title">{{ item.pointName }}</div>
+                                <div class="fengji-status">
+                                    <img :class="{run: item.facilityFanState === 1}" src="@/assets/images/screen/fengji.png" alt="" />
+                                    <span v-if="item.facilityFanState === 0">停止</span>
+                                    <span v-else-if="item.facilityFanState === 1">运行中</span>
+                                    <span v-else-if="item.facilityFanState === 2">一级报警</span>
+                                    <span v-else-if="item.facilityFanState === 3">二级报警</span>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
                 </div>
                 <div class="left-item">
                     <div class="item-t">工单处理</div>
-                    <div class="item-c"></div>
+                    <div class="item-c">
+                        <el-table 
+                            :data="ordertable" 
+                            :header-cell-style="headerStyle"
+                            :cell-style="rowStyle"
+                            style="height: 100%;"
+                        >
+                            <el-table-column prop="code" label="工单号" />
+                            <el-table-column prop="typeView" label="工单类型" />
+                            <el-table-column prop="createTimeView" label="上报时间" />
+                            <el-table-column prop="createUserName" label="上报人" />
+                            <el-table-column prop="address" label="所属地址" />
+                            <el-table-column label="工单状态">
+                                <template #default="scoped">
+                                    <div v-if="scoped.row.executeState === 200" style="color: #36fc0e;">已处理</div>
+                                    <div v-else style="color: #ccc;">未处理</div>
+                                </template>
+                            </el-table-column>
+                        </el-table>
+                    </div>
                 </div>
                 <div class="left-item">
                     <div class="item-t">设备状态</div>
-                    <div class="item-c"></div>
+                    <div class="item-c">
+                        <div ref="statusRef" class="sbStatus"></div>
+                    </div>
                 </div>
             </div>
         </div>
         <div class="device-c">
             <div class="center">
                 <div class="center-item">
-                    <div class="item-t">实时数据</div>
-                    <div class="item-c"></div>
+                    <div class="item-t">
+                        <div class="title-left">实时数据</div>
+                        <div class="title-right">
+                            <el-select
+                                v-model="typeValue.pointId"
+                                size="small"
+                                style="width: 8rem"
+                                @change="getNewData"
+                            >
+                                <el-option
+                                v-for="item in pointList"
+                                :key="item.id"
+                                :label="item.pointName"
+                                :value="item.id"
+                                />
+                            </el-select>
+                            <el-select
+                                v-model="typeValue.facilityState"
+                                size="small"
+                                style="width: 8rem"
+                                @change="getNewData"
+                            >
+                                <el-option
+                                v-for="item in fengjiOption"
+                                :key="item.value"
+                                :label="item.label"
+                                :value="item.value"
+                                />
+                            </el-select>
+                        </div>
+                    </div>
+                    <div class="item-c">
+                        <div class="data-list">
+                            <template v-for="(item, index) in newDataList" :key="index">
+                                <dataItem :item="item" />
+                            </template>
+                        </div>
+                    </div>
                 </div>
                 <div class="center-item">
                     <div class="item-t">终端监控分类曲线</div>
-                    <div class="item-c"></div>
+                    <div class="item-c">
+                        <div ref="moniterRef" class="moniter"></div>
+                    </div>
                 </div>
             </div>
         </div>
@@ -36,11 +138,35 @@
             <div class="right">
                 <div class="right-item">
                     <div class="item-t">风机状态</div>
-                    <div class="item-c"></div>
+                    <div class="item-c">
+                        <el-table 
+                            :data="fengjiStatusTable" 
+                            :header-cell-style="headerStyle"
+                            :cell-style="rowStyle"
+                            style="height: 100%;"
+                        >
+                            <el-table-column prop="facilityId" label="风机编号" />
+                            <el-table-column prop="runTimeString" label="单次运行时长" />
+                            <el-table-column prop="pointName" label="运行地址" />
+                            <el-table-column prop="sumTimeString" label="总运行时长" />
+                        </el-table>
+                    </div>
                 </div>
                 <div class="right-item">
                     <div class="item-t">设备报警</div>
-                    <div class="item-c"></div>
+                    <div class="item-c">
+                        <el-table 
+                            :data="warnRecordTable" 
+                            :header-cell-style="headerStyle"
+                            :cell-style="rowStyle"
+                            style="height: 100%;"
+                        >
+                            <el-table-column prop="facilityCode" label="设备编号" />
+                            <el-table-column prop="alarmTypeView" label="报警类型" />
+                            <el-table-column prop="address" label="报警地址" />
+                            <el-table-column prop="latestAlarmTime" label="报警时间" />
+                        </el-table>
+                    </div>
                 </div>
             </div>
         </div>
@@ -48,7 +174,217 @@
 </template>
 
 <script setup>
+    import { onMounted, reactive } from 'vue';
+    import dataItem from './components/dataItem.vue'
+    import * as echarts from 'echarts';
+    import { getOrder, getFanFacity, getFacityData, getFacityRunTime, getFacityWarn, getFacityStatus, getPointStatic } from '@/api/screen/device'
+    import { getWarnRecord } from '@/api/screen/data'
+    import pointApi from "@/api/facility/point";
 
+    const facityWarnTable = ref([])
+    const fengjiList = ref([])
+    const ordertable = ref([])
+    const facityStatus = ref([])
+    const newDataList = ref([])
+    const lineChartList = ref([])
+    const fengjiStatusTable = ref([])
+    const warnRecordTable = ref([])
+
+    const typeValue = reactive({
+        fengji: 1,
+        pointId: '',
+        facilityState: 1,
+    })
+    const fengjiOption = [
+        {label: '停止', value: 0},
+        {label: '运行中', value: 1},
+        {label: '一级报警', value: 2},
+        {label: '二级报警', value: 3}
+    ]
+    const pointList = ref([])
+
+    const headerStyle = { 
+        "background-color": '#041025 !important'
+    }
+    const rowStyle = {
+        "background-color": '#081C3F !important'
+    }
+
+    const statusRef = ref()
+    const moniterRef = ref()
+    let statusCharts = null
+    let moniterCharts = null
+
+    const setStatusCharts = () => {
+         const option = {
+                tooltip: {
+                    trigger: 'item'
+                },
+                series: [
+                    {
+                        type: 'pie',
+                        radius: ['40%', '70%'],
+                        data: facityStatus.value
+                    }
+                ]
+            };
+
+            statusCharts.setOption(option)
+    }
+
+    const setMoniterCharts = () => {
+        let xdata = []
+        let sdata = []
+        lineChartList.value.forEach(el => {
+            xdata.push(el.pointName)
+            sdata.push(el.count)
+        })
+        const option = {
+                tooltip: {
+                    trigger: 'axis'
+                },
+                dataZoom: [
+                    {
+                        id: 'dataZoomX',
+                        type: 'slider',
+                        xAxisIndex: [0],
+                        filterMode: 'filter'
+                    }
+                ],
+                xAxis: {
+                    type: 'category',
+                    boundaryGap: false,
+                    data: xdata
+                },
+                yAxis: {
+                    type: 'value'
+                },
+                series: [
+                    {
+                        data: sdata,
+                        type: 'line',
+                        areaStyle: {
+                            color: {
+                                type: 'linear',
+                                x: 0,
+                                y: 0,
+                                x2: 0,
+                                y2: 1,
+                                colorStops: [
+                                    {offset: 0, color: 'rgba(118,196,235,1)' },
+                                    {offset: 1, color: 'rgba(118,196,235,0)'}
+                                ],
+                            }
+                        }
+                    }
+                ]
+            };
+
+            moniterCharts.setOption(option)
+    }
+
+    // 获取监控点列表
+    const getPointData = () => {
+        const searchData = {
+            limit: 100,
+            page: 1
+        }
+        return pointApi().search(searchData).then((res) => {
+            pointList.value = res.data.list
+            typeValue.pointId = res.data.list[0].id
+        })
+    }
+
+    // 设备报警时长
+    const getFacityTimelong = () => {
+        getFacityWarn().then(res => {
+            facityWarnTable.value = res.data
+        })
+    }
+
+    // 获取工单
+    const getOrderList = () => {
+        getOrder().then(res => {
+            ordertable.value = res.data
+        })
+    }
+
+    // 风机管理
+    const getFanList = () => {
+        getFanFacity({ type: typeValue.fengji }).then(res => {
+            fengjiList.value = res.data
+        })
+    }
+
+    // 设备状态
+    const getStatus = () => {
+        getFacityStatus().then(res => {
+            facityStatus.value = res.data.map(item => {
+                return {
+                    name: item.typeName,
+                    value: Number(item.value)
+                }
+            })
+            setStatusCharts()
+        })
+    }
+
+    // 实时数据
+    const getNewData = () => {
+        const searchData = {
+            pointId: typeValue.pointId,
+            facilityState: typeValue.facilityState
+        }
+        getFacityData(searchData).then(res => {
+            newDataList.value = res.data
+        })
+    }
+
+    // 监控统计
+    const getPoint = () => {
+        getPointStatic().then(res => {
+            lineChartList.value = res.data
+            setMoniterCharts()
+        })
+    }
+
+
+    // 风机状态
+    const getFanStatus = () => {
+        getFacityRunTime().then(res => {
+            fengjiStatusTable.value = res.data
+        })
+    }
+
+    // 设备报警
+    const getFacityWarnRecord = () => {
+        getWarnRecord().then(res => {
+            warnRecordTable.value = res.data
+        })
+    }
+
+     const init = async () => {
+        if(statusRef.value){
+            statusCharts = echarts.init(statusRef.value)
+        }
+        if(moniterRef.value){
+            moniterCharts = echarts.init(moniterRef.value)
+        }
+        await getPointData()
+        getFacityTimelong()
+        getOrderList()
+        getFanList()
+        getStatus()
+        getNewData()
+        getPoint()
+        getFanStatus()
+        getFacityWarnRecord()
+    }
+
+
+    onMounted(() => {
+        init()
+    })
 </script>
 
 <style scoped lang="scss">
@@ -57,8 +393,23 @@
         color: #fff;
         display: flex;
         justify-content: space-between;
+        :deep(.el-table){
+            --el-table-border-color: #000;
+            --el-table-bg-color: transparent;
+            th{
+                font-size: 12px;
+                color: #fff;
+            }
+            tr{
+                font-size: 12px;
+                color: #fff;
+            }
+            .el-table__cell{
+                border: none;
+            }
+        }
         &-l{
-            width: 25%;
+            width: 29%;
             height: 100%;
             .left{
                 height: 100%;   
@@ -66,6 +417,7 @@
                 flex-direction: column;
                 justify-content: space-between;
                 .left-item{
+                    flex-shrink: 0;
                     width: 100%;
                     height: 24%;
                     background-image: url('@/assets/images/screen/ct-small.png');
@@ -75,17 +427,64 @@
                         width: 100%;
                         height: 3rem;
                         line-height: 3rem;
-                        padding-left: 3.5rem;
+                        padding: 0 5rem 0 4rem;
+                        display: flex;
+                        justify-content: space-between;
+                        align-items: center;
+                        .title-right{
+                            display: flex;
+                            gap: 1rem;
+                        }
                     }
                     .item-c{
                         height: calc(100% - 3rem);
                         padding: 0.5rem;
+                        // overflow-y: scroll;
+                        // &::-webkit-scrollbar{
+                        //     display: none;
+                        // }
+                        .sbStatus{
+                            width: 100%;
+                            height: 100%;
+                        }
+                    }
+                    .fengji{
+                        width: 100%;
+                        height: 100%;
+                        display: flex;
+                        flex-wrap: wrap;
+                        overflow-y: scroll;
+                        &::-webkit-scrollbar{
+                            display: none;
+                        }
+                        .fengjiItem{
+                            width: 50%;
+                            height: 50%;
+                            text-align: center;
+                            .fengji-title{
+                                font-size: 0.8rem;
+                                padding: 0.5rem 0;
+                            }
+                            .fengji-status{
+                                display: flex;
+                                align-items: center;
+                                justify-content: center;
+                                img{
+                                    width: 2rem;
+                                    height: 2rem;
+                                    margin-right: 2rem;
+                                }
+                                .run{
+                                    animation: rotateAnimation 1s linear 0s infinite;
+                                }
+                            }
+                        }
                     }
                 }
             }
         }
         &-c{
-            width: 49%;
+            width: 40%;
             height: 100%;
             .center{
                 height: 100%;   
@@ -100,17 +499,38 @@
                     .item-t{
                         height: 3rem;
                         line-height: 3rem;
-                        padding-left: 4.5rem;
+                        padding: 0  6rem 0 3.8rem;
+                        display: flex;
+                        justify-content: space-between;
+                        align-items: center;
+                        .title-right{
+                            display: flex;
+                            gap: 1rem;
+                        }
                     }
                     .item-c{
                         height: calc(100% - 3rem);
                         padding: 0.5rem;
+                        .moniter{
+                            width: 100%;
+                            height: 100%;
+                        }
+                        .data-list{
+                            height: 100%;
+                            display: flex;
+                            flex-wrap: wrap;
+                            gap: 0.7rem;
+                            overflow-y: scroll;
+                            &::-webkit-scrollbar{
+                                display: none;
+                            }
+                        }
                     }
                 }
             }
         }
         &-r{
-            width: 25%;
+            width: 29%;
             height: 100%;
             .right{
                 height: 100%;   
@@ -135,4 +555,13 @@
             }
         }
     }
+
+    @keyframes rotateAnimation{
+        0%{
+            transform: rotate(0deg);
+        }
+        100%{
+            transform: rotate(360deg);
+        }
+    }
 </style>
\ No newline at end of file

--
Gitblit v1.9.3