|
|
|
|
@ -3,26 +3,33 @@
|
|
|
|
|
<!-- Camera Section -->
|
|
|
|
|
<el-row :gutter="20" class="camera-section">
|
|
|
|
|
<el-col v-for="camera in cameras" :key="camera.id" :span="8">
|
|
|
|
|
<el-card shadow="never">
|
|
|
|
|
<div slot="header" class="clearfix">
|
|
|
|
|
<el-card shadow="hover">
|
|
|
|
|
<div slot="header" class="clearfix" @click="handleCameraClick(camera.camera_url)">
|
|
|
|
|
<span>{{ camera.name }}</span>
|
|
|
|
|
<el-button style="float: right; padding: 3px 0" type="text" :class="camera.status === '离线' ? 'offline' : ''">{{ camera.status }}</el-button>
|
|
|
|
|
<!-- <el-button style="float: right; padding: 3px 0" type="text" :class="camera.status === '离线' ? 'offline' : ''">{{ camera.status }}</el-button> -->
|
|
|
|
|
</div>
|
|
|
|
|
<div class="camera-body">
|
|
|
|
|
<div class="camera-body" @click="handleCameraClick(camera.camera_url)">
|
|
|
|
|
<el-image
|
|
|
|
|
style="width: 100%; height: 180px; background-color: #000; display: flex; align-items: center; justify-content: center;"
|
|
|
|
|
:src="camera.image"
|
|
|
|
|
style="
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 180px;
|
|
|
|
|
background-color: #000;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
"
|
|
|
|
|
:src="camera.image?camera.image.url:''"
|
|
|
|
|
fit="cover"
|
|
|
|
|
>
|
|
|
|
|
<div slot="error" class="image-slot">
|
|
|
|
|
<i class="el-icon-picture-outline" style="font-size: 40px; color: #ccc;" />
|
|
|
|
|
<div style="color: #ccc;">EZVIZ</div>
|
|
|
|
|
<!-- <div slot="error" class="image-slot">
|
|
|
|
|
<i class="el-icon-picture-outline" style="font-size: 40px; color: #ccc" />
|
|
|
|
|
<div style="color: #ccc">EZVIZ</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div slot="placeholder" class="image-slot">
|
|
|
|
|
<i class="el-icon-loading" style="font-size: 40px; color: #ccc;" />
|
|
|
|
|
</div>
|
|
|
|
|
<i class="el-icon-loading" style="font-size: 40px; color: #ccc" />
|
|
|
|
|
</div> -->
|
|
|
|
|
</el-image>
|
|
|
|
|
<div class="camera-info">视频通道: {{ camera.channel }}</div>
|
|
|
|
|
<div class="camera-info">点击跳转:账号admin,密码abc125634</div>
|
|
|
|
|
</div>
|
|
|
|
|
</el-card>
|
|
|
|
|
</el-col>
|
|
|
|
|
@ -37,16 +44,27 @@
|
|
|
|
|
<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;" />
|
|
|
|
|
<!-- <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"
|
|
|
|
|
/>
|
|
|
|
|
{{ point.status }}
|
|
|
|
|
</el-tag>
|
|
|
|
|
</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 class="value" :class="point.status === '预警' ? 'warning-value' : ''">
|
|
|
|
|
{{ point.coConcentration }}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
@ -85,29 +103,7 @@ 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]'
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
cameras: [],
|
|
|
|
|
environmentPoints: []
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
@ -117,26 +113,48 @@ export default {
|
|
|
|
|
methods: {
|
|
|
|
|
async loadEnvironmentPoints() {
|
|
|
|
|
try {
|
|
|
|
|
const response = await getGasList()
|
|
|
|
|
const response = await getGasList({
|
|
|
|
|
// show_relation:['image']
|
|
|
|
|
})
|
|
|
|
|
const list = response.data ? response.data : []
|
|
|
|
|
console.log('原始数据:', list)
|
|
|
|
|
// 只保留node_id为1,3,5的
|
|
|
|
|
const wantedNodeIds = ['1', '3', '5']
|
|
|
|
|
const filtered = wantedNodeIds.map(nodeId => {
|
|
|
|
|
const group = list.filter(item => String(item.node_id) === nodeId)
|
|
|
|
|
if (group.length === 0) return null
|
|
|
|
|
group.sort((a, b) => new Date(b.update_time || b.created_at || 0) - new Date(a.update_time || a.created_at || 0))
|
|
|
|
|
return group[0]
|
|
|
|
|
}).filter(Boolean)
|
|
|
|
|
const filtered = wantedNodeIds
|
|
|
|
|
.map(nodeId => {
|
|
|
|
|
const group = list.filter(item => String(item.node_id) === nodeId)
|
|
|
|
|
if (group.length === 0) return null
|
|
|
|
|
group.sort(
|
|
|
|
|
(a, b) =>
|
|
|
|
|
new Date(b.record_time) -
|
|
|
|
|
new Date(a.record_time)
|
|
|
|
|
)
|
|
|
|
|
return group[0]
|
|
|
|
|
})
|
|
|
|
|
.filter(Boolean)
|
|
|
|
|
console.log('filtered:', filtered)
|
|
|
|
|
this.environmentPoints = filtered.map(item => ({
|
|
|
|
|
id: item.id,
|
|
|
|
|
name: item.gas_config && item.gas_config.name ? item.gas_config.name : `监控点${item.node_id}`,
|
|
|
|
|
name:
|
|
|
|
|
item.gas_config && item.gas_config.name
|
|
|
|
|
? item.gas_config.name
|
|
|
|
|
: `监控点${item.node_id}`,
|
|
|
|
|
status: item.status || '正常',
|
|
|
|
|
coConcentration: item.co_concentration != null && item.co_concentration !== '' ? `${item.co_concentration} ppm` : '-',
|
|
|
|
|
temperature: item.temperature != null && item.temperature !== '' ? `${item.temperature} ℃` : '-',
|
|
|
|
|
coConcentration:
|
|
|
|
|
item.co_concentration != null && item.co_concentration !== ''
|
|
|
|
|
? `${item.co_concentration} ppm`
|
|
|
|
|
: '-',
|
|
|
|
|
temperature:
|
|
|
|
|
item.temperature != null && item.temperature !== '' ? `${item.temperature} ℃` : '-',
|
|
|
|
|
humidity: item.humidity != null && item.humidity !== '' ? `${item.humidity} %` : '-',
|
|
|
|
|
updateTime: item.record_time || ''
|
|
|
|
|
}))
|
|
|
|
|
this.cameras = filtered.map(item => ({
|
|
|
|
|
id: item.id,
|
|
|
|
|
name: item.gas_config.camera_name,
|
|
|
|
|
camera_url: item.gas_config.camera_url,
|
|
|
|
|
image: item.gas_config.image
|
|
|
|
|
}))
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('环境检测数据获取失败:', error)
|
|
|
|
|
this.$message && this.$message.error('环境检测数据获取失败')
|
|
|
|
|
@ -154,6 +172,14 @@ export default {
|
|
|
|
|
if (status === '正常') return 'success'
|
|
|
|
|
if (status === '预警') return 'warning'
|
|
|
|
|
return 'info'
|
|
|
|
|
},
|
|
|
|
|
handleCameraClick(cameraUrl) {
|
|
|
|
|
// console.log(cameraUrl)
|
|
|
|
|
if (cameraUrl) {
|
|
|
|
|
window.open(cameraUrl, '_blank')
|
|
|
|
|
} else {
|
|
|
|
|
this.$message.error('摄像头URL为空')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -171,31 +197,32 @@ export default {
|
|
|
|
|
|
|
|
|
|
.el-card {
|
|
|
|
|
border: none; // Remove default card border if desired
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.clearfix:before,
|
|
|
|
|
.clearfix:after {
|
|
|
|
|
display: table;
|
|
|
|
|
content: "";
|
|
|
|
|
content: '';
|
|
|
|
|
}
|
|
|
|
|
.clearfix:after {
|
|
|
|
|
clear: both
|
|
|
|
|
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%;
|
|
|
|
|
}
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
|
|
|
.image-slot {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
height: 100%;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.camera-info {
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
@ -208,7 +235,7 @@ export default {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.offline {
|
|
|
|
|
color: #F56C6C; // Style for offline button
|
|
|
|
|
color: #f56c6c; // Style for offline button
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.environment-section {
|
|
|
|
|
@ -225,14 +252,15 @@ export default {
|
|
|
|
|
color: #fff; // Default text color for cards
|
|
|
|
|
|
|
|
|
|
&.status-normal-blue {
|
|
|
|
|
background-color: #409EFF; // Blue for normal status
|
|
|
|
|
background-color: #409eff; // Blue for normal status
|
|
|
|
|
}
|
|
|
|
|
&.status-warning {
|
|
|
|
|
background-color: #E6A23C; // Yellow for warning status
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
&.status-normal-green { // Assuming point C has a distinct 'green normal' status
|
|
|
|
|
background-color: #67C23A; // Green for normal status
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.env-header {
|
|
|
|
|
display: flex;
|
|
|
|
|
@ -246,8 +274,14 @@ export default {
|
|
|
|
|
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;}
|
|
|
|
|
&.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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -267,12 +301,12 @@ export default {
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
&.warning-value {
|
|
|
|
|
color: #fdf6ec; // Slightly different color for warning value if needed
|
|
|
|
|
color: #fdf6ec; // Slightly different color for warning value if needed
|
|
|
|
|
}
|
|
|
|
|
&.date {
|
|
|
|
|
font-size: 14px; // Smaller font for date
|
|
|
|
|
font-weight: normal;
|
|
|
|
|
}
|
|
|
|
|
&.date {
|
|
|
|
|
font-size: 14px; // Smaller font for date
|
|
|
|
|
font-weight: normal;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|