feat:bug修改

This commit is contained in:
dzc committed 2025-09-15 13:50:13 +08:00
1 parent e9fd667623
commit f771123601
15 files changed
+106 -78

No files matched your search

+1 -1
View File
@@ -12,7 +12,7 @@
placeholder="请选择报警类型" />
</el-form-item>
<el-form-item style="width: 350px;" label="抓拍时间" prop="capTimeList">
<el-date-picker v-model="state.queryForm.capTimeList" value-format="YYYY-MM-DD"
<el-date-picker v-model="state.queryForm.capTimeList" value-format="YYYY-MM-DD HH:mm:ss"
type="daterange" />
</el-form-item>
<el-form-item>
+1 -1
View File
@@ -10,7 +10,7 @@
<dict-select v-model="state.queryForm.carDirect" :options="dh_car_direct" placeholder="请选择行车方向" />
</el-form-item>
<el-form-item style="width: 350px;" label="抓拍时间" prop="capTimeList">
<el-date-picker v-model="state.queryForm.capTimeList" value-format="YYYY-MM-DD" type="daterange" />
<el-date-picker v-model="state.queryForm.capTimeList" value-format="YYYY-MM-DD HH:mm:ss" type="daterange" />
</el-form-item>
<el-form-item>
<el-button icon="search" type="primary" @click="getDataList">
@@ -7,7 +7,7 @@ import API from "./api.js";
*/
class PlayerManager {
constructor(opt) {
if(!opt.el) {
if (!opt.el) {
console.warn(`请初始化播放器时传入必传参数:
new PlayerManager({
el: "wsplayer_id", // 播放器所在的容器ID
@@ -37,24 +37,24 @@ new PlayerManager({
* 在 ws/wss 直连模式下, serverIp 表示MTS流媒体服务 IP
* 在 代理 模式下, serverIp 表示的是 代理服务器的IP 地址
*/
this.serverIp = opt.serverIp
this.serverIp = opt.serverIp
/**
* V1.2.8 版本新增字段
* 解码库资源文件前缀
*/
this.prefixUrl = opt.prefixUrl || './static'
/**
* V1.2.8 版本新增字段
* 优先级最高,该方法传入后
* 结构如下:
* eg:
* (rtspUrl) => {
* return "wss://{ip}:9102"
* }
* 配置后:protocol, isIntranet, proxyServerIp, streamServerIp
*/
this.setWSUrl = opt.setWSUrl
/**
* V1.2.8 版本新增字段
* 解码库资源文件前缀
*/
this.prefixUrl = opt.prefixUrl || './static'
/**
* V1.2.8 版本新增字段
* 优先级最高,该方法传入后
* 结构如下:
* eg:
* (rtspUrl) => {
* return "wss://{ip}:9102"
* }
* 配置后:protocol, isIntranet, proxyServerIp, streamServerIp
*/
this.setWSUrl = opt.setWSUrl
/**
* V1.2.8 版本新增字段
* websocket协议,http支持wss协议拉流,因此增加protocol配置
@@ -69,28 +69,28 @@ new PlayerManager({
*/
this.isIntranet = opt.isIntranet
this.intranetMap = opt.intranetMap
/**
* V1.2.7 版本新增字段
* 用于只有内网
* @desc 代理 模式下,代理服务器的IP 地址
* 如果代理服务有端口则拼接端口
*
*/
this.proxyServerIp = opt.proxyServerIp
/**
* V1.2.7 版本新增字段
* 用于只有内网
* @desc 流媒体服务 IP 地址
* 如果拉流的 9100 9320 端口发生修改,则需要后面拼接修改后的端口
*/
this.streamServerIp = opt.streamServerIp
/**
* V1.2.7 版本新增字段
* @desc 模式类型 是直连模式/代理模式
*/
this.useNginxProxy = opt.useNginxProxy || false
/**
* V1.2.7 版本新增字段
* 用于只有内网
* @desc 代理 模式下,代理服务器的IP 地址
* 如果代理服务有端口则拼接端口
*
*/
this.proxyServerIp = opt.proxyServerIp
/**
* V1.2.7 版本新增字段
* 用于只有内网
* @desc 流媒体服务 IP 地址
* 如果拉流的 9100 9320 端口发生修改,则需要后面拼接修改后的端口
*/
this.streamServerIp = opt.streamServerIp
/**
* V1.2.7 版本新增字段
* @desc 模式类型 是直连模式/代理模式
*/
this.useNginxProxy = opt.useNginxProxy || false
if(opt.importLoad) {
if (opt.importLoad) {
this.loadWSPlayer(() => {
this.initPlayer(opt)
})
@@ -104,9 +104,9 @@ new PlayerManager({
dom.src = `${this.prefixUrl}/WSPlayer/WSPlayer.js`;
document.head.appendChild(dom);
var loaded = false;
if(typeof callback === 'function') {
dom.onload = dom.onreadystatechange = function() {
if(!loaded && (!dom.readyState || /loaded|complete/.test(dom.readyState))) {
if (typeof callback === 'function') {
dom.onload = dom.onreadystatechange = function () {
if (!loaded && (!dom.readyState || /loaded|complete/.test(dom.readyState))) {
dom.onload = dom.onreadystatechange = null;
loaded = true;
callback();
@@ -118,10 +118,10 @@ new PlayerManager({
// 初始化播放器
initPlayer(opt) {
// 初始化播放器
if(window.WSPlayer.WSPlayer) {
if (window.WSPlayer.WSPlayer) {
window.WSPlayer = window.WSPlayer.WSPlayer
}
switch(opt.type) {
switch (opt.type) {
case "real":
this.initRealPlayer(opt);
break;
@@ -165,7 +165,7 @@ new PlayerManager({
useNginxProxy: this.useNginxProxy, // V1.2.7 版本新增该配置 直连时需要改为 false, 代理模式为 true
showIcons: opt.showIcons || {
streamChangeSelect: true, // 主辅码流切换
replayIcon:true, // 刷新重播按钮
replayIcon: true, // 刷新重播按钮
ivsIcon: true, // 控制智能帧按钮
talkIcon: true, // 对讲功能按钮
localRecordIcon: true, // 本地录像功能按钮
@@ -196,7 +196,7 @@ new PlayerManager({
})
this.player = this.realPlayer;
// 初始化云台控制组件
if(opt.pztEl) {
if (opt.pztEl) {
this.realPlayer.initPanTilt({
// 云台控制容器的id
el: opt.pztEl,
@@ -237,7 +237,7 @@ new PlayerManager({
useNginxProxy: this.useNginxProxy, // V1.2.7 版本新增该配置 直连时需要改为 false, 【代理模式可不传】
showIcons: opt.showIcons || {
streamChangeSelect: true, // 主辅码流切换
replayIcon:true, // 刷新重播按钮
replayIcon: true, // 刷新重播按钮
ivsIcon: true, // 控制智能帧按钮
talkIcon: true, // 对讲功能按钮
localRecordIcon: true, // 本地录像功能按钮
@@ -425,7 +425,7 @@ new PlayerManager({
* 关闭播放器
* @param {number} index 可选,关闭指定索引的窗口的播放器,不传则表示关闭所有播放器
*/
close(index, closeReason="api") {
close(index, closeReason = "api") {
this.player && this.player.close(index, closeReason);
}
@@ -565,7 +565,7 @@ new PlayerManager({
// ----------------- 播放器事件 ------------------------
__receiveMessageFromWSPlayer(method, data) {
switch(method) {
switch (method) {
// ------------- 公共事件 ---------------------
case "initializationCompleted":
// 初始化完成,可调用播放方法(适用于动态加载解码库)
@@ -601,7 +601,7 @@ new PlayerManager({
case "closeVideo": // 视频关闭
// 点击关闭按钮引发的视频关闭进行提示
// 切换视频引发的视频关闭不进行提示
if(!data.changeVideoFlag) {
if (!data.changeVideoFlag) {
console.log(`窗口${data.selectIndex}的视频已关闭`)
}
// 关闭原因: btnClick-按钮关闭 chromeMemoryOut-浏览器内存不足 changeStream-切换视频调用 playSDKError-解码库报错关闭 recordFinish-录像回放完成 api-调用API关闭 destroy-解码库销毁关闭 otherCustom-可自定义关闭内容
@@ -638,12 +638,12 @@ new PlayerManager({
console.error(data)
break;
case "customDomInfo": // 窗口大小发生变化,视频播放时均会触发
// data.customDomId 为每一个小窗口的自定义dom的id
// data.width 为当前窗口的宽度
// data.height 为当前窗口的高度
// data.currentWindowPlaying 当前窗口是否正在播放视频
// 根据上述内容 进行水印的添加,或其他操作
break;
// data.customDomId 为每一个小窗口的自定义dom的id
// data.width 为当前窗口的宽度
// data.height 为当前窗口的高度
// data.currentWindowPlaying 当前窗口是否正在播放视频
// 根据上述内容 进行水印的添加,或其他操作
break;
case "chromeMemoryOut":
console.warn("浏览器资源不足!")
break;
@@ -660,7 +660,7 @@ new PlayerManager({
case 'localRecordFile': // 本地录像停止时返回Blob数据
break;
case "notifyTalk": // 点击顶部对讲按钮,触发此回调
// 当采用 realByUrl 进行实时预览时,点击顶部对讲按钮,会触发此回调,需要在此回调内 获取对讲rtsp发起对讲
// 当采用 realByUrl 进行实时预览时,点击顶部对讲按钮,会触发此回调,需要在此回调内 获取对讲rtsp发起对讲
case "switchStartTime":
// 在调用 recordByUrl 中配置 playRecordByTime: false 后, 每次拖拽都会触发此回调,此回调需要重新获取rtsp拉流(不支持直接拖拽跳转的设备需要重新拉流,走此回调)
break;
@@ -51,8 +51,7 @@ async function init(list: any) {
channelIdList: list
})
if (cameraCode != 0) throw new Error()
if (channelList == null || channelList.length == 0) throw new Error()
channel.playList = channelList
channel.playList = channelList ?? []
initVideo()
}
} catch (error: any) {
@@ -67,7 +66,7 @@ function initVideo() {
realPlayer = new PlayerManager({
el: "ws-real-player" /** 实时预览容器id,创建多个播放器,传入不同的容器id即可 **/,
type: "real" /** real - 实时预览 record - 录像回放 **/,
maxNum: 25 /** 一个播放器上限能播放的路数,可根据实际情况设置,支持 1 4 9 16 25 **/,
maxNum: 16 /** 一个播放器上限能播放的路数,可根据实际情况设置,支持 1 4 9 16 25 **/,
num: videoState.videoNum /** 初始化,页面显示的路数 **/,
showControl: true /** 是否显示工具栏,默认显示 **/,
prefixUrl: "lib" /** 解码库所在位置的前缀 **/,
@@ -160,6 +159,7 @@ function destroy() {
realPlayer.close(index)
}
}
realPlayer.destroy()
realPlayer = null;
}
}
@@ -144,7 +144,7 @@ function initVideo(channelCode?: string) {
realPlayer = new PlayerManager({
el: "ws-real-player" /** 实时预览容器id,创建多个播放器,传入不同的容器id即可 **/,
type: "real" /** real - 实时预览 record - 录像回放 **/,
maxNum: 25 /** 一个播放器上限能播放的路数,可根据实际情况设置,支持 1 4 9 16 25 **/,
maxNum: 16 /** 一个播放器上限能播放的路数,可根据实际情况设置,支持 1 4 9 16 25 **/,
num: state.videoNum /** 初始化,页面显示的路数 **/,
showControl: true /** 是否显示工具栏,默认显示 **/,
prefixUrl: "lib" /** 解码库所在位置的前缀 **/,
@@ -250,6 +250,7 @@ function destroy() {
realPlayer.close(index)
}
}
realPlayer.destroy()
realPlayer = null;
}
}
@@ -38,7 +38,6 @@ onUnmounted(() => {
// 初始化播放器
const init = (dataList: any, queryForm: any) => {
destroy()
if (!dataList || !dataList.length) return
state.queryForm = queryForm
if (dataList && dataList.length) {
state.channelList = dataList
@@ -50,7 +49,6 @@ const init = (dataList: any, queryForm: any) => {
state.startTimestamp = dateRange.startTimestamp
state.endTimestamp = dateRange.endTimestamp
}
state.currentNum = findSuitableNum(state.channelList.length, state.numList)
replayVideo = new PlayerManager({
@@ -159,6 +157,7 @@ function destroy() {
replayVideo.close(index)
}
}
replayVideo.destroy()
replayVideo = null;
}
@@ -314,6 +314,7 @@ function destroy() {
replayVideo.close(index)
}
}
replayVideo.destroy()
replayVideo = null;
}
+2
View File
@@ -97,6 +97,8 @@ const onSubmit = async () => {
const _form: any = { ...form }
if (_form.panelViewCodes && _form.panelViewCodes.length) {
_form.panelViewCodes = _form.panelViewCodes.join(',')
} else {
_form.panelViewCodes = ""
}
form.id ? await deviceGroupApi.putObj(_form) : await deviceGroupApi.addObj(_form);
useMessage().success(form.id ? '修改成功' : '添加成功');
+7
View File
@@ -49,6 +49,13 @@
<dict-tag :options="device_group_type" :value="row.bizType" />
</template>
</el-table-column>
<el-table-column prop="panelViewCodes" width="450" label="大屏预览分组">
<template #default="{ row }">
<div class="flex items-center gap-2">
<dict-tag v-for="v in row.panelViewCodes?.split(',')" :options="panel_type" :value="v" />
</div>
</template>
</el-table-column>
<el-table-column prop="sort" label="排序" />
<el-table-column label="操作" width="210">
<template #default="{ row }">
+3 -8
View File
@@ -51,12 +51,9 @@
</template>
<script setup lang="ts" name="previewTab">
import { BasicTableProps, useTable } from "/@/hooks/table";
import * as deviceGroupApi from "/@/api/device/deviceGroup";
import { useMessage } from "/@/hooks/message";
import { useDict } from '/@/hooks/dict';
import * as DeviceCameraApi from "/@/api/device/deviceCamera"
import * as DeviceChannelApi from "/@/api/device/deviceChannel"
// 引入组件
@@ -152,11 +149,9 @@ const getDataList = async () => {
...state.replayForm,
deviceChannelCodeList: state.channelCodeList
})
if (data && data.length) {
state.dataList = data
if (replayVideoRef.value) {
replayVideoRef.value.init(state.dataList, state.replayForm)
}
state.dataList = data ?? []
if (replayVideoRef.value) {
replayVideoRef.value.init(state.dataList, state.replayForm)
}
} catch (error: any) {
console.error("获取回放列表错误", error);
+1 -1
View File
@@ -16,7 +16,7 @@
placeholder="请选择报警类型" />
</el-form-item>
<el-form-item style="width: 350px;" label="抓拍时间" prop="swingTimeList">
<el-date-picker v-model="state.queryForm.swingTimeList" value-format="YYYY-MM-DD"
<el-date-picker v-model="state.queryForm.swingTimeList" value-format="YYYY-MM-DD HH:mm:ss"
type="daterange" />
</el-form-item>
<el-form-item>
+2 -1
View File
@@ -13,7 +13,8 @@
<dict-select v-model="state.queryForm.openType" :options="dh_door_open_type" placeholder="请选择进开门类型" />
</el-form-item>
<el-form-item style="width: 350px;" label="抓拍时间" prop="swingTimeList">
<el-date-picker v-model="state.queryForm.swingTimeList" value-format="YYYY-MM-DD" type="daterange" />
<el-date-picker v-model="state.queryForm.swingTimeList" value-format="YYYY-MM-DD HH:mm:ss"
type="daterange" />
</el-form-item>
<el-form-item>
<el-button icon="search" type="primary" @click="getDataList">
@@ -1,20 +1,42 @@
<!-- 视频预览 -->
<template>
<div class="w-full h-full pt-[10px]">
<div class="w-full h-full flex flex-col pt-[10px]">
<com-title title="监控预览">
<select-device-group v-model="refreshForm.dutyId" autoFirst style="width: 250px;" />
</com-title>
<div class="h-[10px]" />
<preview-video ref="previewVideoRef" />
</div>
</template>
<script setup lang="ts" name="videoPay">
import * as deviceChannelApi from "/@/api/device/deviceChannel"
const comTitle = defineAsyncComponent(() => import('./com-title.vue'));
const PreviewVideo = defineAsyncComponent(() => import("../../../device/components/preview-video/index.vue"));
const refreshForm = reactive<any>({
dutyId: ""
})
const previewVideoRef = ref<any>(null)
watch(
() => refreshForm.dutyId,
() => {
refreshVideo()
}
)
const refreshVideo = async () => {
const { code, data } = await deviceChannelApi.list({
groupId: refreshForm.dutyId
})
if (code != 0) return
const channelCode = data?.map((v: any) => v.channelCode) ?? []
previewVideoRef.value.init(channelCode)
}
</script>
<style lang="scss" scoped></style>
+1 -1
View File
@@ -12,7 +12,7 @@
:options="car_alarm_type" multiple placeholder="请选择进开门类型" />
</el-form-item>
<el-form-item style="width: 350px;" label="抓拍时间" prop="capTimeList">
<el-date-picker v-model="state.queryForm.capTimeList" value-format="YYYY-MM-DD"
<el-date-picker v-model="state.queryForm.capTimeList" value-format="YYYY-MM-DD HH:mm:ss"
type="daterange" />
</el-form-item>
<el-form-item>
+1 -1
View File
@@ -20,7 +20,7 @@
:options="door_alarm_type" multiple placeholder="请选择报警类型" />
</el-form-item>
<el-form-item style="width: 350px;" label="抓拍时间" prop="swingTimeList">
<el-date-picker v-model="state.queryForm.swingTimeList" value-format="YYYY-MM-DD"
<el-date-picker v-model="state.queryForm.swingTimeList" value-format="YYYY-MM-DD HH:mm:ss"
type="daterange" />
</el-form-item>
<el-form-item>