514 lines
13 KiB
Markdown
514 lines
13 KiB
Markdown
# 视频监控改造 - 设计文档
|
||
|
||
## 1. 架构概述
|
||
### 1.1 系统架构图
|
||
```mermaid
|
||
flowchart TD
|
||
A[用户] --> B[VideoWall.vue]
|
||
B --> C[轮巡版块]
|
||
B --> D[追踪版块]
|
||
B --> E[特情版块]
|
||
C --> F[宫格布局]
|
||
D --> G[一主六副布局]
|
||
E --> H[左侧一主六副布局]
|
||
E --> I[右侧特情处置预案]
|
||
J[外部事件/API] --> B
|
||
B --> K[状态管理]
|
||
```
|
||
|
||
### 1.2 核心组件关系
|
||
| 组件名称 | 功能描述 | 依赖关系 |
|
||
|---------|---------|---------|
|
||
| VideoWall.vue | 视频监控主组件 | 轮巡版块、追踪版块、特情版块 |
|
||
| 轮巡版块 | 支持多种宫格排列方式 | 宫格布局组件 |
|
||
| 追踪版块 | 一主六副布局 | 视频画面组件 |
|
||
| 特情版块 | 左右分栏布局 | 视频画面组件、特情处置预案组件 |
|
||
| 宫格布局组件 | 动态宫格布局 | 视频画面组件 |
|
||
| 视频画面组件 | 显示监控画面 | 摄像头数据 |
|
||
| 特情处置预案组件 | 显示特情处置预案 | 预案数据 |
|
||
|
||
## 2. 核心组件设计
|
||
|
||
### 2.1 VideoWall.vue(视频监控主组件)
|
||
#### 2.1.1 功能设计
|
||
- **版块切换**:根据状态自动切换三个版块
|
||
- **状态管理**:管理视频监控系统的状态
|
||
- **事件处理**:处理外部事件和API调用
|
||
- **原有功能兼容**:保持原有视频墙的操作方式
|
||
|
||
#### 2.1.2 状态管理
|
||
```javascript
|
||
// 核心状态
|
||
const currentSection = ref('patrol') // 当前版块:patrol(轮巡), track(追踪), emergency(特情)
|
||
const selectedLayout = ref('3x3') // 轮巡版块的布局选择
|
||
const cameras = ref([]) // 摄像头列表
|
||
const emergencyPlan = ref({}) // 特情处置预案数据
|
||
```
|
||
|
||
#### 2.1.3 核心方法
|
||
```javascript
|
||
// 切换版块
|
||
const switchSection = (section) => {
|
||
currentSection.value = section
|
||
}
|
||
|
||
// 处理外部事件
|
||
const handleExternalEvent = (event) => {
|
||
if (event.type === 'abnormal') {
|
||
switchSection('track')
|
||
} else if (event.type === 'emergency') {
|
||
switchSection('emergency')
|
||
} else {
|
||
switchSection('patrol')
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2.2 轮巡版块设计
|
||
#### 2.2.1 功能设计
|
||
- **布局选择**:支持多种宫格排列方式(3x3, 3x4, 4x4, 5x5等)
|
||
- **视频显示**:根据选择的布局显示对应数量的视频画面
|
||
- **交互操作**:支持摄像头选择、控制等操作
|
||
|
||
#### 2.2.2 布局实现
|
||
```html
|
||
<!-- 轮巡版块布局 -->
|
||
<div class="patrol-section">
|
||
<div class="settings-bar">
|
||
<el-select v-model="selectedLayout" placeholder="选择视频墙布局" @change="handleLayoutChange">
|
||
<el-option label="3*3" value="3x3"></el-option>
|
||
<el-option label="3*4" value="3x4"></el-option>
|
||
<el-option label="4*4" value="4x4"></el-option>
|
||
<el-option label="5*5" value="5x5"></el-option>
|
||
</el-select>
|
||
</div>
|
||
|
||
<div class="video-grid" :class="`layout-${selectedLayout}`">
|
||
<div
|
||
v-for="(item, index) in getVideoCount()"
|
||
:key="index"
|
||
class="video-item"
|
||
@click="selectCamera(index)"
|
||
>
|
||
<div class="video-frame">
|
||
<!-- 视频画面 -->
|
||
<div class="video-placeholder">
|
||
<img :src="`/images/jiankong/${(index % 5) + 1}.jpg`" alt="监控画面" class="video-image">
|
||
<div class="video-name">摄像头 {{ index + 1 }}</div>
|
||
<div class="video-status">在线</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
### 2.3 追踪版块设计
|
||
#### 2.3.1 功能设计
|
||
- **一主六副布局**:主画面占较大比例,副画面占较小比例
|
||
- **视频显示**:显示7个视频画面
|
||
- **交互操作**:支持摄像头选择、控制等操作
|
||
|
||
#### 2.3.2 布局实现
|
||
```html
|
||
<!-- 追踪版块布局 -->
|
||
<div class="track-section">
|
||
<div class="main-sub-layout">
|
||
<!-- 主画面 -->
|
||
<div class="main-video">
|
||
<div class="video-frame" @click="selectMainCamera()">
|
||
<div class="video-placeholder">
|
||
<img src="/images/jiankong/1.jpg" alt="主监控画面" class="video-image">
|
||
<div class="video-name">主摄像头</div>
|
||
<div class="video-status">在线</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 副画面区域 -->
|
||
<div class="sub-videos">
|
||
<div
|
||
v-for="index in 6"
|
||
:key="`sub-${index}`"
|
||
class="sub-video"
|
||
>
|
||
<div class="video-frame" @click="selectSubCamera(index)">
|
||
<div class="video-placeholder">
|
||
<img :src="`/images/jiankong/${index + 1}.jpg`" alt="副监控画面" class="video-image">
|
||
<div class="video-name">副摄像头 {{ index }}</div>
|
||
<div class="video-status">在线</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
### 2.4 特情版块设计
|
||
#### 2.4.1 功能设计
|
||
- **左右分栏布局**:左侧70%显示监控画面,右侧30%显示特情处置预案
|
||
- **视频显示**:左侧显示一主六副监控画面
|
||
- **预案显示**:右侧显示特情处置预案
|
||
|
||
#### 2.4.2 布局实现
|
||
```html
|
||
<!-- 特情版块布局 -->
|
||
<div class="emergency-section">
|
||
<div class="emergency-layout">
|
||
<!-- 左侧监控区域(70%) -->
|
||
<div class="left-section">
|
||
<div class="main-sub-layout">
|
||
<!-- 主画面 -->
|
||
<div class="main-video">
|
||
<div class="video-frame" @click="selectMainCamera()">
|
||
<div class="video-placeholder">
|
||
<img src="/images/jiankong/1.jpg" alt="主监控画面" class="video-image">
|
||
<div class="video-name">主摄像头</div>
|
||
<div class="video-status">在线</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 副画面区域 -->
|
||
<div class="sub-videos">
|
||
<div
|
||
v-for="index in 6"
|
||
:key="`sub-${index}`"
|
||
class="sub-video"
|
||
>
|
||
<div class="video-frame" @click="selectSubCamera(index)">
|
||
<div class="video-placeholder">
|
||
<img :src="`/images/jiankong/${index + 1}.jpg`" alt="副监控画面" class="video-image">
|
||
<div class="video-name">副摄像头 {{ index }}</div>
|
||
<div class="video-status">在线</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 右侧预案区域(30%) -->
|
||
<div class="right-section">
|
||
<div class="emergency-plan">
|
||
<h3>特情处置预案</h3>
|
||
<div class="plan-content">
|
||
<h4>{{ emergencyPlan.title }}</h4>
|
||
<div class="plan-steps">
|
||
<div
|
||
v-for="(step, index) in emergencyPlan.steps"
|
||
:key="index"
|
||
class="plan-step"
|
||
>
|
||
<span class="step-number">{{ index + 1 }}</span>
|
||
<span class="step-content">{{ step }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
## 3. 自动切换逻辑设计
|
||
|
||
### 3.1 状态转换图
|
||
```mermaid
|
||
stateDiagram
|
||
[*] --> Patrol
|
||
Patrol --> Track : 异常事件
|
||
Track --> Patrol : 异常解除
|
||
Track --> Emergency : 特情事件
|
||
Emergency --> Patrol : 特情解除
|
||
Emergency --> Track : 特情降级为异常
|
||
```
|
||
|
||
### 3.2 状态转换条件
|
||
| 状态转换 | 触发条件 | 操作 |
|
||
|---------|---------|------|
|
||
| 轮巡 → 追踪 | 外部事件触发异常 | 切换到追踪版块 |
|
||
| 追踪 → 轮巡 | 异常解除 | 切换到轮巡版块 |
|
||
| 追踪 → 特情 | 外部事件触发特情 | 切换到特情版块 |
|
||
| 特情 → 轮巡 | 特情解除 | 切换到轮巡版块 |
|
||
| 特情 → 追踪 | 特情降级为异常 | 切换到追踪版块 |
|
||
|
||
### 3.3 事件处理机制
|
||
```javascript
|
||
// 处理外部事件
|
||
const handleExternalEvent = (event) => {
|
||
switch (event.type) {
|
||
case 'abnormal':
|
||
switchSection('track')
|
||
break
|
||
case 'emergency':
|
||
switchSection('emergency')
|
||
// 加载特情处置预案
|
||
loadEmergencyPlan(event.planId)
|
||
break
|
||
case 'normal':
|
||
switchSection('patrol')
|
||
break
|
||
case 'abnormal_resolved':
|
||
switchSection('patrol')
|
||
break
|
||
case 'emergency_resolved':
|
||
switchSection('patrol')
|
||
break
|
||
case 'emergency_to_abnormal':
|
||
switchSection('track')
|
||
break
|
||
default:
|
||
break
|
||
}
|
||
}
|
||
```
|
||
|
||
## 4. 样式设计
|
||
|
||
### 4.1 轮巡版块样式
|
||
```css
|
||
/* 轮巡版块容器 */
|
||
.patrol-section {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
/* 轮巡版块设置栏 */
|
||
.patrol-section .settings-bar {
|
||
padding: 10px 20px;
|
||
background-color: transparent;
|
||
border-bottom: 1px solid #e0e0e0;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
/* 轮巡版块视频网格 */
|
||
.patrol-section .video-grid {
|
||
flex: 1;
|
||
padding: 10px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 轮巡版块标准网格 */
|
||
.patrol-section .standard-grid {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
}
|
||
```
|
||
|
||
### 4.2 追踪版块样式
|
||
```css
|
||
/* 追踪版块容器 */
|
||
.track-section {
|
||
width: 100%;
|
||
height: 100%;
|
||
padding: 10px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 一主六副布局 */
|
||
.track-section .main-sub-layout {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
gap: 8px;
|
||
}
|
||
|
||
/* 主画面 */
|
||
.track-section .main-video {
|
||
width: 70%;
|
||
padding: 4px;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
/* 副画面区域 */
|
||
.track-section .sub-videos {
|
||
width: 30%;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
}
|
||
|
||
/* 副画面 */
|
||
.track-section .sub-video {
|
||
width: calc(50% - 4px);
|
||
padding: 4px;
|
||
box-sizing: border-box;
|
||
}
|
||
```
|
||
|
||
### 4.3 特情版块样式
|
||
```css
|
||
/* 特情版块容器 */
|
||
.emergency-section {
|
||
width: 100%;
|
||
height: 100%;
|
||
padding: 10px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 特情版块布局 */
|
||
.emergency-section .emergency-layout {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
gap: 8px;
|
||
}
|
||
|
||
/* 左侧监控区域 */
|
||
.emergency-section .left-section {
|
||
width: 70%;
|
||
height: 100%;
|
||
}
|
||
|
||
/* 右侧预案区域 */
|
||
.emergency-section .right-section {
|
||
width: 30%;
|
||
height: 100%;
|
||
background-color: #f0f2f5;
|
||
border-radius: 4px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 特情处置预案 */
|
||
.emergency-section .emergency-plan {
|
||
padding: 20px;
|
||
height: 100%;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
/* 预案内容 */
|
||
.emergency-section .plan-content {
|
||
margin-top: 15px;
|
||
}
|
||
|
||
/* 预案步骤 */
|
||
.emergency-section .plan-steps {
|
||
margin-top: 15px;
|
||
}
|
||
|
||
/* 预案步骤项 */
|
||
.emergency-section .plan-step {
|
||
margin-bottom: 10px;
|
||
display: flex;
|
||
align-items: flex-start;
|
||
}
|
||
|
||
/* 步骤编号 */
|
||
.emergency-section .step-number {
|
||
width: 24px;
|
||
height: 24px;
|
||
border-radius: 50%;
|
||
background-color: #1a73e8;
|
||
color: white;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-right: 10px;
|
||
font-size: 14px;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
/* 步骤内容 */
|
||
.emergency-section .step-content {
|
||
flex: 1;
|
||
font-size: 14px;
|
||
line-height: 1.5;
|
||
}
|
||
```
|
||
|
||
## 4. 数据结构设计
|
||
|
||
### 4.1 摄像头数据结构
|
||
```javascript
|
||
interface Camera {
|
||
id: string // 摄像头ID
|
||
name: string // 摄像头名称
|
||
status: 'online' | 'offline' // 摄像头状态
|
||
streamUrl?: string // 视频流URL
|
||
location?: string // 摄像头位置
|
||
}
|
||
```
|
||
|
||
### 4.2 特情处置预案数据结构
|
||
```javascript
|
||
interface EmergencyPlan {
|
||
id: string // 预案ID
|
||
title: string // 预案标题
|
||
description: string // 预案描述
|
||
steps: string[] // 预案步骤
|
||
priority: 'high' | 'medium' | 'low' // 预案优先级
|
||
}
|
||
```
|
||
|
||
### 4.3 外部事件数据结构
|
||
```javascript
|
||
interface ExternalEvent {
|
||
type: 'abnormal' | 'emergency' | 'normal' | 'abnormal_resolved' | 'emergency_resolved' | 'emergency_to_abnormal' // 事件类型
|
||
planId?: string // 特情预案ID
|
||
cameraId?: string // 关联摄像头ID
|
||
timestamp: number // 事件时间戳
|
||
}
|
||
```
|
||
|
||
## 5. 测试要点
|
||
|
||
### 5.1 轮巡版块测试
|
||
- 布局切换功能是否正常
|
||
- 视频画面显示是否正常
|
||
- 摄像头选择功能是否正常
|
||
|
||
### 5.2 追踪版块测试
|
||
- 一主六副布局是否正常
|
||
- 主画面和副画面比例是否协调
|
||
- 视频画面显示是否正常
|
||
|
||
### 5.3 特情版块测试
|
||
- 左右分栏布局是否正常(7:3比例)
|
||
- 左侧监控画面是否正常
|
||
- 右侧特情处置预案是否正常
|
||
|
||
### 5.4 自动切换逻辑测试
|
||
- 异常事件触发是否切换到追踪版块
|
||
- 特情事件触发是否切换到特情版块
|
||
- 正常事件触发是否切换到轮巡版块
|
||
- 状态转换是否流畅
|
||
|
||
### 5.5 边界情况测试
|
||
- 多个事件同时触发
|
||
- 事件频繁切换
|
||
- 长时间运行稳定性
|
||
|
||
## 6. 部署和维护
|
||
|
||
### 6.1 部署方式
|
||
- 使用现有Vite构建工具进行打包
|
||
- 部署到现有服务器
|
||
- 无需额外配置
|
||
|
||
### 6.2 维护要点
|
||
- 定期检查视频监控系统的状态
|
||
- 及时更新特情处置预案
|
||
- 监控系统性能,优化资源使用
|
||
- 定期测试自动切换逻辑
|
||
|
||
## 7. 后续扩展
|
||
|
||
### 7.1 功能扩展
|
||
- 支持手动切换版块
|
||
- 支持自定义布局
|
||
- 支持动态获取特情处置预案
|
||
- 支持视频回放功能
|
||
|
||
### 7.2 技术扩展
|
||
- 集成AI异常检测功能
|
||
- 支持更多视频流格式
|
||
- 实现视频画面智能分析
|
||
- 支持移动端访问 |