添加环境监控页面 和 环境预警页面设置

master
lynn 8 months ago
parent 0a2fac6cdb
commit 35d3c17be3

@ -1,24 +1,257 @@
<template>
<div class="container">
<div style="padding: 0px 20px">
<el-image
style="width: 100%"
:src="require('/src/assets/monitor.png')"
fit="fill"></el-image>
<!-- <div ref="lxHeader">
<lx-header icon="md-apps" text="环境监控" style="margin-bottom: 10px; border: 0px; margin-top: 15px">
<div slot="content"></div>
<slot>
</slot>
</lx-header>
</div> -->
<div class="monitor-container">
<!-- Camera Section -->
<el-row :gutter="20" class="camera-section">
<el-col :span="8" v-for="camera in cameras" :key="camera.id">
<el-card shadow="never">
<div slot="header" class="clearfix">
<span>{{ camera.name }}</span>
<el-button style="float: right; padding: 3px 0" type="text" :class="camera.status === '离线' ? 'offline' : ''">{{ camera.status }}</el-button>
</div>
<div class="camera-body">
<el-image
style="width: 100%; height: 180px; background-color: #000; display: flex; align-items: center; justify-content: center;"
:src="camera.image"
fit="cover">
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline" style="font-size: 40px; color: #ccc;"></i>
<div style="color: #ccc;">EZVIZ</div>
</div>
<div slot="placeholder" class="image-slot">
<i class="el-icon-loading" style="font-size: 40px; color: #ccc;"></i>
</div>
</el-image>
<div class="camera-info">视频通道: {{ camera.channel }}</div>
</div>
</el-card>
</el-col>
</el-row>
<!-- Environment Section -->
<div class="environment-section">
<h3 class="section-title">环境信息</h3>
<el-row :gutter="20">
<el-col :span="8" v-for="point in environmentPoints" :key="point.id">
<el-card shadow="never" :body-style="{ padding: '0px' }">
<div class="environment-card" :class="getCardClass(point.status)">
<div class="env-header">
<span>{{ point.name }}</span>
<el-tag size="small" :type="getTagType(point.status)" effect="dark" class="status-tag">
<i v-if="point.status === '正常'" class="el-icon-success" style="margin-right: 4px;"></i>
{{ point.status }}
</el-tag>
</div>
<el-row class="env-data">
<el-col :span="12">
<div class="data-item">
<div class="label">CO浓度</div>
<div class="value" :class="point.status === '预警' ? 'warning-value' : ''">{{ point.coConcentration }}</div>
</div>
</el-col>
<el-col :span="12">
<div class="data-item">
<div class="label">温度</div>
<div class="value">{{ point.temperature }}</div>
</div>
</el-col>
</el-row>
<el-row class="env-data">
<el-col :span="12">
<div class="data-item">
<div class="label">湿度</div>
<div class="value">{{ point.humidity }}</div>
</div>
</el-col>
<el-col :span="12">
<div class="data-item">
<div class="label">更新时间</div>
<div class="value date">{{ point.updateTime }}</div>
</div>
</el-col>
</el-row>
</div>
</el-card>
</el-col>
</el-row>
</div>
</div>
</template>
<script>
export default {
name: 'MonitorPage',
data() {
return {
cameras: [
{
id: 1,
name: '摄像头1',
status: '离线',
image: 'https://img.freepik.com/free-vector/cctv-surveillance-system-concept_23-2148529272.jpg',
channel: '[DS-2CD2225XM-LGLSE(AE1005192)- AE1005192]'
},
{
id: 2,
name: '摄像头2',
status: '离线',
image: 'https://img.freepik.com/premium-photo/security-camera-perspective-hallway-corridor-monitoring-space-3d-rendering_172660-215.jpg',
channel: '[DS-2CD2225XM-LGLSE(AE1005068)- AE1005068]'
},
{
id: 3,
name: '摄像头3',
status: '离线',
image: 'https://img.freepik.com/premium-photo/video-surveillance-camera-record-street-cctv-camera-work-building_169016-21553.jpg',
channel: '[DS-2CD2225XM-LGLSE(AE1005197)- AE1005197]'
}
],
environmentPoints: [
{ id: 'A', name: '监控点 A', status: '正常', coConcentration: '2.5 ppm', temperature: '24.5 ℃', humidity: '45 %', updateTime: '2024-01-05' },
{ id: 'B', name: '监控点 B', status: '预警', coConcentration: '8.2 ppm', temperature: '26.8 ℃', humidity: '52 %', updateTime: '2024-01-05' },
{ id: 'C', name: '监控点 C', status: '正常', coConcentration: '1.8 ppm', temperature: '23.9 ℃', humidity: '48 %', updateTime: '2024-01-05' }
]
};
},
methods: {
getCardClass(status) {
if (status === '正常') {
// Assuming the green normal status is also '' based on context,
// We check the ID for C to apply green, otherwise blue
// Or better, add a specific status like 'Normal-Green' if data allows
return 'status-normal-blue'; // Default blue for ''
// For point C, if we assume its status implies green:
// return pointId === 'C' ? 'status-normal-green' : 'status-normal-blue';
} else if (status === '预警') {
return 'status-warning';
}
return '';
},
getTagType(status) {
if (status === '正常') return 'success'; // Element UI tag type for green/blue normal
if (status === '预警') return 'warning'; // Element UI tag type for yellow warning
return 'info'; // Default
}
}
};
</script>
<style>
<style lang="scss" scoped>
.monitor-container {
padding: 20px;
background-color: #f5f7fa; // Light background for the whole page
}
.camera-section {
margin-bottom: 30px;
}
.el-card {
border: none; // Remove default card border if desired
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
}
.clearfix:after {
clear: both
}
.camera-body {
text-align: center;
.el-image {
margin-bottom: 10px;
border-radius: 4px;
overflow: hidden;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
.image-slot {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
}
}
.camera-info {
font-size: 12px;
color: #999;
margin-top: 5px;
word-break: break-all;
text-align: left;
padding: 0 5px;
}
}
.offline {
color: #F56C6C; // Style for offline button
}
.environment-section {
.section-title {
font-size: 16px;
font-weight: bold;
margin-bottom: 15px;
color: #303133;
}
}
.environment-card {
padding: 15px;
color: #fff; // Default text color for cards
&.status-normal-blue {
background-color: #409EFF; // Blue for normal status
}
&.status-warning {
background-color: #E6A23C; // Yellow for warning status
}
&.status-normal-green { // Assuming point C has a distinct 'green normal' status
background-color: #67C23A; // Green for normal status
}
.env-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
font-size: 16px;
font-weight: bold;
.status-tag {
border-radius: 10px; // Make tag more pill-shaped
border: none;
// Match background to card, or use Element UI types
&.el-tag--success { background-color: rgba(255, 255, 255, 0.2); color: #fff;}
&.el-tag--warning { background-color: rgba(255, 255, 255, 0.2); color: #fff;}
}
}
.env-data {
margin-bottom: 10px; // Space between data rows
&:last-child {
margin-bottom: 0;
}
.data-item {
.label {
font-size: 13px;
color: rgba(255, 255, 255, 0.8); // Lighter label color
margin-bottom: 5px;
}
.value {
font-size: 20px;
font-weight: bold;
&.warning-value {
color: #fdf6ec; // Slightly different color for warning value if needed
}
&.date {
font-size: 14px; // Smaller font for date
font-weight: normal;
}
}
}
}
}
</style>

@ -0,0 +1,253 @@
<template>
<div class="warning-setting-container">
<el-card class="setting-card">
<div slot="header" class="clearfix">
<span>监控设置</span>
</div>
<!-- 监控点配置 -->
<el-form ref="monitorForm" :model="monitorPoints" label-width="120px">
<div v-for="(point, index) in monitorPoints" :key="`point-${index}`" class="monitor-point-config">
<div class="point-header">监控点 {{ point.name }}</div>
<!-- 视频配置 -->
<el-form-item :label="`摄像头地址`">
<el-input v-model="point.videoUrl" placeholder="请输入摄像头视频流地址"></el-input>
</el-form-item>
<el-form-item label="摄像头名称">
<el-input v-model="point.videoName" placeholder="请输入摄像头名称"></el-input>
</el-form-item>
<!-- 环境监测阈值 -->
<el-divider content-position="left">环境监测阈值</el-divider>
<el-form-item label="CO浓度阈值(ppm)">
<el-input-number
v-model="point.coThreshold"
:min="0"
:max="50"
:step="0.1"
:precision="1"
controls-position="right">
</el-input-number>
<span class="description">超过此值将触发预警</span>
</el-form-item>
<el-form-item label="温度阈值(℃)">
<el-row>
<el-col :span="11">
<el-input-number
v-model="point.tempMinThreshold"
:min="-20"
:max="50"
controls-position="right">
</el-input-number>
<span class="threshold-label">最低温度</span>
</el-col>
<el-col :span="11" :offset="2">
<el-input-number
v-model="point.tempMaxThreshold"
:min="0"
:max="100"
controls-position="right">
</el-input-number>
<span class="threshold-label">最高温度</span>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="湿度阈值(%)">
<el-row>
<el-col :span="11">
<el-input-number
v-model="point.humidityMinThreshold"
:min="0"
:max="100"
controls-position="right">
</el-input-number>
<span class="threshold-label">最低湿度</span>
</el-col>
<el-col :span="11" :offset="2">
<el-input-number
v-model="point.humidityMaxThreshold"
:min="0"
:max="100"
controls-position="right">
</el-input-number>
<span class="threshold-label">最高湿度</span>
</el-col>
</el-row>
</el-form-item>
</div>
</el-form>
<!-- 预警接收设置 -->
<div class="section-title">预警接收设置</div>
<el-form ref="warningForm" :model="warningForm" label-width="120px">
<el-form-item label="预警手机号">
<el-input v-model="warningForm.phoneNumber" placeholder="请输入接收预警信息的手机号">
<template slot="append">
<el-button @click="addReceiver"></el-button>
</template>
</el-input>
</el-form-item>
<el-table
v-if="warningForm.receivers.length > 0"
:data="warningForm.receivers"
style="width: 100%; margin-top: 10px;">
<el-table-column label="序号" type="index" width="50"></el-table-column>
<el-table-column prop="phone" label="手机号"></el-table-column>
<el-table-column prop="name" label="联系人"></el-table-column>
<el-table-column label="操作" width="120">
<template slot-scope="scope">
<el-button
type="text"
size="small"
@click="removeReceiver(scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-form>
<el-form-item>
<el-button type="primary" @click="saveSettings"></el-button>
<el-button @click="resetForm"></el-button>
</el-form-item>
</el-card>
</div>
</template>
<script>
export default {
name: 'WarningSetting',
data() {
return {
monitorPoints: [
{
name: 'A',
videoName: '摄像头1',
videoUrl: 'ezopen://open.ys7.com/203751922/1.cga',
coThreshold: 5.0,
tempMinThreshold: 15,
tempMaxThreshold: 30,
humidityMinThreshold: 30,
humidityMaxThreshold: 70
},
{
name: 'B',
videoName: '摄像头2',
videoUrl: 'ezopen://open.ys7.com/F59651352/1.cga',
coThreshold: 5.0,
tempMinThreshold: 15,
tempMaxThreshold: 30,
humidityMinThreshold: 30,
humidityMaxThreshold: 70
},
{
name: 'C',
videoName: '摄像头3',
videoUrl: 'ezopen://open.ys7.com/G39410642/1.cga',
coThreshold: 5.0,
tempMinThreshold: 15,
tempMaxThreshold: 30,
humidityMinThreshold: 30,
humidityMaxThreshold: 70
}
],
warningForm: {
phoneNumber: '',
receivers: [
{ phone: '13800138000', name: '张三' },
{ phone: '13900139000', name: '李四' }
]
}
};
},
methods: {
addReceiver() {
if (!this.warningForm.phoneNumber) {
this.$message.warning('请输入手机号');
return;
}
//
const phoneReg = /^1[3-9]\d{9}$/;
if (!phoneReg.test(this.warningForm.phoneNumber)) {
this.$message.error('请输入正确的手机号格式');
return;
}
this.warningForm.receivers.push({
phone: this.warningForm.phoneNumber,
name: '联系人' + (this.warningForm.receivers.length + 1)
});
this.warningForm.phoneNumber = '';
},
removeReceiver(index) {
this.warningForm.receivers.splice(index, 1);
},
saveSettings() {
// API
console.log('Monitor point settings:', this.monitorPoints);
console.log('Warning receivers:', this.warningForm.receivers);
this.$message({
message: '设置保存成功',
type: 'success'
});
},
resetForm() {
//
this.$refs.monitorForm && this.$refs.monitorForm.resetFields();
this.$refs.warningForm && this.$refs.warningForm.resetFields();
}
}
};
</script>
<style lang="scss" scoped>
.warning-setting-container {
padding: 20px;
.setting-card {
margin-bottom: 20px;
}
.section-title {
font-size: 16px;
font-weight: bold;
padding: 10px 0;
margin: 15px 0 5px 0;
border-bottom: 1px solid #ebeef5;
}
.monitor-point-config {
background-color: #f9f9f9;
border-radius: 4px;
padding: 15px;
margin-bottom: 20px;
.point-header {
font-size: 16px;
font-weight: bold;
margin-bottom: 15px;
color: #409EFF;
}
}
.description {
margin-left: 10px;
color: #909399;
font-size: 12px;
}
.threshold-label {
margin-left: 5px;
color: #909399;
font-size: 12px;
}
}
</style>
Loading…
Cancel
Save