refactor(demo1): 重构示范电站页面布局和样式
- 调整了设备情况、电站一次系统图等组件的布局 - 优化了卡片样式,添加了新的运行步骤日志卡片 - 修改了标题组件的样式,增加了字体大小等属性 - 调整了安全运行天数的展示方式,增加了背景图片
This commit is contained in:
@ -9,15 +9,18 @@ VITE_APP_ENV = 'development'
|
|||||||
# 李陈杰 209
|
# 李陈杰 209
|
||||||
# VITE_APP_BASE_API = 'http://192.168.110.209:8899'
|
# VITE_APP_BASE_API = 'http://192.168.110.209:8899'
|
||||||
# 李陈杰 209
|
# 李陈杰 209
|
||||||
# VITE_APP_BASE_API = 'http://192.168.110.209:8899'
|
# VITE_APP_BASE_API = 'http://192.168.110.209:8899'
|
||||||
# 曾涛
|
# 曾涛
|
||||||
VITE_APP_BASE_API = 'http://192.168.110.209:8899'
|
# VITE_APP_BASE_API = 'http://192.168.110.209:8899'
|
||||||
# 罗成
|
# 罗成
|
||||||
# VITE_APP_BASE_API = 'http://192.168.110.209:8899'
|
# VITE_APP_BASE_API = 'http://192.168.110.209:8899'
|
||||||
# 朱银
|
# 朱银
|
||||||
# VITE_APP_BASE_API = 'http://192.168.110.149:8899'
|
# VITE_APP_BASE_API = 'http://192.168.110.149:8899'
|
||||||
#曾涛
|
#曾涛
|
||||||
# VITE_APP_BASE_API = 'http://192.168.110.171:8899'
|
# VITE_APP_BASE_API = 'http://192.168.110.171:8899'
|
||||||
|
# 屈展航
|
||||||
|
VITE_APP_BASE_API = 'http://192.168.110.210:8899'
|
||||||
|
|
||||||
|
|
||||||
# ws
|
# ws
|
||||||
VITE_APP_BASE_WS_API = 'ws://192.168.110.149:8899/resource/websocket'
|
VITE_APP_BASE_WS_API = 'ws://192.168.110.149:8899/resource/websocket'
|
||||||
|
|||||||
BIN
public/assets/demo/czzl.png
Normal file
BIN
public/assets/demo/czzl.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
public/assets/demo/dayImg.png
Normal file
BIN
public/assets/demo/dayImg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 136 KiB |
BIN
public/assets/demo/glsc.png
Normal file
BIN
public/assets/demo/glsc.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
public/assets/demo/sjjk.png
Normal file
BIN
public/assets/demo/sjjk.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
@ -1,10 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-row>
|
<el-row style="padding: 0 20px;">
|
||||||
<el-col>
|
<el-col>
|
||||||
<div
|
<div style="color: rgba(0, 30, 59, 1); font-family: 'Alibaba-PuHuiTi-Bold'; margin: 10px 0 0 0"
|
||||||
style="color: rgba(0, 30, 59, 1); font-family: 'Alibaba-PuHuiTi-Bold'; margin: 10px 0 0 0"
|
:style="{ fontSize: fontLevelMap[props.fontLevel] }">
|
||||||
:style="{ fontSize: fontLevelMap[props.fontLevel] }"
|
|
||||||
>
|
|
||||||
{{ props.title }}
|
{{ props.title }}
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|||||||
38
src/views/demo1/components/RightTitle.vue
Normal file
38
src/views/demo1/components/RightTitle.vue
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<template>
|
||||||
|
<div style="display: flex;align-items: center;">
|
||||||
|
<div class="icon">
|
||||||
|
<img :src="`/assets/demo/${icon}.png`" alt="图片" />
|
||||||
|
</div>
|
||||||
|
<div class="subtitle">
|
||||||
|
{{ subtitle }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
const { subtitle, icon } = defineProps({
|
||||||
|
subtitle: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.subtitle {
|
||||||
|
font-family: Alibaba-PuHuiTi-Bold;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 400;
|
||||||
|
letter-spacing: 0px;
|
||||||
|
line-height: 21.6px;
|
||||||
|
color: rgba(0, 30, 59, 1);
|
||||||
|
text-align: left;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
226
src/views/demo1/components/czzljl.vue
Normal file
226
src/views/demo1/components/czzljl.vue
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
<template>
|
||||||
|
<div class="operation-log-container">
|
||||||
|
<!-- 页面标题 -->
|
||||||
|
<div class="page-title">
|
||||||
|
<el-icon class="title-icon">
|
||||||
|
<DocumentChecked />
|
||||||
|
</el-icon>
|
||||||
|
<h1>操作指令记录</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 搜索和操作区域 -->
|
||||||
|
<div class="search-bar">
|
||||||
|
<el-select v-model="selectedCommandType" placeholder="输入操作指令..." class="search-select" clearable>
|
||||||
|
<el-option v-for="type in commandTypes" :key="type.value" :label="type.label" :value="type.value" />
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
<el-button type="primary" class="send-btn">
|
||||||
|
<el-icon>
|
||||||
|
<Paperclip />
|
||||||
|
</el-icon>
|
||||||
|
发送
|
||||||
|
</el-button>
|
||||||
|
|
||||||
|
<el-button type="primary" :plain="true" class="export-btn">
|
||||||
|
<el-icon>
|
||||||
|
<Download />
|
||||||
|
</el-icon>
|
||||||
|
导出
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 表格区域 -->
|
||||||
|
<el-table :data="tableData" border stripe class="log-table">
|
||||||
|
<el-table-column type="selection" width="50" />
|
||||||
|
|
||||||
|
<el-table-column prop="commandType" label="指令类型" width="120" />
|
||||||
|
|
||||||
|
<el-table-column prop="operationContent" label="操作内容" min-width="200" />
|
||||||
|
|
||||||
|
<el-table-column prop="device" label="设备" width="100" />
|
||||||
|
|
||||||
|
<el-table-column prop="status" label="状态" width="120" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag :type="scope.row.status === 'SUCCESS' ? 'success' : 'danger'" effect="light"
|
||||||
|
class="status-tag">
|
||||||
|
<el-icon :class="scope.row.status === 'SUCCESS' ? 'success-icon' : 'error-icon'">
|
||||||
|
<Check v-if="scope.row.status === 'SUCCESS'" />
|
||||||
|
<Close v-else />
|
||||||
|
</el-icon>
|
||||||
|
{{ scope.row.status }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column prop="time" label="时间" width="140" />
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 分页区域 -->
|
||||||
|
<div class="pagination-container">
|
||||||
|
<div class="record-info">
|
||||||
|
显示第1到7条,共54条记录
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-pagination v-model:current-page="currentPage" :page-size="pageSize" :page-count="totalPages"
|
||||||
|
layout="prev, pager, next" @current-change="handlePageChange" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import {
|
||||||
|
DocumentChecked,
|
||||||
|
Paperclip,
|
||||||
|
Download,
|
||||||
|
Check,
|
||||||
|
Close
|
||||||
|
} from '@element-plus/icons-vue';
|
||||||
|
|
||||||
|
// 指令类型选项
|
||||||
|
const commandTypes = [
|
||||||
|
{ label: '系统自检', value: 'system_check' },
|
||||||
|
{ label: '闭合馈线开关', value: 'close_feeder_switch' },
|
||||||
|
{ label: '闭合保护开关', value: 'close_protection_switch' },
|
||||||
|
{ label: '断开馈线开关', value: 'open_feeder_switch' },
|
||||||
|
];
|
||||||
|
|
||||||
|
// 选中的指令类型
|
||||||
|
const selectedCommandType = ref('');
|
||||||
|
|
||||||
|
// 表格数据
|
||||||
|
const tableData = ref([
|
||||||
|
{
|
||||||
|
commandType: '系统自检',
|
||||||
|
operationContent: '系统进入正常供电模式.',
|
||||||
|
device: '主系统',
|
||||||
|
status: 'SUCCESS',
|
||||||
|
time: '09:51:24'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandType: '闭合馈线开关',
|
||||||
|
operationContent: '馈线开关A已闭合,负载A.',
|
||||||
|
device: '主系统',
|
||||||
|
status: 'SUCCESS',
|
||||||
|
time: '09:41:20'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandType: '闭合保护开关',
|
||||||
|
operationContent: '闭合母线开关',
|
||||||
|
device: '主系统',
|
||||||
|
status: 'ERROR',
|
||||||
|
time: '09:21:24'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandType: '系统自检',
|
||||||
|
operationContent: '母线电压稳定在110KV',
|
||||||
|
device: '主系统',
|
||||||
|
status: 'SUCCESS',
|
||||||
|
time: '09:11:24'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandType: '断开馈线开关',
|
||||||
|
operationContent: '闭合馈线开关',
|
||||||
|
device: '主系统',
|
||||||
|
status: 'SUCCESS',
|
||||||
|
time: '09:02:24'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandType: '断开馈线开关',
|
||||||
|
operationContent: '闭合馈线开关',
|
||||||
|
device: '主系统',
|
||||||
|
status: 'SUCCESS',
|
||||||
|
time: '09:02:24'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
commandType: '断开馈线开关',
|
||||||
|
operationContent: '闭合馈线开关',
|
||||||
|
device: '主系统',
|
||||||
|
status: 'SUCCESS',
|
||||||
|
time: '09:02:24'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 分页相关
|
||||||
|
const currentPage = ref(3);
|
||||||
|
const pageSize = ref(7);
|
||||||
|
const totalPages = ref(20);
|
||||||
|
|
||||||
|
// 处理页码变化
|
||||||
|
const handlePageChange = (page) => {
|
||||||
|
currentPage.value = page;
|
||||||
|
// 实际应用中这里会根据页码加载对应的数据
|
||||||
|
console.log(`切换到第${page}页`);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.operation-log-container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 20px auto;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-icon {
|
||||||
|
margin-right: 8px;
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-select {
|
||||||
|
flex: 0 1 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.send-btn,
|
||||||
|
.export-btn {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-table {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-icon {
|
||||||
|
color: #67c23a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-icon {
|
||||||
|
color: #f56c6c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
color: #606266;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record-info {
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-pagination {
|
||||||
|
--el-pagination-active-color: #409eff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
349
src/views/demo1/components/dzt.vue
Normal file
349
src/views/demo1/components/dzt.vue
Normal file
@ -0,0 +1,349 @@
|
|||||||
|
<template>
|
||||||
|
<el-card style="width: 100%;">
|
||||||
|
<div class="circuit-container">
|
||||||
|
<!-- 状态指示器 -->
|
||||||
|
<div class="status-indicators">
|
||||||
|
<div class="status-item">
|
||||||
|
<span class="status-dot closed"></span>
|
||||||
|
<span>闭合</span>
|
||||||
|
</div>
|
||||||
|
<div class="status-item">
|
||||||
|
<span class="status-dot open"></span>
|
||||||
|
<span>断开</span>
|
||||||
|
</div>
|
||||||
|
<div class="status-item">
|
||||||
|
<span class="status-dot running"></span>
|
||||||
|
<span>运行中</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 控制按钮 -->
|
||||||
|
<div class="control-buttons">
|
||||||
|
<button v-for="(device, index) in devices" :key="index" @click="toggleDevice(device.id)"
|
||||||
|
:class="{ 'btn-active': device.status === 'closed' }">
|
||||||
|
{{ device.name }}: {{ device.statusText }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 电路图 SVG -->
|
||||||
|
<svg class="circuit-svg" viewBox="0 0 800 400" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<!-- 背景网格 -->
|
||||||
|
<pattern id="grid" width="50" height="50" patternUnits="userSpaceOnUse">
|
||||||
|
<path d="M 50 0 L 0 0 0 50" fill="none" stroke="#f0f0f0" stroke-width="1" />
|
||||||
|
</pattern>
|
||||||
|
<rect width="100%" height="100%" fill="url(#grid)" />
|
||||||
|
|
||||||
|
<!-- 主线路径 -->
|
||||||
|
<!-- 发电站到主开关 -->
|
||||||
|
<line x1="100" y1="200" x2="180" y2="200" stroke="#22c55e" stroke-width="4" />
|
||||||
|
|
||||||
|
<!-- 主开关到变压器 -->
|
||||||
|
<line x1="220" y1="200" x2="280" y2="200" stroke="#22c55e" stroke-width="4" />
|
||||||
|
|
||||||
|
<!-- 变压器到母线开关 -->
|
||||||
|
<line x1="360" y1="200" x2="420" y2="200" stroke="#22c55e" stroke-width="4" />
|
||||||
|
|
||||||
|
<!-- 母线开关到分支点 -->
|
||||||
|
<line x1="460" y1="200" x2="500" y2="200" stroke="#22c55e" stroke-width="4" />
|
||||||
|
|
||||||
|
<!-- 分支点到馈线开关A -->
|
||||||
|
<line x1="500" y1="200" x2="500" y2="100" stroke="#22c55e" stroke-width="4" />
|
||||||
|
<line x1="500" y1="100" x2="580" y2="100" stroke="#22c55e" stroke-width="4" />
|
||||||
|
|
||||||
|
<!-- 分支点到馈线开关B -->
|
||||||
|
<line x1="500" y1="200" x2="500" y2="300" stroke="#ef4444" stroke-width="4" stroke-dasharray="5,5" />
|
||||||
|
<line x1="500" y1="300" x2="580" y2="300" stroke="#ef4444" stroke-width="4" stroke-dasharray="5,5" />
|
||||||
|
|
||||||
|
<!-- 馈线开关B到保护开关 -->
|
||||||
|
<line x1="620" y1="300" x2="700" y2="300" stroke="#ef4444" stroke-width="4" stroke-dasharray="5,5" />
|
||||||
|
|
||||||
|
<!-- 发电站 -->
|
||||||
|
<circle cx="100" cy="200" r="30" fill="#3b82f6" stroke="#1e40af" stroke-width="2" />
|
||||||
|
<text x="100" y="205" text-anchor="middle" fill="white" font-weight="bold">发电站</text>
|
||||||
|
|
||||||
|
<!-- 主开关 -->
|
||||||
|
<g :class="{ 'switch-closed': devices[0].status === 'closed' }">
|
||||||
|
<circle cx="200" cy="200" r="15" :fill="devices[0].status === 'closed' ? '#10b981' : '#ef4444'" />
|
||||||
|
<text x="200" y="250" text-anchor="middle" font-size="12">主开关</text>
|
||||||
|
<text x="200" y="270" text-anchor="middle" font-size="10" fill="#666">220kV</text>
|
||||||
|
<text x="200" y="285" text-anchor="middle" font-size="10"
|
||||||
|
:fill="devices[0].status === 'closed' ? '#10b981' : '#ef4444'">
|
||||||
|
{{ devices[0].statusText }}
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 变压器 -->
|
||||||
|
<g>
|
||||||
|
<rect x="300" y="170" width="60" height="60" fill="white" stroke="#666" stroke-width="2" />
|
||||||
|
<line x1="315" y1="190" x2="345" y2="190" stroke="#666" stroke-width="2" />
|
||||||
|
<line x1="315" y1="210" x2="345" y2="210" stroke="#666" stroke-width="2" />
|
||||||
|
<line x1="315" y1="230" x2="345" y2="230" stroke="#666" stroke-width="2" />
|
||||||
|
<text x="330" y="285" text-anchor="middle" font-size="10" fill="#10b981">已完成</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 母线开关 -->
|
||||||
|
<g :class="{ 'switch-closed': devices[1].status === 'closed' }">
|
||||||
|
<circle cx="440" cy="200" r="15" :fill="devices[1].status === 'closed' ? '#10b981' : '#ef4444'" />
|
||||||
|
<text x="440" y="250" text-anchor="middle" font-size="12">母线开关</text>
|
||||||
|
<text x="440" y="270" text-anchor="middle" font-size="10" fill="#666">110kV</text>
|
||||||
|
<text x="440" y="285" text-anchor="middle" font-size="10"
|
||||||
|
:fill="devices[1].status === 'closed' ? '#10b981' : '#ef4444'">
|
||||||
|
{{ devices[1].statusText }}
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 分支点 -->
|
||||||
|
<circle cx="500" cy="200" r="8" fill="#666" />
|
||||||
|
|
||||||
|
<!-- 馈线开关A -->
|
||||||
|
<g :class="{ 'switch-closed': devices[2].status === 'closed' }">
|
||||||
|
<circle cx="600" cy="100" r="15" :fill="devices[2].status === 'closed' ? '#10b981' : '#ef4444'" />
|
||||||
|
<text x="600" y="60" text-anchor="middle" font-size="12">馈线开关A</text>
|
||||||
|
<text x="600" y="80" text-anchor="middle" font-size="10"
|
||||||
|
:fill="devices[2].status === 'closed' ? '#10b981' : '#ef4444'">
|
||||||
|
{{ devices[2].statusText }}
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 负载A -->
|
||||||
|
<circle cx="680" cy="100" r="20" fill="#3b82f6" stroke="#1e40af" stroke-width="2" />
|
||||||
|
<text x="680" y="105" text-anchor="middle" fill="white" font-size="12">负载A</text>
|
||||||
|
<text x="680" y="135" text-anchor="middle" font-size="10" fill="#10b981">已完成</text>
|
||||||
|
|
||||||
|
<!-- 馈线开关B -->
|
||||||
|
<g :class="{ 'switch-closed': devices[3].status === 'closed' }">
|
||||||
|
<circle cx="600" cy="300" r="15" :fill="devices[3].status === 'closed' ? '#10b981' : '#ef4444'" />
|
||||||
|
<text x="600" y="340" text-anchor="middle" font-size="12">馈线开关B</text>
|
||||||
|
<text x="600" y="360" text-anchor="middle" font-size="10"
|
||||||
|
:fill="devices[3].status === 'closed' ? '#10b981' : '#ef4444'">
|
||||||
|
{{ devices[3].statusText }}
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- 保护开关 -->
|
||||||
|
<g :class="{ 'switch-closed': devices[4].status === 'closed' }">
|
||||||
|
<circle cx="720" cy="300" r="15" :fill="devices[4].status === 'closed' ? '#10b981' : '#ef4444'" />
|
||||||
|
<text x="720" y="340" text-anchor="middle" font-size="12">保护开关</text>
|
||||||
|
<text x="720" y="360" text-anchor="middle" font-size="10"
|
||||||
|
:fill="devices[4].status === 'closed' ? '#10b981' : '#ef4444'">
|
||||||
|
{{ devices[4].statusText }}
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<!-- WebSocket 连接状态 -->
|
||||||
|
<div class="connection-status">
|
||||||
|
<span>WebSocket 连接状态:</span>
|
||||||
|
<span :class="wsConnected ? 'connected' : 'disconnected'">
|
||||||
|
{{ wsConnected ? '已连接' : '未连接' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, onUnmounted } from 'vue';
|
||||||
|
|
||||||
|
// 设备状态数据
|
||||||
|
const devices = ref([
|
||||||
|
{ id: 'main-switch', name: '主开关', status: 'closed', statusText: '已完成' },
|
||||||
|
{ id: 'bus-switch', name: '母线开关', status: 'closed', statusText: '已完成' },
|
||||||
|
{ id: 'feeder-a', name: '馈线开关A', status: 'closed', statusText: '已完成' },
|
||||||
|
{ id: 'feeder-b', name: '馈线开关B', status: 'open', statusText: '未完成' },
|
||||||
|
{ id: 'protection-switch', name: '保护开关', status: 'open', statusText: '未完成' }
|
||||||
|
]);
|
||||||
|
|
||||||
|
// WebSocket 连接状态
|
||||||
|
const wsConnected = ref(false);
|
||||||
|
let ws = null;
|
||||||
|
|
||||||
|
// 切换设备状态
|
||||||
|
const toggleDevice = (deviceId) => {
|
||||||
|
const device = devices.value.find(d => d.id === deviceId);
|
||||||
|
if (device) {
|
||||||
|
// 切换状态
|
||||||
|
device.status = device.status === 'closed' ? 'open' : 'closed';
|
||||||
|
device.statusText = device.status === 'closed' ? '已完成' : '未完成';
|
||||||
|
|
||||||
|
// 发送状态到服务器
|
||||||
|
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
type: 'status-update',
|
||||||
|
deviceId,
|
||||||
|
status: device.status
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 连接 WebSocket
|
||||||
|
const connectWebSocket = () => {
|
||||||
|
// 实际应用中替换为真实的 WebSocket 服务器地址
|
||||||
|
const wsUrl = 'ws://localhost:8080/ws/circuit';
|
||||||
|
|
||||||
|
// 关闭现有连接
|
||||||
|
if (ws) {
|
||||||
|
ws.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新连接
|
||||||
|
ws = new WebSocket(wsUrl);
|
||||||
|
|
||||||
|
ws.onopen = () => {
|
||||||
|
console.log('WebSocket 连接已建立');
|
||||||
|
wsConnected.value = true;
|
||||||
|
|
||||||
|
// 发送当前状态
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
type: 'initial-status',
|
||||||
|
status: devices.value.reduce((acc, device) => {
|
||||||
|
acc[device.id] = device.status;
|
||||||
|
return acc;
|
||||||
|
}, {})
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onmessage = (event) => {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(event.data);
|
||||||
|
console.log('收到消息:', data);
|
||||||
|
|
||||||
|
// 处理状态更新
|
||||||
|
if (data.type === 'status-update' && data.deviceId && data.status) {
|
||||||
|
const device = devices.value.find(d => d.id === data.deviceId);
|
||||||
|
if (device) {
|
||||||
|
device.status = data.status;
|
||||||
|
device.statusText = data.status === 'closed' ? '已完成' : '未完成';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('解析 WebSocket 消息失败:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onclose = () => {
|
||||||
|
console.log('WebSocket 连接已关闭');
|
||||||
|
wsConnected.value = false;
|
||||||
|
|
||||||
|
// 5秒后尝试重连
|
||||||
|
setTimeout(connectWebSocket, 5000);
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onerror = (error) => {
|
||||||
|
console.error('WebSocket 错误:', error);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// 组件挂载时连接 WebSocket
|
||||||
|
onMounted(() => {
|
||||||
|
connectWebSocket();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 组件卸载时关闭 WebSocket 连接
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (ws) {
|
||||||
|
ws.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.circuit-container {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
padding: 20px;
|
||||||
|
max-width: 1000px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-indicators {
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-dot {
|
||||||
|
display: inline-block;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-dot.closed {
|
||||||
|
background-color: #10b981;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-dot.open {
|
||||||
|
background-color: #ef4444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-dot.running {
|
||||||
|
background-color: #eab308;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-buttons button {
|
||||||
|
padding: 8px 16px;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-buttons button.btn-active {
|
||||||
|
background-color: #10b981;
|
||||||
|
color: white;
|
||||||
|
border-color: #059669;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-buttons button:hover {
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-buttons button.btn-active:hover {
|
||||||
|
background-color: #059669;
|
||||||
|
}
|
||||||
|
|
||||||
|
.circuit-svg {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.connection-status {
|
||||||
|
margin-top: 15px;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.connection-status .connected {
|
||||||
|
color: #10b981;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.connection-status .disconnected {
|
||||||
|
color: #ef4444;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
69
src/views/demo1/components/glsc.vue
Normal file
69
src/views/demo1/components/glsc.vue
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<RightTitle subtitle="功率输出趋势" icon="glsc" />
|
||||||
|
</div>
|
||||||
|
<div ref="chartRef" style="width: 100%; height: 400px;"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import RightTitle from './RightTitle.vue';
|
||||||
|
// 创建对 chart DOM 的引用
|
||||||
|
const chartRef = ref(null);
|
||||||
|
|
||||||
|
// 初始化图表并设置配置
|
||||||
|
onMounted(() => {
|
||||||
|
const chart = echarts.init(chartRef.value); // 初始化图表
|
||||||
|
|
||||||
|
const option = {
|
||||||
|
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ['发电机1', '发电机2'],
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: false,
|
||||||
|
data: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'],
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
min: 10,
|
||||||
|
max: 20,
|
||||||
|
interval: 2,
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '发电机1',
|
||||||
|
type: 'line',
|
||||||
|
data: [14, 16, 14, 15, 16, 14, 16, 15, 16, 17, 16],
|
||||||
|
smooth: true,
|
||||||
|
color: '#3366FF',
|
||||||
|
areaStyle: {
|
||||||
|
opacity: 0.2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '发电机2',
|
||||||
|
type: 'line',
|
||||||
|
data: [16, 17, 15, 16, 18, 16, 17, 17, 18, 19, 18],
|
||||||
|
smooth: true,
|
||||||
|
color: '#FFCC00',
|
||||||
|
areaStyle: {
|
||||||
|
opacity: 0.2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// 设置图表的配置
|
||||||
|
chart.setOption(option);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* Optional styling */
|
||||||
|
</style>
|
||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-card>
|
<el-card style="width: 100%;">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="top">
|
<div class="top">
|
||||||
@ -31,7 +31,7 @@
|
|||||||
<img src="/assets/demo/sb2.png" alt="">
|
<img src="/assets/demo/sb2.png" alt="">
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<p class="t1">128小时</p>
|
<p class="t1" style="font-size: 21px;">128小时</p>
|
||||||
<p class="t2">运行时长</p>
|
<p class="t2">运行时长</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -99,9 +99,8 @@
|
|||||||
<span class="t2">(30 days)</span>
|
<span class="t2">(30 days)</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="back">
|
<div class="item day">
|
||||||
<span>34522天</span>
|
<span class="text">34522天</span>
|
||||||
<span>已安全运行</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
@ -113,14 +112,40 @@
|
|||||||
|
|
||||||
.container {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-around;
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.day {
|
||||||
|
flex: 1.5 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
background-color: transparent !important;
|
||||||
|
background-image: url('/assets/demo/dayImg.png');
|
||||||
|
background-size: contain;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 100% 50%;
|
||||||
|
position: relative;
|
||||||
|
width: 120px;
|
||||||
|
|
||||||
|
.text {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 60px;
|
||||||
|
color: rgba(24, 109, 245, 1);
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 25px;
|
||||||
|
margin-left: 10px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
background-color: rgba(240, 249, 255, 1);
|
background-color: rgba(240, 249, 255, 1);
|
||||||
padding: 20px 40px 20px 20px;
|
padding: 30px 15px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
flex: 1;
|
||||||
|
margin: 75px 0;
|
||||||
|
|
||||||
.top {
|
.top {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -177,8 +202,16 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.back {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
|
:deep(.el-card__body) {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|||||||
136
src/views/demo1/components/sjjk.vue
Normal file
136
src/views/demo1/components/sjjk.vue
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
<template>
|
||||||
|
<RightTitle subtitle="实时数据监控" icon="sjjk" />
|
||||||
|
|
||||||
|
<div class="sjjk-container">
|
||||||
|
<div class="chart-container">
|
||||||
|
<div id="chart" class="echarts-wrapper" style="width: 800px; height: 200px;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import RightTitle from './RightTitle.vue';
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
import { onMounted } from 'vue';
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 初始化图表
|
||||||
|
const myChart = echarts.init(document.getElementById('chart'));
|
||||||
|
|
||||||
|
// 图表配置项
|
||||||
|
const option = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'shadow',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ['电压(kv)', '电流(A)', '功率(MW)'],
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: '15%',
|
||||||
|
left: '12%',
|
||||||
|
right: '12%',
|
||||||
|
bottom: '20%',
|
||||||
|
containLabel: true,
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: ['发电机1', '发电机2', '发电机3', '发电机4', '发电机5', '发电机6'],
|
||||||
|
axisLabel: {
|
||||||
|
interval: 0,
|
||||||
|
rotate: 45
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
name: '电压(kv)/电流(A)',
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
name: '功率(MW)',
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '电压(kv)',
|
||||||
|
type: 'bar',
|
||||||
|
data: [80, 70, 55, 80, 80, 80],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '电流(A)',
|
||||||
|
type: 'bar',
|
||||||
|
data: [65, 80, 65, 65, 65, 65],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '功率(MW)',
|
||||||
|
type: 'bar',
|
||||||
|
yAxisIndex: 1,
|
||||||
|
data: [58, 80, 80, 58, 58, 58],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// 渲染图表
|
||||||
|
myChart.setOption(option);
|
||||||
|
|
||||||
|
// 窗口大小变化时,图表自适应
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
myChart.resize();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
:deep(.el-card__body) {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sjjk-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 8px;
|
||||||
|
/* padding: 20px; */
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 800px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 800px;
|
||||||
|
height: 400px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.echarts-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 400px;
|
||||||
|
border-radius: 4px;
|
||||||
|
/* box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -2,10 +2,26 @@
|
|||||||
<div style="padding: 20px;">
|
<div style="padding: 20px;">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="15">
|
<el-col :span="15">
|
||||||
|
<el-row>
|
||||||
<TitleComponent title="设备情况" subtitle="电站一次监控数据" />
|
<TitleComponent title="设备情况" subtitle="电站一次监控数据" />
|
||||||
<sbqk />
|
<sbqk />
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<TitleComponent title="电站一次系统图" subtitle="电站一次监控数据" />
|
||||||
|
<dzt />
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<TitleComponent title="运行步骤日志" subtitle="实时更新中" />
|
||||||
|
<!-- <sbqk /> -->
|
||||||
|
</el-row>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8" :push="1">
|
||||||
|
<TitleComponent title="运行步骤日志" subtitle="实时更新中" />
|
||||||
|
<el-card style="padding: 0;">
|
||||||
|
<sjjk />
|
||||||
|
<glsc />
|
||||||
|
<czzljl />
|
||||||
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
@ -19,5 +35,8 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import TitleComponent from '@/views/demo/components/TitleComponent.vue';
|
import TitleComponent from '@/views/demo/components/TitleComponent.vue';
|
||||||
import sbqk from './components/sbqk.vue';
|
import sbqk from './components/sbqk.vue';
|
||||||
|
import sjjk from './components/sjjk.vue';
|
||||||
|
import glsc from './components/glsc.vue';
|
||||||
|
import czzljl from './components/czzljl.vue';
|
||||||
|
import dzt from './components/dzt.vue';
|
||||||
</script>
|
</script>
|
||||||
Reference in New Issue
Block a user