diff --git a/README.md b/README.md index 29e39b2..ec8f23f 100644 --- a/README.md +++ b/README.md @@ -267,6 +267,378 @@ export default router; ![image-20241031164625119](https://gitee.com/gonghao_git/draw-bed/raw/master/img/%E5%A4%A7%E5%B1%8F%E9%A1%B5%E9%9D%A2%E5%88%9D%E7%A8%BF-20241031164625119.png) + + + +## 告警规则设置 + + + +### 界面接口列表 + +- 获取所有摄像头信息 (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 { + 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 + +- 弹窗模式开关 + - 交互式开关(点击触发弹窗) + - 响应式开关(触发对话框) +- 弹窗现实 + - 格式化类型 + - 格式化时间 + - 现实时间 + - 弹窗布局调整 +- 控制台日志处理(部分) + + + + + + + + + + + + + + + + + + + + diff --git a/public/bg01.png b/public/bg01.png deleted file mode 100644 index 3eca95e..0000000 Binary files a/public/bg01.png and /dev/null differ diff --git a/public/login-bg.jpg b/public/login-bg.jpg deleted file mode 100644 index c9f972a..0000000 Binary files a/public/login-bg.jpg and /dev/null differ diff --git a/public/logo.png b/public/logo.png deleted file mode 100644 index fbebd5f..0000000 Binary files a/public/logo.png and /dev/null differ diff --git a/public/turing.png b/public/turing.png deleted file mode 100644 index f1ce7b9..0000000 Binary files a/public/turing.png and /dev/null differ diff --git a/src/components/AlertChart.vue b/src/components/AlertChart.vue index 58f215e..9140f06 100644 --- a/src/components/AlertChart.vue +++ b/src/components/AlertChart.vue @@ -35,6 +35,7 @@ import { BoxApi } from '@/utils/boxApi.ts'; import dayjs from 'dayjs'; import { debounce } from 'lodash'; + const activeName = ref('first'); const hourlyCounts = ref(Array(24).fill(0)); const dailyCounts = ref(Array(7).fill(0)); @@ -135,7 +136,7 @@ const updateCounts = async (range) => { timeAfter = dayjs().startOf('day').add(i, 'hour').format(); timeBefore = dayjs().startOf('day').add(i + 1, 'hour').format(); hourlyCounts.value[i] = await getEventCount(timeBefore, timeAfter); - console.log(`Hour ${i}: ${hourlyCounts.value[i]}`); + // console.log(`Hour ${i}: ${hourlyCounts.value[i]}`); } delayedInitChart(todayLineChartDom, createChartOption('今日告警趋势', Array.from({ length: 24 }, (_, i) => `${i}:00`), hourlyCounts.value)); diff --git a/src/components/Layout.vue b/src/components/Layout.vue index 0021c48..af8268f 100644 --- a/src/components/Layout.vue +++ b/src/components/Layout.vue @@ -3,7 +3,7 @@ @@ -36,13 +36,13 @@ - + + + + - + diff --git a/src/components/Max/CenterBottom.vue b/src/components/Max/CenterBottom.vue index 966afb3..c0f7efe 100644 --- a/src/components/Max/CenterBottom.vue +++ b/src/components/Max/CenterBottom.vue @@ -136,7 +136,7 @@ timeAfter = dayjs().startOf('day').add(i, 'hour').format(); timeBefore = dayjs().startOf('day').add(i + 1, 'hour').format(); hourlyCounts.value[i] = await getEventCount(timeBefore, timeAfter); - console.log(`Hour ${i}: ${hourlyCounts.value[i]}`); + // console.log(`Hour ${i}: ${hourlyCounts.value[i]}`); } delayedInitChart(todayLineChartDom, createChartOption('今日告警趋势', Array.from({ length: 24 }, (_, i) => `${i}:00`), hourlyCounts.value)); diff --git a/src/components/Max/CenterTop.vue b/src/components/Max/CenterTop.vue index 55491c7..57bb2bb 100644 --- a/src/components/Max/CenterTop.vue +++ b/src/components/Max/CenterTop.vue @@ -1,347 +1,356 @@ - - - onBeforeUnmount(() => { - selectedCameras.value.forEach(camera => { - if (camera.player) { - camera.player.destroy(); - } - }); - }); - - - \ No newline at end of file diff --git a/src/components/Max/LeftBottom.vue b/src/components/Max/LeftBottom.vue index d9194c5..80d3307 100644 --- a/src/components/Max/LeftBottom.vue +++ b/src/components/Max/LeftBottom.vue @@ -13,7 +13,7 @@ - +
@@ -51,28 +51,25 @@
--> - + - +
- - - - - - + \ No newline at end of file diff --git a/src/components/Statistics.vue b/src/components/Statistics.vue index 45c014b..3a776cb 100644 --- a/src/components/Statistics.vue +++ b/src/components/Statistics.vue @@ -1,204 +1,310 @@ diff --git a/src/html/AlertManagement.vue b/src/html/AlertManagement.vue index 05cdc6a..5157433 100644 --- a/src/html/AlertManagement.vue +++ b/src/html/AlertManagement.vue @@ -14,7 +14,7 @@ --> - + @@ -22,14 +22,14 @@ - + - + @@ -38,29 +38,36 @@ - + - + - + 查询 重置 {{ isExporting ? '正在导出,请勿重复点击' : '导出' }} + + + 批量标记为已处理 + +
- + +