645 lines
14 KiB
Markdown
645 lines
14 KiB
Markdown
# local_alert
|
||
|
||
本地告警页面
|
||
=======
|
||
## Project Setup
|
||
|
||
```sh
|
||
npm install
|
||
```
|
||
|
||
### Compile and Hot-Reload for Development
|
||
|
||
```sh
|
||
npm run dev
|
||
```
|
||
|
||
### Type-Check, Compile and Minify for Production
|
||
|
||
```sh
|
||
npm run build
|
||
```
|
||
|
||
|
||
|
||
## 依赖包
|
||
|
||
```
|
||
"axios": "^1.7.3",
|
||
"echarts": "^5.5.1",
|
||
"element-plus": "^2.7.8",
|
||
"file-saver": "^2.0.5",
|
||
"http-proxy-middleware": "^3.0.0",
|
||
"jszip": "^3.10.1",
|
||
"qs": "^6.12.3",
|
||
"vue": "^3.4.29",
|
||
"vue-router": "^4.4.0"
|
||
```
|
||
|
||
> - axios:异步
|
||
> - echarts:图标盘
|
||
> - element-plus: 组件
|
||
> - file-saver: 文件加载
|
||
> - http-proxy-middleware: 请求跨域
|
||
> - jszip:下载打包
|
||
> - qs:静态资源请求
|
||
> - vue:框架
|
||
> - vue-router:路由
|
||
|
||
|
||
|
||
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
卷 文档 的文件夹 PATH 列表
|
||
卷序列号为 8BA4-D80A
|
||
D:\JAVA\DEMO\TURING\ALARM\ALARM_DEV\ALARM_MANAGERMENT
|
||
│ .gitignore
|
||
│ dist.zip
|
||
│ env.d.ts
|
||
│ index.html
|
||
│ package-lock.json
|
||
│ package.json
|
||
│ README.md
|
||
│ tree.txt
|
||
│ tsconfig.app.json
|
||
│ tsconfig.json
|
||
│ tsconfig.node.json
|
||
│ vite.config.ts
|
||
│ vite.config.ts.timestamp-1722563872625-dafa6df9d3ee1.mjs
|
||
│
|
||
├─.vscode
|
||
│ extensions.json
|
||
│
|
||
├─dist
|
||
│ │ icon.ico
|
||
│ │ index.html
|
||
│ │ login-bg.jpg
|
||
│ │ logo.png
|
||
│ │
|
||
│ └─assets
|
||
│ index-ChTHFsuW.css
|
||
│ index-DvIh3OSh.js
|
||
│
|
||
├─node_modules
|
||
│
|
||
├─public
|
||
│ icon.ico
|
||
│ login-bg.jpg
|
||
│ logo.png
|
||
│
|
||
└─src
|
||
│ App.vue
|
||
│ main.ts
|
||
│
|
||
├─components
|
||
│ DemoPart.vue
|
||
│ Layout.vue
|
||
│
|
||
├─html
|
||
│ DeepFlow.vue
|
||
│ DemoToHK.vue
|
||
│ Flow.vue
|
||
│ Login.vue
|
||
│ PassFlow.vue
|
||
│ Point.vue
|
||
│
|
||
├─router
|
||
│ index.ts
|
||
│
|
||
├─static
|
||
│ login-bg.jpg
|
||
│ logo.png
|
||
│
|
||
└─utils
|
||
axios-config.ts
|
||
misc.ts
|
||
store.ts
|
||
Superbox.ts
|
||
type.ts
|
||
```
|
||
|
||
|
||
|
||
## Src文件说明
|
||
|
||
### 目录分解
|
||
|
||
```
|
||
└─src
|
||
│ App.vue
|
||
│ main.ts
|
||
│
|
||
├─components
|
||
│ DemoPart.vue
|
||
│ Layout.vue
|
||
│
|
||
├─html
|
||
│ DeepFlow.vue
|
||
│ DemoToHK.vue
|
||
│ Flow.vue
|
||
│ Login.vue
|
||
│ PassFlow.vue
|
||
│ Point.vue
|
||
│
|
||
├─router
|
||
│ index.ts
|
||
│
|
||
├─static
|
||
│ login-bg.jpg
|
||
│ logo.png
|
||
│
|
||
└─utils
|
||
axios-config.ts
|
||
misc.ts
|
||
store.ts
|
||
Superbox.ts
|
||
type.ts
|
||
```
|
||
|
||
|
||
|
||
### 根目录
|
||
|
||
```
|
||
└─src
|
||
│ App.vue
|
||
│ main.ts
|
||
├─components
|
||
├─html
|
||
├─router
|
||
├─static
|
||
└─utils
|
||
```
|
||
|
||
#### App.vue(关键)
|
||
|
||
- 在index.html中可见
|
||
|
||
```
|
||
<div id="app"></div>
|
||
```
|
||
|
||
> 页面的app为页面主体框架结构,所有组件仿照类似嵌套方式申明和使用,其下囊括页面布局的其他页面和子页面组件
|
||
> 相当于整体布局的一个载体(根父组件)
|
||
|
||
```
|
||
<template>
|
||
<div id="app">
|
||
<router-view></router-view>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts">
|
||
import { provide } from 'vue';
|
||
|
||
export default {
|
||
name: 'App',
|
||
// setup() {
|
||
//定义响应式数据
|
||
// }
|
||
};
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* 添加你的样式 */
|
||
</style>
|
||
|
||
```
|
||
|
||
> 作为父页面,不可避免需要向其下子组件传递参数,可通过导入vue中的provide方法直接传递多层次的子组件信息,子组件inject获取信息,当然在vue3中数据的变化需要用reactive包裹数据,创建响应式变化。
|
||
|
||
|
||
|
||
#### main.ts(关键)
|
||
|
||
> 对于app组件的挂载和改改父组件的依赖使用和申明需要在这里定义使用,当一些新的外部组件引用逻辑正确但是显示异常,可检查是否在根文件中引用
|
||
|
||
|
||
|
||
### 路由(Route)
|
||
|
||
```
|
||
└─src
|
||
├─router
|
||
│ index.ts
|
||
```
|
||
|
||
- 看门狗(to,form,next)
|
||
|
||
```
|
||
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
|
||
const routes = [
|
||
{
|
||
path: '/',
|
||
name: '',
|
||
component: ,
|
||
children: []
|
||
|
||
}
|
||
const router = createRouter({
|
||
history: createWebHashHistory(),
|
||
routes
|
||
});
|
||
router.beforeEach((to, from, next) => {
|
||
const token = localStorage.getItem('token');
|
||
if (to.matched.some(record => record.meta.requiresAuth) && !token) {
|
||
next({ name: 'Login' });
|
||
} else {
|
||
next();
|
||
}
|
||
});
|
||
export default router;
|
||
|
||
|
||
```
|
||
|
||
|
||
|
||
|
||
|
||
## 本地告警首页ViewList布局
|
||
|
||

|
||
|
||
|
||
|
||

|
||
|
||
|
||
|
||
## 告警规则设置
|
||
|
||
|
||
|
||
### 界面接口列表
|
||
|
||
- 获取所有摄像头信息 (getAllCamera):/camera/cameras/get_all
|
||
- 通道流开启(startCameraStream):/camera/cameras/start_stream
|
||
- 通道流关闭(stopCameraStream):/camera/cameras/stop_stream
|
||
|
||
|
||
|
||
|
||
|
||
- 摄像实例
|
||
|
||
```
|
||
const cameraId = 1; // 示例摄像头 ID
|
||
const token = "your-auth-token";
|
||
const cameraJson = {
|
||
"id": 1,
|
||
"name": "421枪机",
|
||
"uri": "rtsp://admin:1234qwer@192.168.28.102:554/Streaming/Channels/202",
|
||
"mode": "on",
|
||
"status": "online",
|
||
"detect_params": { "threshold": 0.5 },
|
||
"default_params": {},
|
||
"should_push": false,
|
||
"config_params": {},
|
||
"sampling": false,
|
||
"note": {},
|
||
"snapshot": "http://127.0.0.1:8000/media/cameras/1/snapshot.jpg",
|
||
"remote_id": -1,
|
||
"raw_address": "0b8342ec52e62d01dd3273f583d326ec",
|
||
"ip": "admin:1234qwer@192.168.28.102:554",
|
||
"port": 8082,
|
||
"rules": [] // 包含的 rules 会被排除
|
||
};
|
||
await apiInstance.updateCamera(token, cameraId, cameraJson);
|
||
|
||
```
|
||
|
||
|
||
|
||
- 规则实例
|
||
|
||
```
|
||
const cameraId = 1; // 示例摄像头 ID
|
||
const token = "your-auth-token";
|
||
const cameraJson = {
|
||
"id": 1,
|
||
"name": "421枪机",
|
||
"uri": "rtsp://admin:1234qwer@192.168.28.102:554/Streaming/Channels/202",
|
||
"mode": "on",
|
||
"status": "online",
|
||
"detect_params": { "threshold": 0.5 },
|
||
"default_params": {},
|
||
"should_push": false,
|
||
"config_params": {},
|
||
"sampling": false,
|
||
"note": {},
|
||
"snapshot": "http://127.0.0.1:8000/media/cameras/1/snapshot.jpg",
|
||
"remote_id": -1,
|
||
"raw_address": "0b8342ec52e62d01dd3273f583d326ec",
|
||
"ip": "admin:1234qwer@192.168.28.102:554",
|
||
"port": 8082,
|
||
"rules": [] // 包含的 rules 会被排除
|
||
};
|
||
await apiInstance.updateCamera(token, cameraId, cameraJson);
|
||
|
||
```
|
||
|
||
|
||
|
||
```
|
||
单条camera实例部分内容:
|
||
{
|
||
"id": 1,
|
||
"name": "421枪机",
|
||
|
||
"mode": "on",
|
||
|
||
|
||
"rules": [{规则1json数据},{规则2json数据}]
|
||
}
|
||
|
||
单条rule实例部分:
|
||
{
|
||
"id": 3,
|
||
"camera": 1,
|
||
"name": "人员逗留",
|
||
"mode": "schedule",
|
||
"algo": "personnel_staying",
|
||
"params": {},
|
||
"params_base": "",
|
||
"unique_id": "7ce99a51-0ee4-4251-a754-bd897d671303",
|
||
"event_types": {
|
||
"personnel_staying": "人员逗留"
|
||
},
|
||
"schedule": {
|
||
"type": "weekly",
|
||
"time_slots": [
|
||
[
|
||
5,
|
||
1415
|
||
]
|
||
],
|
||
"week_day": "Monday"
|
||
}
|
||
}
|
||
```
|
||
|
||
|
||
|
||
|
||
|
||
> 表单数据显示摄像id,name,mode对应的规则显示对应的id,name,mode,schedule
|
||
>
|
||
> 其中摄像mode有ON和OFF两种状态,规则中mode有On,OFF和schedule三中状态,规则模式只有在schedule状态才会显示schedule中内容type,
|
||
>
|
||
> schedule中type又分为每日daily和每周weekly两周状态,其中dayily直接设置,当日时间范围time_slots,weekly可选择周几week_day和对应当天的当日时间范围time_slots
|
||
>
|
||
> time_slots为两个数字,对应当天开始时间和结束时间,计算交互方式为选择时间点
|
||
>
|
||
> 几点几分,然后计算这个时间总计有多少分钟,例如1点10分对应数字为70
|
||
|
||
|
||
|
||
- 结果返回信息修改(用户提示信息)
|
||
|
||
```
|
||
public async updateRule(token: string | null = null, rules: RuleData[]): Promise<any[]> {
|
||
const results: any[] = [];
|
||
|
||
for (const rule of rules) {
|
||
const url = `${this.superRule}/${rule.id}`;
|
||
try {
|
||
const res = await this.axios.patch(url, rule, this._authHeader(token));
|
||
if (res.data.err.ec === 0) {
|
||
results.push({
|
||
success: true,
|
||
ruleId: rule.id,
|
||
data: res.data.ret,
|
||
});
|
||
} else {
|
||
results.push({
|
||
success: false,
|
||
ruleId: rule.id,
|
||
error: res.data.err.dm,
|
||
});
|
||
}
|
||
} catch (error: any) {
|
||
results.push({
|
||
success: false,
|
||
ruleId: rule.id,
|
||
error: error.message || '未知错误',
|
||
});
|
||
}
|
||
}
|
||
|
||
return results;
|
||
}
|
||
|
||
```
|
||
|
||
|
||
|
||
|
||
|
||
- 时间段设置
|
||
|
||
> 添加时间段schedule的设置,组件显示开始时间点和结束时间,数据格式化方式为将代表累计分钟的数字转换为时间点,每60分钟为1小时,数字范围在0到1440,实例[56,65]代表0:56到1:05,组件显示将数字组转换为时间段,请求时将组件时间段显示为数字组。
|
||
>
|
||
> 时间段结束时间点不能大于开始时间点,多时间段添加不能有重合部分。
|
||
>
|
||
> 设置规则,只有在rule.mode为schedule时才可设置时间段,携带参数日期类型和多个时间段数字组合,在未保存切换rule。mode模式时间段不会因为隐藏组件而清空数值,始终显示开始设定好的默认值,当提交时处于时间段模式至少得设置一个时间段数组否则无法保存,若处在schedule情况下保存,携带参数请求,若rule.mode处于on或者off,代表没有时间段设置,那么schedule下的所有参数及时原来有值,也需要伴随请求清空默认值。
|
||
|
||
|
||
|
||
> 重新修改这段CameraRule.vue代码, 1.在rule.mode为schedule模式添加时间段time_slots的组件,添加时间段类型,输入框值默认为daily,不可修改 2.开始时间和结束时间的组件,时间通过分钟数转换为格式化的时间(小时:分钟),有删除按钮可删除临时的时间段设置,使用数字范围(0-1440),单个时间点代表0点到设置的时间点累计的分钟数字 3.时间段的校验,结束时间不能小于开始时间,多时间段之间不能有重叠。 4.如果 rule.mode 为 schedule,则必须包含至少一个时间段,如果 rule.mode 是 on 或 off,清空所有时间段和时间段类型
|
||
|
||
|
||
|
||
|
||
|
||
- 静态数据实例
|
||
|
||
```
|
||
"camera": {
|
||
"id": 1,
|
||
"name": "421枪机",
|
||
"mode": "on",
|
||
"status": "online",
|
||
"rules": [
|
||
{
|
||
"id": 1,
|
||
|
||
"camera": 1,
|
||
"name": "入侵test2",
|
||
"mode": "schedule",
|
||
"algo": "intrude",
|
||
"schedule": {
|
||
"type": "daily",
|
||
"time_slots": [
|
||
[
|
||
118,
|
||
898
|
||
],
|
||
[
|
||
0,
|
||
60
|
||
]
|
||
]
|
||
},
|
||
},
|
||
{
|
||
"id": 3,
|
||
"camera": 1,
|
||
"name": "人员逗留",
|
||
"mode": "schedule",
|
||
"algo": "personnel_staying",
|
||
"schedule": {
|
||
"type": "daily",
|
||
"time_slots": [
|
||
[
|
||
180,
|
||
420
|
||
]
|
||
]
|
||
},
|
||
}
|
||
],
|
||
"snapshot": "http://192.168.28.33:8000/media/cameras/1/snapshot.jpg",
|
||
}
|
||
```
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
```
|
||
模拟静态数据实例,
|
||
"camera": {
|
||
"id": 1,
|
||
"name": "421枪机",
|
||
"mode": "on",
|
||
"status": "online",
|
||
"rules": [
|
||
{
|
||
"id": 1,
|
||
|
||
"camera": 1,
|
||
"name": "入侵test2",
|
||
"mode": "schedule",
|
||
"algo": "intrude",
|
||
"schedule": {
|
||
"type": "daily",
|
||
"time_slots": [
|
||
[
|
||
118,
|
||
898
|
||
],
|
||
[
|
||
0,
|
||
60
|
||
]
|
||
]
|
||
},
|
||
},
|
||
{
|
||
"id": 3,
|
||
"camera": 1,
|
||
"name": "人员逗留",
|
||
"mode": "schedule",
|
||
"algo": "personnel_staying",
|
||
"schedule": {
|
||
"type": "daily",
|
||
"time_slots": [
|
||
[
|
||
180,
|
||
420
|
||
]
|
||
]
|
||
},
|
||
}
|
||
],
|
||
"snapshot": "http://192.168.28.33:8000/media/cameras/1/snapshot.jpg",
|
||
}
|
||
读取显示rules中多条数据,每条rule中rule.mode对应el-radio三种状态,在rule.model为schedule时
|
||
```
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
## 日志
|
||
|
||
### 2024.11.21
|
||
|
||
- 本地打包
|
||
- 服务器页面备份
|
||
- 服务器迭代,覆盖
|
||
- 版本提交云端
|
||
|
||
- 更新内容
|
||
- 1.弹窗仅图片显示(AlertManagement,LeftBottom,App)
|
||
- 2.通道点播(Setting,Channel)
|
||
- 摄像列表
|
||
- 搜索/在线状态过滤
|
||
- 3.通道规则设置(Channel,CameraRules)
|
||
- 规则开关
|
||
- 时间设置
|
||
- 下阶段
|
||
- 1.弹窗模式按钮
|
||
- 交互式开关(已有,点击响应)
|
||
- 响应式开关(###)
|
||
- 2.光影效果
|
||
- 声音联动(提示音)
|
||
- 交互(首页)
|
||
- 3.用户设定不可更改项
|
||
- 测试调整(遗留代码冗余调整)
|
||
|
||
|
||
|
||
|
||
|
||
### 2024.11.22
|
||
|
||
- 弹窗模式开关
|
||
- 交互式开关(点击触发弹窗)
|
||
- 响应式开关(触发对话框)
|
||
- 弹窗现实
|
||
- 格式化类型
|
||
- 格式化时间
|
||
- 现实时间
|
||
- 弹窗布局调整
|
||
- 控制台日志处理(部分)
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|