diff --git a/src/views/alarm/dangerAssessment/manage/list.vue b/src/views/alarm/dangerAssessment/manage/list.vue
index cb66292..110dcab 100644
--- a/src/views/alarm/dangerAssessment/manage/list.vue
+++ b/src/views/alarm/dangerAssessment/manage/list.vue
@@ -79,7 +79,7 @@
// 危险作业
const columnsWork: TableColumn[] = [
{ text: '所属单位', value: 'deptName', align: 'center' },
- { text: '危险作业', value: 'hazardousHork', align: 'center' },
+ { text: '危险作业', value: 'hazardousWork', align: 'center' },
{ text: '危险作业等级', value: 'workLevel', align: 'center' },
{ text: '主要危险描述', value: 'hazardousRemark', align: 'center' },
{ text: '相关部门', value: 'relevantDepartments', align: 'center' },
diff --git a/src/views/alarm/policyConfig/monitorPoint/drawArea.vue b/src/views/alarm/policyConfig/monitorPoint/drawArea.vue
index fdf9ea0..dee9056 100644
--- a/src/views/alarm/policyConfig/monitorPoint/drawArea.vue
+++ b/src/views/alarm/policyConfig/monitorPoint/drawArea.vue
@@ -41,11 +41,12 @@
ctx.lineTo(e.boundary[3].x, e.boundary[3].y)
}
// ctx.strokeStyle = e.pointColor
- ctx.strokeStyle = e.pointColor || '#3d7eff'
+ ctx.strokeStyle = e.pointColor || '#1aa034'
ctx.closePath()
- ctx.font = '13px Arial'
+ // ctx.font = `${window.localStorage.getItem('fontSize')} Arial` || '13px Arial'
+ ctx.font = `${window.localStorage.getItem('fontSize')} 微软雅黑` || '13px 微软雅黑'
// ctx.fillStyle = e.pointColor
- ctx.fillStyle = e.pointColor || '#3d7eff'
+ ctx.fillStyle = e.pointColor || '#1aa034'
// const minY = Math.min(e.boundary[0].y, e.boundary[1].y, e.boundary[2].y, e.boundary[3].y)
// const minX = Math.min(e.boundary[0].x, e.boundary[1].x, e.boundary[2].x, e.boundary[3].x)
const textX = e.boundary[0].x === 0 ? 0 : e.boundary[0].x + 3 > props.width - 60 ? props.width - 60 : e.boundary[0].x + 3
@@ -53,7 +54,7 @@
ctx.fillText(e.remark, textX, textY)
})
}
- ctx.lineWidth = 1
+ ctx.lineWidth = window.localStorage.getItem('lineWidth') || 2
ctx.stroke()
}
@@ -207,8 +208,8 @@
height: 10px;
position: absolute;
border-radius: 50%;
- background-color: #3d7eff;
- opacity: 0.5;
+ background-color: #1aa034;
+ opacity: 0.8;
top: 0;
left: 0;
z-index: 99;
@@ -222,7 +223,7 @@
height: 10px;
position: absolute;
border-radius: 50%;
- background-color: #3d7eff;
+ background-color: #1aa034;
opacity: 0.5;
top: 0;
left: 0;
diff --git a/src/views/alarm/policyConfig/monitorPoint/editDialog.vue b/src/views/alarm/policyConfig/monitorPoint/editDialog.vue
index 3cb33d1..9b80f6e 100644
--- a/src/views/alarm/policyConfig/monitorPoint/editDialog.vue
+++ b/src/views/alarm/policyConfig/monitorPoint/editDialog.vue
@@ -6,6 +6,7 @@
import type { FormInstance, FormRules } from 'element-plus'
import type { IForm, IList } from './monitorPoint-interface'
import drawArea from './drawArea.vue'
+import { createStream, sendHeart, stopStream } from '@/api/monitor/index-new-gm'
import type { TableColumn } from '@/components/NormalTable/table_interface'
import { isIp } from '@/utils/validate'
import { getMediaStream, getMediaToken } from '@/api/monitor/media'
@@ -14,7 +15,10 @@
const emits = defineEmits(['closeRefresh'])
const dialogStatus = ref('add')
const baseurl = ref(window.location.href.split('/#')[0])
+const timer = ref() // gm取流定时器
const dialogVisible = ref(false) // 弹窗显示隐藏
+const systemType = ref('') // 系统类别
+const currentStreamId = ref('') // 正在播的流的国标号
const mediaToken = ref('') // 流媒体token
const mediaUrl = ref('') // 流媒体url
const cameraIndexCode = ref('') // 设备国标号
@@ -291,6 +295,7 @@
// -----------------------------------初始化、关闭对话框相关-----------------------------------------
function initDialog(dialogstatus: string, row: any) {
+ systemType.value = window.localStorage.getItem('systemType') as string
dialogVisible.value = true
fetchEdgeDeviceList() // 获取边缘设备列表
fetchAlgorithmList() // 获取算法列表
@@ -357,14 +362,28 @@
dialogStatus.value = dialogstatus // 类型 新建add 编辑edit 详情detail
cameraIndexCode.value = row.cameraIndexCode || '' // 设备国标号
nvrIndexCode.value = row.nvrIndexCode || '' // nvr国标号
- if (cameraIndexCode.value && nvrIndexCode.value) {
+ if (systemType.value === 'sm' && cameraIndexCode.value && nvrIndexCode.value) { // 流媒体
fetchMediaStream(cameraIndexCode.value, nvrIndexCode.value)
}
+ if (systemType.value === 'gm' && cameraIndexCode.value) { // gm取流
+ playGmStream(cameraIndexCode.value)
+ }
btnLoading.value = false
}
// 关闭并刷新
function closeRefresh() {
+ if (systemType.value === 'gm') {
+ // 先停心跳
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+
+ // 播下一个流先停止上一个流
+ if (currentStreamId.value) {
+ handleStopStream(currentStreamId.value)
+ }
+ }
drawAreaRef.value.removeCanvas()
dialogVisible.value = false
mediaToken.value = '' // 流媒体token
@@ -413,7 +432,7 @@
formData.value.algoModelId = '' // 模型id
recognitionList.value = [] // 清空表格
}
-// ----------------------------------------------取流---------------------------------------------------------
+// ----------------------------------------------流媒体取流---------------------------------------------------------
// 拉取流--普通流
async function fetchMediaStream(deviceId: string, channelId: string) {
// 获取流媒体token
@@ -428,6 +447,68 @@
ElMessage.warning('设备未注册')
}
}
+// ----------------------------------------gm流---------------------------------------------------
+// 创建流
+async function fetchStream(deviceId: string) {
+ const res = await createStream(deviceId)
+ if (res && res.data) {
+ return {
+ url: res.data.url,
+ createStreamResponseId: res.data.id,
+ }
+ }
+ else {
+ ElMessage.warning('创建流失败!')
+ }
+}
+
+// 停止流
+async function handleStopStream(deviceId: string) {
+ const res = await stopStream(deviceId)
+ if (res.code !== 200) {
+ ElMessage.warning('停止流失败!')
+ }
+}
+
+// 发送心跳
+async function handleSendHeart(deviceId: string) {
+ const res = await sendHeart(deviceId)
+ if (res && res.data) {
+ if (`${res.data.status}` !== 'on') { // 停止状态
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+ }
+ }
+}
+
+// 播放流
+function playGmStream(cameraIndexCode: string) {
+ // 先停心跳
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+
+ // 播下一个流先停止上一个流
+ if (currentStreamId.value) {
+ handleStopStream(currentStreamId.value)
+ }
+ // 获取视频流接口
+ fetchStream(cameraIndexCode).then((res: any) => {
+ const { url, createStreamResponseId } = res
+ mediaUrl.value = `${url}?token=${window.localStorage.getItem('token')}`
+ // 记录正在播的流的国标号
+ currentStreamId.value = createStreamResponseId
+
+ // 发送心跳
+ timer.value = setInterval(() => {
+ handleSendHeart(createStreamResponseId)
+ }, Number(window.localStorage.getItem('timeGap')))
+ }).catch(() => {
+ ElMessage.warning('未获取到流!请联系管理员!')
+ })
+}
+// -----------------------------------------------------------------------------------------------
// ---------------------------------------------- 以下是暴露的方法内容 ---------------------------------------------------------
defineExpose({ initDialog })
@@ -642,5 +723,6 @@
margin: 0;
box-sizing: content-box;
position: relative;
+ background-color: #161616;
}
diff --git a/src/views/alarm/policyConfig/videoPreview/videoPreview.vue b/src/views/alarm/policyConfig/videoPreview/videoPreview.vue
index bfa7da7..a16585e 100644
--- a/src/views/alarm/policyConfig/videoPreview/videoPreview.vue
+++ b/src/views/alarm/policyConfig/videoPreview/videoPreview.vue
@@ -4,14 +4,18 @@
import { ElMessage, ElMessageBox } from 'element-plus'
import dayjs from 'dayjs'
import { getSecurityAlarmList } from '@/api/alarm/securityAlarm/securityAlarmList'
+import { createStream, sendHeart, stopStream } from '@/api/monitor/index-new-gm'
import { getMediaStream, getMediaToken } from '@/api/monitor/media'
import { videoTree } from '@/api/monitor/broadcast'
import drawArea from '@/views/alarm/policyConfig/monitorPoint/drawArea.vue'
+const timer = ref() // gm取流定时器
const router = useRouter()
const baseurl = ref(window.location.href.split('/#')[0])
const treeRef = ref(null) as any
const filterText = ref('')
+const systemType = ref('') // 系统类别
const data = ref([])
+const currentStreamId = ref('') // 正在播的流的国标号
const points = ref() // 标注信息
// const palyUrl = `${url}?token=${window.localStorage.getItem('token')}`
@@ -60,6 +64,7 @@
let treeClickCount = 0 // 用于双击事件判断
+// 双击树节点
function handleNodeClick(data: any, node: any, self: any) {
console.log('设备信息', data)
@@ -76,25 +81,32 @@
if (data.device.id === currentLeafId.value) {
return
}
- leafLoading.value = true
+ leafLoading.value = true // 叶子结点加载流的时候显示Loading图标
currentLeafId.value = data.device.id
currentData.value = data.device
title.value = data.device.monitorName.replace('-', ' - ')
+ // -------------------------------区域绘制----------------------------------------
if (data.device.deviceBoundaryDTOS && data.device.deviceBoundaryDTOS.length) {
draw(data.device.deviceBoundaryDTOS.filter((item: { boundary: string }) => item.boundary))
}
else {
points.value = []
}
+ // -------------------------------区域绘制----------------------------------------
if (radio.value === '1') { // 原始流
- // 获取原始流
- fetchMediaStream(data.device.cameraIndexCode, data.device.nvrIndexCode).then((res: any) => {
- leafLoading.value = false
- mediaUrl.value = res
- }).catch(() => {
- ElMessage.warning('未获取到流!请联系管理员!')
- leafLoading.value = false
- })
+ if (systemType.value === 'sm') { // 商米流媒体
+ // 获取原始流
+ fetchMediaStream(data.device.cameraIndexCode, data.device.nvrIndexCode).then((res: any) => {
+ leafLoading.value = false
+ mediaUrl.value = res
+ }).catch(() => {
+ ElMessage.warning('未获取到流!请联系管理员!')
+ leafLoading.value = false
+ })
+ }
+ else if (systemType.value === 'gm') { // 国米
+ playGmStream(data.device.cameraIndexCode)
+ }
}
else if (radio.value === '2') { // 识别流
mediaUrl.value = data.device.recognitionUrl
@@ -103,7 +115,8 @@
treeClickCount = now
}
-// 拉取流
+// ----------------------------------------流媒体---------------------------------------------------
+// 拉取流(流媒体)
async function fetchMediaStream(deviceId: string, channelId: string) {
loading.value = true
const res = await getMediaStream(deviceId, channelId, mediaToken.value)
@@ -115,6 +128,72 @@
ElMessage.warning('设备未注册')
}
}
+// ----------------------------------------gm流---------------------------------------------------
+// 创建流
+async function fetchStream(deviceId: string) {
+ loading.value = true
+ const res = await createStream(deviceId)
+ loading.value = false
+ if (res && res.data) {
+ return {
+ url: res.data.url,
+ createStreamResponseId: res.data.id,
+ }
+ }
+ else {
+ ElMessage.warning('创建流失败!')
+ }
+}
+
+// 停止流
+async function handleStopStream(deviceId: string) {
+ const res = await stopStream(deviceId)
+ if (res.code !== 200) {
+ ElMessage.warning('停止流失败!')
+ }
+}
+
+// 发送心跳
+async function handleSendHeart(deviceId: string) {
+ const res = await sendHeart(deviceId)
+ if (res && res.data) {
+ if (`${res.data.status}` !== 'on') { // 停止状态
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+ }
+ }
+}
+
+// 播放流
+function playGmStream(cameraIndexCode: string) {
+ // 先停心跳
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+
+ // 播下一个流先停止上一个流
+ if (currentStreamId.value) {
+ handleStopStream(currentStreamId.value)
+ }
+ // 获取视频流接口
+ fetchStream(cameraIndexCode).then((res: any) => {
+ leafLoading.value = false
+ const { url, createStreamResponseId } = res
+ mediaUrl.value = `${url}?token=${window.localStorage.getItem('token')}`
+ // 记录正在播的流的国标号
+ currentStreamId.value = createStreamResponseId
+
+ // 发送心跳
+ timer.value = setInterval(() => {
+ handleSendHeart(createStreamResponseId)
+ }, Number(window.localStorage.getItem('timeGap')))
+ }).catch(() => {
+ ElMessage.warning('未获取到流!请联系管理员!')
+ leafLoading.value = false
+ })
+}
+// -----------------------------------------------------------------------------------------------
// 获取当日报警数数据
const fetchAlarmData = () => {
@@ -145,17 +224,33 @@
points.value = [] // 清除标注信息
draw(currentData.value.deviceBoundaryDTOS.filter((item: { boundary: string }) => item.boundary))
if (val === '1') { // 原始流
- // 获取原始流
- leafLoading.value = true
- fetchMediaStream(currentData.value.cameraIndexCode, currentData.value.nvrIndexCode).then((res: any) => {
- leafLoading.value = false
- mediaUrl.value = res
- }).catch(() => {
- ElMessage.warning('未获取到流!请联系管理员!')
- leafLoading.value = false
- })
+ if (systemType.value === 'sm') { // 流媒体
+ // 获取原始流
+ leafLoading.value = true
+ fetchMediaStream(currentData.value.cameraIndexCode, currentData.value.nvrIndexCode).then((res: any) => {
+ leafLoading.value = false
+ mediaUrl.value = res
+ }).catch(() => {
+ ElMessage.warning('未获取到流!请联系管理员!')
+ leafLoading.value = false
+ })
+ }
+ else if (systemType.value === 'gm') { // 国米
+ playGmStream(currentData.value.cameraIndexCode)
+ }
}
else if (val === '2') { // 识别流
+ if (systemType.value === 'gm') { // gm切换识别流先清心跳和正在播放的流
+ // 先停心跳
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+
+ // 播下一个流先停止上一个流
+ if (currentStreamId.value) {
+ handleStopStream(currentStreamId.value)
+ }
+ }
mediaUrl.value = currentData.value.recognitionUrl
}
}
@@ -199,18 +294,32 @@
onBeforeUnmount(() => {
unwatch()
window.removeEventListener('resize', resize)
+ if (systemType.value === 'gm') {
+ // 先停心跳
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+
+ // 播下一个流先停止上一个流
+ if (currentStreamId.value) {
+ handleStopStream(currentStreamId.value)
+ }
+ }
})
onMounted(() => {
+ systemType.value = window.localStorage.getItem('systemType') as string
videoTree().then((response) => {
if (response.code === 200) {
data.value = response.data
}
})
- // 获取流媒体token
- getMediaToken().then((res: any) => {
- mediaToken.value = res.data
- })
+ if (systemType.value === 'sm') {
+ // 获取流媒体token
+ getMediaToken().then((res: any) => {
+ mediaToken.value = res.data
+ })
+ }
setTimeout(() => {
resize()
window.addEventListener('resize', resize)
@@ -285,7 +394,7 @@
-
+
-
- {{ userStore.name }}
+
-
-
+
+
diff --git a/src/views/alarm/dangerAssessment/manage/list.vue b/src/views/alarm/dangerAssessment/manage/list.vue
index cb66292..110dcab 100644
--- a/src/views/alarm/dangerAssessment/manage/list.vue
+++ b/src/views/alarm/dangerAssessment/manage/list.vue
@@ -79,7 +79,7 @@
// 危险作业
const columnsWork: TableColumn[] = [
{ text: '所属单位', value: 'deptName', align: 'center' },
- { text: '危险作业', value: 'hazardousHork', align: 'center' },
+ { text: '危险作业', value: 'hazardousWork', align: 'center' },
{ text: '危险作业等级', value: 'workLevel', align: 'center' },
{ text: '主要危险描述', value: 'hazardousRemark', align: 'center' },
{ text: '相关部门', value: 'relevantDepartments', align: 'center' },
diff --git a/src/views/alarm/policyConfig/monitorPoint/drawArea.vue b/src/views/alarm/policyConfig/monitorPoint/drawArea.vue
index fdf9ea0..dee9056 100644
--- a/src/views/alarm/policyConfig/monitorPoint/drawArea.vue
+++ b/src/views/alarm/policyConfig/monitorPoint/drawArea.vue
@@ -41,11 +41,12 @@
ctx.lineTo(e.boundary[3].x, e.boundary[3].y)
}
// ctx.strokeStyle = e.pointColor
- ctx.strokeStyle = e.pointColor || '#3d7eff'
+ ctx.strokeStyle = e.pointColor || '#1aa034'
ctx.closePath()
- ctx.font = '13px Arial'
+ // ctx.font = `${window.localStorage.getItem('fontSize')} Arial` || '13px Arial'
+ ctx.font = `${window.localStorage.getItem('fontSize')} 微软雅黑` || '13px 微软雅黑'
// ctx.fillStyle = e.pointColor
- ctx.fillStyle = e.pointColor || '#3d7eff'
+ ctx.fillStyle = e.pointColor || '#1aa034'
// const minY = Math.min(e.boundary[0].y, e.boundary[1].y, e.boundary[2].y, e.boundary[3].y)
// const minX = Math.min(e.boundary[0].x, e.boundary[1].x, e.boundary[2].x, e.boundary[3].x)
const textX = e.boundary[0].x === 0 ? 0 : e.boundary[0].x + 3 > props.width - 60 ? props.width - 60 : e.boundary[0].x + 3
@@ -53,7 +54,7 @@
ctx.fillText(e.remark, textX, textY)
})
}
- ctx.lineWidth = 1
+ ctx.lineWidth = window.localStorage.getItem('lineWidth') || 2
ctx.stroke()
}
@@ -207,8 +208,8 @@
height: 10px;
position: absolute;
border-radius: 50%;
- background-color: #3d7eff;
- opacity: 0.5;
+ background-color: #1aa034;
+ opacity: 0.8;
top: 0;
left: 0;
z-index: 99;
@@ -222,7 +223,7 @@
height: 10px;
position: absolute;
border-radius: 50%;
- background-color: #3d7eff;
+ background-color: #1aa034;
opacity: 0.5;
top: 0;
left: 0;
diff --git a/src/views/alarm/policyConfig/monitorPoint/editDialog.vue b/src/views/alarm/policyConfig/monitorPoint/editDialog.vue
index 3cb33d1..9b80f6e 100644
--- a/src/views/alarm/policyConfig/monitorPoint/editDialog.vue
+++ b/src/views/alarm/policyConfig/monitorPoint/editDialog.vue
@@ -6,6 +6,7 @@
import type { FormInstance, FormRules } from 'element-plus'
import type { IForm, IList } from './monitorPoint-interface'
import drawArea from './drawArea.vue'
+import { createStream, sendHeart, stopStream } from '@/api/monitor/index-new-gm'
import type { TableColumn } from '@/components/NormalTable/table_interface'
import { isIp } from '@/utils/validate'
import { getMediaStream, getMediaToken } from '@/api/monitor/media'
@@ -14,7 +15,10 @@
const emits = defineEmits(['closeRefresh'])
const dialogStatus = ref('add')
const baseurl = ref(window.location.href.split('/#')[0])
+const timer = ref() // gm取流定时器
const dialogVisible = ref(false) // 弹窗显示隐藏
+const systemType = ref('') // 系统类别
+const currentStreamId = ref('') // 正在播的流的国标号
const mediaToken = ref('') // 流媒体token
const mediaUrl = ref('') // 流媒体url
const cameraIndexCode = ref('') // 设备国标号
@@ -291,6 +295,7 @@
// -----------------------------------初始化、关闭对话框相关-----------------------------------------
function initDialog(dialogstatus: string, row: any) {
+ systemType.value = window.localStorage.getItem('systemType') as string
dialogVisible.value = true
fetchEdgeDeviceList() // 获取边缘设备列表
fetchAlgorithmList() // 获取算法列表
@@ -357,14 +362,28 @@
dialogStatus.value = dialogstatus // 类型 新建add 编辑edit 详情detail
cameraIndexCode.value = row.cameraIndexCode || '' // 设备国标号
nvrIndexCode.value = row.nvrIndexCode || '' // nvr国标号
- if (cameraIndexCode.value && nvrIndexCode.value) {
+ if (systemType.value === 'sm' && cameraIndexCode.value && nvrIndexCode.value) { // 流媒体
fetchMediaStream(cameraIndexCode.value, nvrIndexCode.value)
}
+ if (systemType.value === 'gm' && cameraIndexCode.value) { // gm取流
+ playGmStream(cameraIndexCode.value)
+ }
btnLoading.value = false
}
// 关闭并刷新
function closeRefresh() {
+ if (systemType.value === 'gm') {
+ // 先停心跳
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+
+ // 播下一个流先停止上一个流
+ if (currentStreamId.value) {
+ handleStopStream(currentStreamId.value)
+ }
+ }
drawAreaRef.value.removeCanvas()
dialogVisible.value = false
mediaToken.value = '' // 流媒体token
@@ -413,7 +432,7 @@
formData.value.algoModelId = '' // 模型id
recognitionList.value = [] // 清空表格
}
-// ----------------------------------------------取流---------------------------------------------------------
+// ----------------------------------------------流媒体取流---------------------------------------------------------
// 拉取流--普通流
async function fetchMediaStream(deviceId: string, channelId: string) {
// 获取流媒体token
@@ -428,6 +447,68 @@
ElMessage.warning('设备未注册')
}
}
+// ----------------------------------------gm流---------------------------------------------------
+// 创建流
+async function fetchStream(deviceId: string) {
+ const res = await createStream(deviceId)
+ if (res && res.data) {
+ return {
+ url: res.data.url,
+ createStreamResponseId: res.data.id,
+ }
+ }
+ else {
+ ElMessage.warning('创建流失败!')
+ }
+}
+
+// 停止流
+async function handleStopStream(deviceId: string) {
+ const res = await stopStream(deviceId)
+ if (res.code !== 200) {
+ ElMessage.warning('停止流失败!')
+ }
+}
+
+// 发送心跳
+async function handleSendHeart(deviceId: string) {
+ const res = await sendHeart(deviceId)
+ if (res && res.data) {
+ if (`${res.data.status}` !== 'on') { // 停止状态
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+ }
+ }
+}
+
+// 播放流
+function playGmStream(cameraIndexCode: string) {
+ // 先停心跳
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+
+ // 播下一个流先停止上一个流
+ if (currentStreamId.value) {
+ handleStopStream(currentStreamId.value)
+ }
+ // 获取视频流接口
+ fetchStream(cameraIndexCode).then((res: any) => {
+ const { url, createStreamResponseId } = res
+ mediaUrl.value = `${url}?token=${window.localStorage.getItem('token')}`
+ // 记录正在播的流的国标号
+ currentStreamId.value = createStreamResponseId
+
+ // 发送心跳
+ timer.value = setInterval(() => {
+ handleSendHeart(createStreamResponseId)
+ }, Number(window.localStorage.getItem('timeGap')))
+ }).catch(() => {
+ ElMessage.warning('未获取到流!请联系管理员!')
+ })
+}
+// -----------------------------------------------------------------------------------------------
// ---------------------------------------------- 以下是暴露的方法内容 ---------------------------------------------------------
defineExpose({ initDialog })
@@ -642,5 +723,6 @@
margin: 0;
box-sizing: content-box;
position: relative;
+ background-color: #161616;
}
diff --git a/src/views/alarm/policyConfig/videoPreview/videoPreview.vue b/src/views/alarm/policyConfig/videoPreview/videoPreview.vue
index bfa7da7..a16585e 100644
--- a/src/views/alarm/policyConfig/videoPreview/videoPreview.vue
+++ b/src/views/alarm/policyConfig/videoPreview/videoPreview.vue
@@ -4,14 +4,18 @@
import { ElMessage, ElMessageBox } from 'element-plus'
import dayjs from 'dayjs'
import { getSecurityAlarmList } from '@/api/alarm/securityAlarm/securityAlarmList'
+import { createStream, sendHeart, stopStream } from '@/api/monitor/index-new-gm'
import { getMediaStream, getMediaToken } from '@/api/monitor/media'
import { videoTree } from '@/api/monitor/broadcast'
import drawArea from '@/views/alarm/policyConfig/monitorPoint/drawArea.vue'
+const timer = ref() // gm取流定时器
const router = useRouter()
const baseurl = ref(window.location.href.split('/#')[0])
const treeRef = ref(null) as any
const filterText = ref('')
+const systemType = ref('') // 系统类别
const data = ref([])
+const currentStreamId = ref('') // 正在播的流的国标号
const points = ref() // 标注信息
// const palyUrl = `${url}?token=${window.localStorage.getItem('token')}`
@@ -60,6 +64,7 @@
let treeClickCount = 0 // 用于双击事件判断
+// 双击树节点
function handleNodeClick(data: any, node: any, self: any) {
console.log('设备信息', data)
@@ -76,25 +81,32 @@
if (data.device.id === currentLeafId.value) {
return
}
- leafLoading.value = true
+ leafLoading.value = true // 叶子结点加载流的时候显示Loading图标
currentLeafId.value = data.device.id
currentData.value = data.device
title.value = data.device.monitorName.replace('-', ' - ')
+ // -------------------------------区域绘制----------------------------------------
if (data.device.deviceBoundaryDTOS && data.device.deviceBoundaryDTOS.length) {
draw(data.device.deviceBoundaryDTOS.filter((item: { boundary: string }) => item.boundary))
}
else {
points.value = []
}
+ // -------------------------------区域绘制----------------------------------------
if (radio.value === '1') { // 原始流
- // 获取原始流
- fetchMediaStream(data.device.cameraIndexCode, data.device.nvrIndexCode).then((res: any) => {
- leafLoading.value = false
- mediaUrl.value = res
- }).catch(() => {
- ElMessage.warning('未获取到流!请联系管理员!')
- leafLoading.value = false
- })
+ if (systemType.value === 'sm') { // 商米流媒体
+ // 获取原始流
+ fetchMediaStream(data.device.cameraIndexCode, data.device.nvrIndexCode).then((res: any) => {
+ leafLoading.value = false
+ mediaUrl.value = res
+ }).catch(() => {
+ ElMessage.warning('未获取到流!请联系管理员!')
+ leafLoading.value = false
+ })
+ }
+ else if (systemType.value === 'gm') { // 国米
+ playGmStream(data.device.cameraIndexCode)
+ }
}
else if (radio.value === '2') { // 识别流
mediaUrl.value = data.device.recognitionUrl
@@ -103,7 +115,8 @@
treeClickCount = now
}
-// 拉取流
+// ----------------------------------------流媒体---------------------------------------------------
+// 拉取流(流媒体)
async function fetchMediaStream(deviceId: string, channelId: string) {
loading.value = true
const res = await getMediaStream(deviceId, channelId, mediaToken.value)
@@ -115,6 +128,72 @@
ElMessage.warning('设备未注册')
}
}
+// ----------------------------------------gm流---------------------------------------------------
+// 创建流
+async function fetchStream(deviceId: string) {
+ loading.value = true
+ const res = await createStream(deviceId)
+ loading.value = false
+ if (res && res.data) {
+ return {
+ url: res.data.url,
+ createStreamResponseId: res.data.id,
+ }
+ }
+ else {
+ ElMessage.warning('创建流失败!')
+ }
+}
+
+// 停止流
+async function handleStopStream(deviceId: string) {
+ const res = await stopStream(deviceId)
+ if (res.code !== 200) {
+ ElMessage.warning('停止流失败!')
+ }
+}
+
+// 发送心跳
+async function handleSendHeart(deviceId: string) {
+ const res = await sendHeart(deviceId)
+ if (res && res.data) {
+ if (`${res.data.status}` !== 'on') { // 停止状态
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+ }
+ }
+}
+
+// 播放流
+function playGmStream(cameraIndexCode: string) {
+ // 先停心跳
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+
+ // 播下一个流先停止上一个流
+ if (currentStreamId.value) {
+ handleStopStream(currentStreamId.value)
+ }
+ // 获取视频流接口
+ fetchStream(cameraIndexCode).then((res: any) => {
+ leafLoading.value = false
+ const { url, createStreamResponseId } = res
+ mediaUrl.value = `${url}?token=${window.localStorage.getItem('token')}`
+ // 记录正在播的流的国标号
+ currentStreamId.value = createStreamResponseId
+
+ // 发送心跳
+ timer.value = setInterval(() => {
+ handleSendHeart(createStreamResponseId)
+ }, Number(window.localStorage.getItem('timeGap')))
+ }).catch(() => {
+ ElMessage.warning('未获取到流!请联系管理员!')
+ leafLoading.value = false
+ })
+}
+// -----------------------------------------------------------------------------------------------
// 获取当日报警数数据
const fetchAlarmData = () => {
@@ -145,17 +224,33 @@
points.value = [] // 清除标注信息
draw(currentData.value.deviceBoundaryDTOS.filter((item: { boundary: string }) => item.boundary))
if (val === '1') { // 原始流
- // 获取原始流
- leafLoading.value = true
- fetchMediaStream(currentData.value.cameraIndexCode, currentData.value.nvrIndexCode).then((res: any) => {
- leafLoading.value = false
- mediaUrl.value = res
- }).catch(() => {
- ElMessage.warning('未获取到流!请联系管理员!')
- leafLoading.value = false
- })
+ if (systemType.value === 'sm') { // 流媒体
+ // 获取原始流
+ leafLoading.value = true
+ fetchMediaStream(currentData.value.cameraIndexCode, currentData.value.nvrIndexCode).then((res: any) => {
+ leafLoading.value = false
+ mediaUrl.value = res
+ }).catch(() => {
+ ElMessage.warning('未获取到流!请联系管理员!')
+ leafLoading.value = false
+ })
+ }
+ else if (systemType.value === 'gm') { // 国米
+ playGmStream(currentData.value.cameraIndexCode)
+ }
}
else if (val === '2') { // 识别流
+ if (systemType.value === 'gm') { // gm切换识别流先清心跳和正在播放的流
+ // 先停心跳
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+
+ // 播下一个流先停止上一个流
+ if (currentStreamId.value) {
+ handleStopStream(currentStreamId.value)
+ }
+ }
mediaUrl.value = currentData.value.recognitionUrl
}
}
@@ -199,18 +294,32 @@
onBeforeUnmount(() => {
unwatch()
window.removeEventListener('resize', resize)
+ if (systemType.value === 'gm') {
+ // 先停心跳
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+
+ // 播下一个流先停止上一个流
+ if (currentStreamId.value) {
+ handleStopStream(currentStreamId.value)
+ }
+ }
})
onMounted(() => {
+ systemType.value = window.localStorage.getItem('systemType') as string
videoTree().then((response) => {
if (response.code === 200) {
data.value = response.data
}
})
- // 获取流媒体token
- getMediaToken().then((res: any) => {
- mediaToken.value = res.data
- })
+ if (systemType.value === 'sm') {
+ // 获取流媒体token
+ getMediaToken().then((res: any) => {
+ mediaToken.value = res.data
+ })
+ }
setTimeout(() => {
resize()
window.addEventListener('resize', resize)
@@ -285,7 +394,7 @@
-
+
-
- {{ userStore.name }}
+
-
-
+
+
diff --git a/src/views/alarm/dangerAssessment/manage/list.vue b/src/views/alarm/dangerAssessment/manage/list.vue
index cb66292..110dcab 100644
--- a/src/views/alarm/dangerAssessment/manage/list.vue
+++ b/src/views/alarm/dangerAssessment/manage/list.vue
@@ -79,7 +79,7 @@
// 危险作业
const columnsWork: TableColumn[] = [
{ text: '所属单位', value: 'deptName', align: 'center' },
- { text: '危险作业', value: 'hazardousHork', align: 'center' },
+ { text: '危险作业', value: 'hazardousWork', align: 'center' },
{ text: '危险作业等级', value: 'workLevel', align: 'center' },
{ text: '主要危险描述', value: 'hazardousRemark', align: 'center' },
{ text: '相关部门', value: 'relevantDepartments', align: 'center' },
diff --git a/src/views/alarm/policyConfig/monitorPoint/drawArea.vue b/src/views/alarm/policyConfig/monitorPoint/drawArea.vue
index fdf9ea0..dee9056 100644
--- a/src/views/alarm/policyConfig/monitorPoint/drawArea.vue
+++ b/src/views/alarm/policyConfig/monitorPoint/drawArea.vue
@@ -41,11 +41,12 @@
ctx.lineTo(e.boundary[3].x, e.boundary[3].y)
}
// ctx.strokeStyle = e.pointColor
- ctx.strokeStyle = e.pointColor || '#3d7eff'
+ ctx.strokeStyle = e.pointColor || '#1aa034'
ctx.closePath()
- ctx.font = '13px Arial'
+ // ctx.font = `${window.localStorage.getItem('fontSize')} Arial` || '13px Arial'
+ ctx.font = `${window.localStorage.getItem('fontSize')} 微软雅黑` || '13px 微软雅黑'
// ctx.fillStyle = e.pointColor
- ctx.fillStyle = e.pointColor || '#3d7eff'
+ ctx.fillStyle = e.pointColor || '#1aa034'
// const minY = Math.min(e.boundary[0].y, e.boundary[1].y, e.boundary[2].y, e.boundary[3].y)
// const minX = Math.min(e.boundary[0].x, e.boundary[1].x, e.boundary[2].x, e.boundary[3].x)
const textX = e.boundary[0].x === 0 ? 0 : e.boundary[0].x + 3 > props.width - 60 ? props.width - 60 : e.boundary[0].x + 3
@@ -53,7 +54,7 @@
ctx.fillText(e.remark, textX, textY)
})
}
- ctx.lineWidth = 1
+ ctx.lineWidth = window.localStorage.getItem('lineWidth') || 2
ctx.stroke()
}
@@ -207,8 +208,8 @@
height: 10px;
position: absolute;
border-radius: 50%;
- background-color: #3d7eff;
- opacity: 0.5;
+ background-color: #1aa034;
+ opacity: 0.8;
top: 0;
left: 0;
z-index: 99;
@@ -222,7 +223,7 @@
height: 10px;
position: absolute;
border-radius: 50%;
- background-color: #3d7eff;
+ background-color: #1aa034;
opacity: 0.5;
top: 0;
left: 0;
diff --git a/src/views/alarm/policyConfig/monitorPoint/editDialog.vue b/src/views/alarm/policyConfig/monitorPoint/editDialog.vue
index 3cb33d1..9b80f6e 100644
--- a/src/views/alarm/policyConfig/monitorPoint/editDialog.vue
+++ b/src/views/alarm/policyConfig/monitorPoint/editDialog.vue
@@ -6,6 +6,7 @@
import type { FormInstance, FormRules } from 'element-plus'
import type { IForm, IList } from './monitorPoint-interface'
import drawArea from './drawArea.vue'
+import { createStream, sendHeart, stopStream } from '@/api/monitor/index-new-gm'
import type { TableColumn } from '@/components/NormalTable/table_interface'
import { isIp } from '@/utils/validate'
import { getMediaStream, getMediaToken } from '@/api/monitor/media'
@@ -14,7 +15,10 @@
const emits = defineEmits(['closeRefresh'])
const dialogStatus = ref('add')
const baseurl = ref(window.location.href.split('/#')[0])
+const timer = ref() // gm取流定时器
const dialogVisible = ref(false) // 弹窗显示隐藏
+const systemType = ref('') // 系统类别
+const currentStreamId = ref('') // 正在播的流的国标号
const mediaToken = ref('') // 流媒体token
const mediaUrl = ref('') // 流媒体url
const cameraIndexCode = ref('') // 设备国标号
@@ -291,6 +295,7 @@
// -----------------------------------初始化、关闭对话框相关-----------------------------------------
function initDialog(dialogstatus: string, row: any) {
+ systemType.value = window.localStorage.getItem('systemType') as string
dialogVisible.value = true
fetchEdgeDeviceList() // 获取边缘设备列表
fetchAlgorithmList() // 获取算法列表
@@ -357,14 +362,28 @@
dialogStatus.value = dialogstatus // 类型 新建add 编辑edit 详情detail
cameraIndexCode.value = row.cameraIndexCode || '' // 设备国标号
nvrIndexCode.value = row.nvrIndexCode || '' // nvr国标号
- if (cameraIndexCode.value && nvrIndexCode.value) {
+ if (systemType.value === 'sm' && cameraIndexCode.value && nvrIndexCode.value) { // 流媒体
fetchMediaStream(cameraIndexCode.value, nvrIndexCode.value)
}
+ if (systemType.value === 'gm' && cameraIndexCode.value) { // gm取流
+ playGmStream(cameraIndexCode.value)
+ }
btnLoading.value = false
}
// 关闭并刷新
function closeRefresh() {
+ if (systemType.value === 'gm') {
+ // 先停心跳
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+
+ // 播下一个流先停止上一个流
+ if (currentStreamId.value) {
+ handleStopStream(currentStreamId.value)
+ }
+ }
drawAreaRef.value.removeCanvas()
dialogVisible.value = false
mediaToken.value = '' // 流媒体token
@@ -413,7 +432,7 @@
formData.value.algoModelId = '' // 模型id
recognitionList.value = [] // 清空表格
}
-// ----------------------------------------------取流---------------------------------------------------------
+// ----------------------------------------------流媒体取流---------------------------------------------------------
// 拉取流--普通流
async function fetchMediaStream(deviceId: string, channelId: string) {
// 获取流媒体token
@@ -428,6 +447,68 @@
ElMessage.warning('设备未注册')
}
}
+// ----------------------------------------gm流---------------------------------------------------
+// 创建流
+async function fetchStream(deviceId: string) {
+ const res = await createStream(deviceId)
+ if (res && res.data) {
+ return {
+ url: res.data.url,
+ createStreamResponseId: res.data.id,
+ }
+ }
+ else {
+ ElMessage.warning('创建流失败!')
+ }
+}
+
+// 停止流
+async function handleStopStream(deviceId: string) {
+ const res = await stopStream(deviceId)
+ if (res.code !== 200) {
+ ElMessage.warning('停止流失败!')
+ }
+}
+
+// 发送心跳
+async function handleSendHeart(deviceId: string) {
+ const res = await sendHeart(deviceId)
+ if (res && res.data) {
+ if (`${res.data.status}` !== 'on') { // 停止状态
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+ }
+ }
+}
+
+// 播放流
+function playGmStream(cameraIndexCode: string) {
+ // 先停心跳
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+
+ // 播下一个流先停止上一个流
+ if (currentStreamId.value) {
+ handleStopStream(currentStreamId.value)
+ }
+ // 获取视频流接口
+ fetchStream(cameraIndexCode).then((res: any) => {
+ const { url, createStreamResponseId } = res
+ mediaUrl.value = `${url}?token=${window.localStorage.getItem('token')}`
+ // 记录正在播的流的国标号
+ currentStreamId.value = createStreamResponseId
+
+ // 发送心跳
+ timer.value = setInterval(() => {
+ handleSendHeart(createStreamResponseId)
+ }, Number(window.localStorage.getItem('timeGap')))
+ }).catch(() => {
+ ElMessage.warning('未获取到流!请联系管理员!')
+ })
+}
+// -----------------------------------------------------------------------------------------------
// ---------------------------------------------- 以下是暴露的方法内容 ---------------------------------------------------------
defineExpose({ initDialog })
@@ -642,5 +723,6 @@
margin: 0;
box-sizing: content-box;
position: relative;
+ background-color: #161616;
}
diff --git a/src/views/alarm/policyConfig/videoPreview/videoPreview.vue b/src/views/alarm/policyConfig/videoPreview/videoPreview.vue
index bfa7da7..a16585e 100644
--- a/src/views/alarm/policyConfig/videoPreview/videoPreview.vue
+++ b/src/views/alarm/policyConfig/videoPreview/videoPreview.vue
@@ -4,14 +4,18 @@
import { ElMessage, ElMessageBox } from 'element-plus'
import dayjs from 'dayjs'
import { getSecurityAlarmList } from '@/api/alarm/securityAlarm/securityAlarmList'
+import { createStream, sendHeart, stopStream } from '@/api/monitor/index-new-gm'
import { getMediaStream, getMediaToken } from '@/api/monitor/media'
import { videoTree } from '@/api/monitor/broadcast'
import drawArea from '@/views/alarm/policyConfig/monitorPoint/drawArea.vue'
+const timer = ref() // gm取流定时器
const router = useRouter()
const baseurl = ref(window.location.href.split('/#')[0])
const treeRef = ref(null) as any
const filterText = ref('')
+const systemType = ref('') // 系统类别
const data = ref([])
+const currentStreamId = ref('') // 正在播的流的国标号
const points = ref() // 标注信息
// const palyUrl = `${url}?token=${window.localStorage.getItem('token')}`
@@ -60,6 +64,7 @@
let treeClickCount = 0 // 用于双击事件判断
+// 双击树节点
function handleNodeClick(data: any, node: any, self: any) {
console.log('设备信息', data)
@@ -76,25 +81,32 @@
if (data.device.id === currentLeafId.value) {
return
}
- leafLoading.value = true
+ leafLoading.value = true // 叶子结点加载流的时候显示Loading图标
currentLeafId.value = data.device.id
currentData.value = data.device
title.value = data.device.monitorName.replace('-', ' - ')
+ // -------------------------------区域绘制----------------------------------------
if (data.device.deviceBoundaryDTOS && data.device.deviceBoundaryDTOS.length) {
draw(data.device.deviceBoundaryDTOS.filter((item: { boundary: string }) => item.boundary))
}
else {
points.value = []
}
+ // -------------------------------区域绘制----------------------------------------
if (radio.value === '1') { // 原始流
- // 获取原始流
- fetchMediaStream(data.device.cameraIndexCode, data.device.nvrIndexCode).then((res: any) => {
- leafLoading.value = false
- mediaUrl.value = res
- }).catch(() => {
- ElMessage.warning('未获取到流!请联系管理员!')
- leafLoading.value = false
- })
+ if (systemType.value === 'sm') { // 商米流媒体
+ // 获取原始流
+ fetchMediaStream(data.device.cameraIndexCode, data.device.nvrIndexCode).then((res: any) => {
+ leafLoading.value = false
+ mediaUrl.value = res
+ }).catch(() => {
+ ElMessage.warning('未获取到流!请联系管理员!')
+ leafLoading.value = false
+ })
+ }
+ else if (systemType.value === 'gm') { // 国米
+ playGmStream(data.device.cameraIndexCode)
+ }
}
else if (radio.value === '2') { // 识别流
mediaUrl.value = data.device.recognitionUrl
@@ -103,7 +115,8 @@
treeClickCount = now
}
-// 拉取流
+// ----------------------------------------流媒体---------------------------------------------------
+// 拉取流(流媒体)
async function fetchMediaStream(deviceId: string, channelId: string) {
loading.value = true
const res = await getMediaStream(deviceId, channelId, mediaToken.value)
@@ -115,6 +128,72 @@
ElMessage.warning('设备未注册')
}
}
+// ----------------------------------------gm流---------------------------------------------------
+// 创建流
+async function fetchStream(deviceId: string) {
+ loading.value = true
+ const res = await createStream(deviceId)
+ loading.value = false
+ if (res && res.data) {
+ return {
+ url: res.data.url,
+ createStreamResponseId: res.data.id,
+ }
+ }
+ else {
+ ElMessage.warning('创建流失败!')
+ }
+}
+
+// 停止流
+async function handleStopStream(deviceId: string) {
+ const res = await stopStream(deviceId)
+ if (res.code !== 200) {
+ ElMessage.warning('停止流失败!')
+ }
+}
+
+// 发送心跳
+async function handleSendHeart(deviceId: string) {
+ const res = await sendHeart(deviceId)
+ if (res && res.data) {
+ if (`${res.data.status}` !== 'on') { // 停止状态
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+ }
+ }
+}
+
+// 播放流
+function playGmStream(cameraIndexCode: string) {
+ // 先停心跳
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+
+ // 播下一个流先停止上一个流
+ if (currentStreamId.value) {
+ handleStopStream(currentStreamId.value)
+ }
+ // 获取视频流接口
+ fetchStream(cameraIndexCode).then((res: any) => {
+ leafLoading.value = false
+ const { url, createStreamResponseId } = res
+ mediaUrl.value = `${url}?token=${window.localStorage.getItem('token')}`
+ // 记录正在播的流的国标号
+ currentStreamId.value = createStreamResponseId
+
+ // 发送心跳
+ timer.value = setInterval(() => {
+ handleSendHeart(createStreamResponseId)
+ }, Number(window.localStorage.getItem('timeGap')))
+ }).catch(() => {
+ ElMessage.warning('未获取到流!请联系管理员!')
+ leafLoading.value = false
+ })
+}
+// -----------------------------------------------------------------------------------------------
// 获取当日报警数数据
const fetchAlarmData = () => {
@@ -145,17 +224,33 @@
points.value = [] // 清除标注信息
draw(currentData.value.deviceBoundaryDTOS.filter((item: { boundary: string }) => item.boundary))
if (val === '1') { // 原始流
- // 获取原始流
- leafLoading.value = true
- fetchMediaStream(currentData.value.cameraIndexCode, currentData.value.nvrIndexCode).then((res: any) => {
- leafLoading.value = false
- mediaUrl.value = res
- }).catch(() => {
- ElMessage.warning('未获取到流!请联系管理员!')
- leafLoading.value = false
- })
+ if (systemType.value === 'sm') { // 流媒体
+ // 获取原始流
+ leafLoading.value = true
+ fetchMediaStream(currentData.value.cameraIndexCode, currentData.value.nvrIndexCode).then((res: any) => {
+ leafLoading.value = false
+ mediaUrl.value = res
+ }).catch(() => {
+ ElMessage.warning('未获取到流!请联系管理员!')
+ leafLoading.value = false
+ })
+ }
+ else if (systemType.value === 'gm') { // 国米
+ playGmStream(currentData.value.cameraIndexCode)
+ }
}
else if (val === '2') { // 识别流
+ if (systemType.value === 'gm') { // gm切换识别流先清心跳和正在播放的流
+ // 先停心跳
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+
+ // 播下一个流先停止上一个流
+ if (currentStreamId.value) {
+ handleStopStream(currentStreamId.value)
+ }
+ }
mediaUrl.value = currentData.value.recognitionUrl
}
}
@@ -199,18 +294,32 @@
onBeforeUnmount(() => {
unwatch()
window.removeEventListener('resize', resize)
+ if (systemType.value === 'gm') {
+ // 先停心跳
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+
+ // 播下一个流先停止上一个流
+ if (currentStreamId.value) {
+ handleStopStream(currentStreamId.value)
+ }
+ }
})
onMounted(() => {
+ systemType.value = window.localStorage.getItem('systemType') as string
videoTree().then((response) => {
if (response.code === 200) {
data.value = response.data
}
})
- // 获取流媒体token
- getMediaToken().then((res: any) => {
- mediaToken.value = res.data
- })
+ if (systemType.value === 'sm') {
+ // 获取流媒体token
+ getMediaToken().then((res: any) => {
+ mediaToken.value = res.data
+ })
+ }
setTimeout(() => {
resize()
window.addEventListener('resize', resize)
@@ -285,7 +394,7 @@