flx:优化云台流程功能 监控展现形式
This commit is contained in:
parent
4bc6693ad4
commit
b4feeafb38
@ -28,3 +28,6 @@ export const selectLiveVideoListApi = (params: {}, showLoading: boolean) => {
|
||||
export const getHikPtzControlApi = (params: {}) => {
|
||||
return http.post(BASEURL + `/xmgl/videoItem/getHikPtzControl`, params, { headers: { noLoading: true }});
|
||||
};
|
||||
export const setHikPtzControlApi = (params: {}) => {
|
||||
return http.post(BASEURL + `/xmgl/videoItem/setHikPtzControl`, params, { headers: { noLoading: true }});
|
||||
};
|
||||
|
||||
@ -30,3 +30,7 @@ export const getVideoItemInfoPoliceCameraItemApi = (params: {}) => {
|
||||
export const getPoliceCameraItemPageApi = (params: {}) => {
|
||||
return http.get(BASEURL + `/xmgl/policeCameraItem/page`, params);
|
||||
};
|
||||
// 查询所有项目信息列表信息
|
||||
export const selectAllProjectInfoList = (params: {}) => {
|
||||
return http.post(BASEURL + `/xmgl/project/selectAllProjectInfoList`, params);
|
||||
};
|
||||
BIN
src/assets/images/iscImage/reload.png
Normal file
BIN
src/assets/images/iscImage/reload.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 714 B |
@ -9,7 +9,8 @@
|
||||
:class="{
|
||||
'container-top_active container_active': controlInfo.videoFlag && controlInfo.opType === 'UP'
|
||||
}"
|
||||
@click="controlVideoFn(0, 0.2, 0, 'UP')"
|
||||
@mousedown="controlVideoMouse('UP', 0)"
|
||||
@mouseup="controlVideoMouse('UP', 1)"
|
||||
>
|
||||
<div class="icon-up"></div>
|
||||
</div>
|
||||
@ -18,7 +19,8 @@
|
||||
:class="{
|
||||
'container-right_active container_active': controlInfo.videoFlag && controlInfo.opType === 'RIGHT'
|
||||
}"
|
||||
@click="controlVideoFn(0.2, 0, 0, 'RIGHT')"
|
||||
@mousedown="controlVideoMouse('RIGHT', 0)"
|
||||
@mouseup="controlVideoMouse('RIGHT', 1)"
|
||||
>
|
||||
<div class="icon-up"></div>
|
||||
</div>
|
||||
@ -27,7 +29,8 @@
|
||||
:class="{
|
||||
'container-bottom_active container_active': controlInfo.videoFlag && controlInfo.opType === 'DOWN'
|
||||
}"
|
||||
@click="controlVideoFn(0, -0.2, 0, 'DOWN')"
|
||||
@mousedown="controlVideoMouse('DOWN', 0)"
|
||||
@mouseup="controlVideoMouse('DOWN', 1)"
|
||||
>
|
||||
<div class="icon-up"></div>
|
||||
</div>
|
||||
@ -36,16 +39,33 @@
|
||||
:class="{
|
||||
'container-left_active container_active': controlInfo.videoFlag && controlInfo.opType === 'LEFT'
|
||||
}"
|
||||
@click="controlVideoFn(-0.2, 0, 0, 'LEFT')"
|
||||
@mousedown="controlVideoMouse('LEFT', 0)"
|
||||
@mouseup="controlVideoMouse('LEFT', 1)"
|
||||
>
|
||||
<div class="icon-up"></div>
|
||||
</div>
|
||||
<div class="container-interior">
|
||||
<div class="interior-main">
|
||||
<div class="interior-item interior-icon1" @click="controlVideoFn(-0.2, 0, 0, 'LEFT_UP')"></div>
|
||||
<div class="interior-item interior-icon2" @click="controlVideoFn(-0.2, 0, 0, 'RIGHT_UP')"></div>
|
||||
<div class="interior-item interior-icon3" @click="controlVideoFn(-0.2, 0, 0, 'RIGHT_DOWN')"></div>
|
||||
<div class="interior-item interior-icon4" @click="controlVideoFn(-0.2, 0, 0, 'LEFT_DOWN')"></div>
|
||||
<div
|
||||
class="interior-item interior-icon1"
|
||||
@mousedown="controlVideoMouse('LEFT_UP', 0)"
|
||||
@mouseup="controlVideoMouse('LEFT_UP', 1)"
|
||||
></div>
|
||||
<div
|
||||
class="interior-item interior-icon2"
|
||||
@mousedown="controlVideoMouse('RIGHT_UP', 0)"
|
||||
@mouseup="controlVideoMouse('RIGHT_UP', 1)"
|
||||
></div>
|
||||
<div
|
||||
class="interior-item interior-icon3"
|
||||
@mousedown="controlVideoMouse('RIGHT_DOWN', 0)"
|
||||
@mouseup="controlVideoMouse('RIGHT_DOWN', 1)"
|
||||
></div>
|
||||
<div
|
||||
class="interior-item interior-icon4"
|
||||
@mousedown="controlVideoMouse('LEFT_DOWN', 0)"
|
||||
@mouseup="controlVideoMouse('LEFT_DOWN', 1)"
|
||||
></div>
|
||||
<div class="interior-refresh">
|
||||
<!-- <div class="icon-refresh"></div> -->
|
||||
</div>
|
||||
@ -59,13 +79,13 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-btn">
|
||||
<div @click="controlVideoFn(0, 0, -0.2, 'ZOOM_OUT')">
|
||||
<div @mousedown="controlVideoMouse('ZOOM_OUT', 0)" @mouseup="controlVideoMouse('ZOOM_OUT', 1)">
|
||||
<div class="btn-round">
|
||||
<div class="icon-minus"></div>
|
||||
</div>
|
||||
<div>倍率缩小</div>
|
||||
</div>
|
||||
<div @click="controlVideoFn(0, 0, 0.2, 'ZOOM_IN')">
|
||||
<div @mousedown="controlVideoMouse('ZOOM_IN', 0)" @mouseup="controlVideoMouse('ZOOM_IN', 1)">
|
||||
<div>倍率放大</div>
|
||||
<div class="btn-round">
|
||||
<div class="icon-plus"></div>
|
||||
@ -76,50 +96,50 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
|
||||
import { getHikPtzControlApi } from "@/api/modules/video";
|
||||
import { getHikPtzControlApi, setHikPtzControlApi } from "@/api/modules/video";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: Number,
|
||||
default: 10
|
||||
default: 10,
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 200
|
||||
default: 200,
|
||||
},
|
||||
min: {
|
||||
type: Number,
|
||||
default: 0
|
||||
default: 0,
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
default: 100
|
||||
default: 100,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ""
|
||||
default: "",
|
||||
},
|
||||
progressColor: {
|
||||
type: String,
|
||||
default: "#00C9FF"
|
||||
default: "#00C9FF",
|
||||
},
|
||||
backgroundColor: {
|
||||
type: String,
|
||||
default: "#BAF0FF"
|
||||
default: "#BAF0FF",
|
||||
},
|
||||
themeColor: {
|
||||
type: String,
|
||||
default: "#fff"
|
||||
default: "#fff",
|
||||
},
|
||||
lineWidth: {
|
||||
type: Number,
|
||||
default: 5
|
||||
default: 5,
|
||||
},
|
||||
newVideoInfo: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["input", "change"]);
|
||||
@ -130,13 +150,20 @@ const ctx = ref(null);
|
||||
const isDragging = ref(false);
|
||||
const controlInfo = ref({
|
||||
videoFlag: false,
|
||||
opType: ""
|
||||
opType: "",
|
||||
});
|
||||
const videoInfo = ref({});
|
||||
|
||||
// 常量定义
|
||||
const DEVICE_TYPE_BALL = 2; // 球机设备类型
|
||||
const VIDEO_TYPE_ISC = 3; // ISC视频类型
|
||||
const SUCCESS_CODE = 200; // 成功状态码
|
||||
const GAP_ANGLE = 90; // 仪表盘缺口角度
|
||||
const INDICATOR_COLOR = "#2758C0"; // 指示器颜色
|
||||
|
||||
// 方法定义
|
||||
const initCanvas = () => {
|
||||
// canvas.value = canvas.value;
|
||||
if (!canvas.value) return;
|
||||
ctx.value = canvas.value.getContext("2d");
|
||||
|
||||
const dpr = window.devicePixelRatio || 1;
|
||||
@ -153,14 +180,22 @@ const drawGauge = () => {
|
||||
const center = props.size / 2;
|
||||
const radius = center - props.lineWidth / 2;
|
||||
const startAngle = Math.PI / 2 + Math.PI / 4;
|
||||
const endAngle = startAngle + ((2 * Math.PI - Math.PI / 2) * currentValue.value) / 100;
|
||||
const endAngle =
|
||||
startAngle + ((2 * Math.PI - Math.PI / 2) * currentValue.value) / 100;
|
||||
|
||||
ctx.value.clearRect(0, 0, props.size, props.size);
|
||||
|
||||
// 绘制背景圆
|
||||
ctx.value.beginPath();
|
||||
ctx.value.setLineDash([5, 3]);
|
||||
ctx.value.arc(center, center, radius, startAngle, startAngle + (2 * Math.PI - Math.PI / 2), false);
|
||||
ctx.value.arc(
|
||||
center,
|
||||
center,
|
||||
radius,
|
||||
startAngle,
|
||||
startAngle + (2 * Math.PI - Math.PI / 2),
|
||||
false
|
||||
);
|
||||
ctx.value.strokeStyle = props.backgroundColor;
|
||||
ctx.value.lineWidth = props.lineWidth;
|
||||
ctx.value.stroke();
|
||||
@ -185,54 +220,95 @@ const drawGauge = () => {
|
||||
|
||||
ctx.value.beginPath();
|
||||
ctx.value.setLineDash([]);
|
||||
ctx.value.rect(-indicatorWidth / 2, -indicatorHeight / 2, indicatorWidth, indicatorHeight);
|
||||
ctx.value.fillStyle = "#2758C0";
|
||||
ctx.value.rect(
|
||||
-indicatorWidth / 2,
|
||||
-indicatorHeight / 2,
|
||||
indicatorWidth,
|
||||
indicatorHeight
|
||||
);
|
||||
ctx.value.fillStyle = INDICATOR_COLOR;
|
||||
ctx.value.fill();
|
||||
|
||||
ctx.value.restore();
|
||||
};
|
||||
|
||||
const controlVideoFn = (pan, tilt, zoom, opType) => {
|
||||
controlInfo.value.opType = opType;
|
||||
if (controlInfo.value.videoFlag) {
|
||||
ElMessage.warning("不要重复点击");
|
||||
return;
|
||||
}
|
||||
if (videoInfo.value.deviceType != 2) {
|
||||
const controlVideoMouse = (opType, action) => {
|
||||
if (videoInfo.value.deviceType !== DEVICE_TYPE_BALL) {
|
||||
ElMessage.warning("该设备不是球机,不支持此操作");
|
||||
return false;
|
||||
}
|
||||
switch (videoInfo.value.videoType) {
|
||||
case 3:
|
||||
controlInfo.value.opType = opType;
|
||||
if (action === 0) {
|
||||
controlInfo.value.videoFlag = true;
|
||||
controlVideoFn_isc(opType);
|
||||
break;
|
||||
default:
|
||||
ElMessage.warning("暂不支持");
|
||||
break;
|
||||
}
|
||||
const json = {
|
||||
itemId: videoInfo.value.itemId,
|
||||
opType: opType,
|
||||
action: action,
|
||||
opSize: currentValue.value,
|
||||
opCode: 1,
|
||||
};
|
||||
setHikPtzControlApi(json)
|
||||
.then((res) => {
|
||||
if (res.code === SUCCESS_CODE) {
|
||||
// 控制成功,静默处理
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("视频控制失败:", error);
|
||||
ElMessage.error("视频控制失败,请稍后重试");
|
||||
})
|
||||
.finally(() => {
|
||||
if (action === 1) {
|
||||
controlInfo.value.videoFlag = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
// 如果将来需要使用,保留此方法
|
||||
// const controlVideoFn = (opType) => {
|
||||
// controlInfo.value.opType = opType;
|
||||
// if (controlInfo.value.videoFlag) {
|
||||
// ElMessage.warning("不要重复点击");
|
||||
// return;
|
||||
// }
|
||||
// if (videoInfo.value.deviceType !== DEVICE_TYPE_BALL) {
|
||||
// ElMessage.warning("该设备不是球机,不支持此操作");
|
||||
// return false;
|
||||
// }
|
||||
// switch (videoInfo.value.videoType) {
|
||||
// case VIDEO_TYPE_ISC:
|
||||
// controlInfo.value.videoFlag = true;
|
||||
// controlVideoFn_isc(opType);
|
||||
// break;
|
||||
// default:
|
||||
// ElMessage.warning("暂不支持");
|
||||
// break;
|
||||
// }
|
||||
// };
|
||||
|
||||
const controlVideoFn_isc = opType => {
|
||||
const controlVideoFn_isc = (opType) => {
|
||||
const json = {
|
||||
itemId: videoInfo.value.itemId,
|
||||
opType: opType,
|
||||
opSize: currentValue.value,
|
||||
opCode: 1
|
||||
opCode: 1,
|
||||
};
|
||||
getHikPtzControlApi(json)
|
||||
.then(res => {
|
||||
if (res.code == 200) {
|
||||
.then((res) => {
|
||||
if (res.code === SUCCESS_CODE) {
|
||||
ElMessage.success("控制成功");
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("ISC视频控制失败:", error);
|
||||
ElMessage.error("视频控制失败,请稍后重试");
|
||||
})
|
||||
.finally(() => {
|
||||
controlInfo.value.videoFlag = false;
|
||||
});
|
||||
};
|
||||
|
||||
// 事件处理
|
||||
const startDrag = e => {
|
||||
const startDrag = (e) => {
|
||||
isDragging.value = true;
|
||||
document.addEventListener("mousemove", handleDrag);
|
||||
document.addEventListener("mouseup", stopDrag);
|
||||
@ -241,26 +317,84 @@ const startDrag = e => {
|
||||
handleDrag(e);
|
||||
};
|
||||
|
||||
const handleDrag = e => {
|
||||
if (!isDragging.value) return;
|
||||
const handleDrag = (e) => {
|
||||
if (!isDragging.value || !canvas.value) return;
|
||||
|
||||
const rect = canvas.value.getBoundingClientRect();
|
||||
const clientX = e.clientX || e.touches[0].clientX;
|
||||
const clientY = e.clientY || e.touches[0].clientY;
|
||||
// 安全地获取触摸或鼠标坐标
|
||||
const clientX = e.clientX ?? (e.touches?.[0]?.clientX);
|
||||
const clientY = e.clientY ?? (e.touches?.[0]?.clientY);
|
||||
|
||||
if (clientX === undefined || clientY === undefined) return;
|
||||
|
||||
const centerX = rect.left + rect.width / 2;
|
||||
const centerY = rect.top + rect.height / 2;
|
||||
const x = clientX - centerX;
|
||||
const y = clientY - centerY;
|
||||
|
||||
let angle = Math.atan2(y, x) * (180 / Math.PI);
|
||||
angle = (angle + 180) % 360;
|
||||
// 计算鼠标相对于圆心的角度(弧度)
|
||||
let angle = Math.atan2(y, x);
|
||||
|
||||
const gapAngle = 90;
|
||||
const usableAngle = 360 - gapAngle;
|
||||
let value = Math.round((angle * 100) / usableAngle);
|
||||
if (angle > usableAngle) value = 100;
|
||||
currentValue.value = Math.min(100, Math.max(0, value));
|
||||
// 仪表盘起始角度:Math.PI / 2 + Math.PI / 4 = 135° (从右上角开始)
|
||||
const startAngle = Math.PI / 2 + Math.PI / 4;
|
||||
// 仪表盘结束角度:135° + 270° = 405° = 45° (跨越0°)
|
||||
const endAngle = startAngle + (2 * Math.PI - Math.PI / 2);
|
||||
// 仪表盘有效角度范围:270° (360° - 90°缺口)
|
||||
const usableAngle = 2 * Math.PI - Math.PI / 2;
|
||||
|
||||
// 将角度转换为 0-2π 范围
|
||||
if (angle < 0) {
|
||||
angle += 2 * Math.PI;
|
||||
}
|
||||
|
||||
// 计算相对于起始角度的偏移角度
|
||||
let relativeAngle;
|
||||
|
||||
// 计算结束角度(在0-2π范围内)
|
||||
const endAngleNormalized = endAngle % (2 * Math.PI); // 45° = π/4
|
||||
|
||||
// 判断角度是否在有效范围内
|
||||
// 情况1:角度在 startAngle 到 2π 之间(135° 到 360°)
|
||||
if (angle >= startAngle && angle <= 2 * Math.PI) {
|
||||
relativeAngle = angle - startAngle;
|
||||
// 如果超出有效范围,限制在边界
|
||||
if (relativeAngle > usableAngle) {
|
||||
relativeAngle = usableAngle;
|
||||
}
|
||||
}
|
||||
// 情况2:角度在 0 到 endAngleNormalized 之间(0° 到 45°),即跨越0°的情况
|
||||
else if (angle >= 0 && angle <= endAngleNormalized) {
|
||||
// 角度跨越了0°,需要加上2π再计算
|
||||
relativeAngle = (angle + 2 * Math.PI) - startAngle;
|
||||
// 确保不超过有效范围
|
||||
if (relativeAngle > usableAngle) {
|
||||
relativeAngle = usableAngle;
|
||||
}
|
||||
// 确保不小于0(防止计算错误)
|
||||
if (relativeAngle < 0) {
|
||||
relativeAngle = 0;
|
||||
}
|
||||
}
|
||||
// 情况3:角度在无效范围内(45° 到 135°之间,即缺口部分)
|
||||
else {
|
||||
// 如果角度在缺口范围内,限制到最近的边界
|
||||
// 判断更接近起始还是结束
|
||||
const distToStart = Math.abs(angle - startAngle);
|
||||
const distToEnd = Math.min(
|
||||
Math.abs(angle - endAngleNormalized),
|
||||
Math.abs(angle + 2 * Math.PI - endAngleNormalized)
|
||||
);
|
||||
|
||||
if (distToStart < distToEnd) {
|
||||
relativeAngle = 0; // 限制到起始位置(0%)
|
||||
} else {
|
||||
relativeAngle = usableAngle; // 限制到结束位置(100%)
|
||||
}
|
||||
}
|
||||
|
||||
// 将角度转换为 0-100 的值
|
||||
const value = Math.round((relativeAngle / usableAngle) * 100);
|
||||
currentValue.value = Math.min(props.max, Math.max(props.min, value));
|
||||
|
||||
drawGauge();
|
||||
emit("input", currentValue.value);
|
||||
@ -272,6 +406,7 @@ const handleDrag = e => {
|
||||
};
|
||||
|
||||
const stopDrag = () => {
|
||||
if (!isDragging.value) return;
|
||||
isDragging.value = false;
|
||||
document.removeEventListener("mousemove", handleDrag);
|
||||
document.removeEventListener("mouseup", stopDrag);
|
||||
@ -281,6 +416,7 @@ const stopDrag = () => {
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
if (!canvas.value) return;
|
||||
initCanvas();
|
||||
drawGauge();
|
||||
canvas.value.addEventListener("mousedown", startDrag);
|
||||
@ -288,8 +424,16 @@ onMounted(() => {
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
// 确保停止拖拽状态
|
||||
if (isDragging.value) {
|
||||
stopDrag();
|
||||
}
|
||||
// 清理canvas事件监听器
|
||||
if (canvas.value) {
|
||||
canvas.value.removeEventListener("mousedown", startDrag);
|
||||
canvas.value.removeEventListener("touchstart", startDrag);
|
||||
}
|
||||
// 清理document事件监听器(防止内存泄漏)
|
||||
document.removeEventListener("mousemove", handleDrag);
|
||||
document.removeEventListener("mouseup", stopDrag);
|
||||
document.removeEventListener("touchmove", handleDrag);
|
||||
@ -299,7 +443,7 @@ onBeforeUnmount(() => {
|
||||
// 监听器
|
||||
watch(
|
||||
() => props.value,
|
||||
newVal => {
|
||||
(newVal) => {
|
||||
currentValue.value = newVal;
|
||||
drawGauge();
|
||||
}
|
||||
@ -307,12 +451,13 @@ watch(
|
||||
|
||||
watch(
|
||||
() => props.newVideoInfo,
|
||||
newVal => {
|
||||
(newVal) => {
|
||||
videoInfo.value = newVal;
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.gauge-canvas {
|
||||
margin-bottom: 28px;
|
||||
@ -570,9 +715,9 @@ watch(
|
||||
.container-btn {
|
||||
width: 270px;
|
||||
height: 50px;
|
||||
background: rgba(39,88,192,0.2);
|
||||
background: rgba(39, 88, 192, 0.2);
|
||||
border-radius: 237px;
|
||||
border: 1px solid rgba(39,88,192,0.6);;
|
||||
border: 1px solid rgba(39, 88, 192, 0.6);
|
||||
margin: 0 auto;
|
||||
margin-top: 15px;
|
||||
display: flex;
|
||||
@ -587,7 +732,7 @@ watch(
|
||||
align-items: center;
|
||||
// justify-content: center;
|
||||
font-size: 15px;
|
||||
color: #FFFFFF;
|
||||
color: #ffffff;
|
||||
cursor: pointer;
|
||||
.btn-round {
|
||||
width: 34px;
|
||||
|
||||
@ -65,6 +65,7 @@ import { reactive, watch, onMounted, computed, nextTick, onBeforeUnmount } from
|
||||
import { ElMessage } from "element-plus";
|
||||
import loadingGif from "@/assets/images/iscImage/loading.gif";
|
||||
import errorPng from "@/assets/images/iscImage/text-to-image.png";
|
||||
import reloadImg from "@/assets/images/iscImage/reload.png";
|
||||
const props = defineProps({
|
||||
devList: {
|
||||
type: Array,
|
||||
@ -415,8 +416,9 @@ const play = (row, index) => {
|
||||
// 视频添加加载中图片
|
||||
const id = `#player-${props.playerId} #player-container-${index}`;
|
||||
var d1 = document.querySelector(id); //获取div元素
|
||||
// console.log(88555, d1.childNodes);
|
||||
d1.childNodes.forEach(item => {
|
||||
if (item.nodeName == "" || item.nodeName == "IMG") {
|
||||
if (item.nodeName == "" || item.nodeName == "IMG" || item.className == "classImg") {
|
||||
d1.removeChild(item);
|
||||
}
|
||||
});
|
||||
@ -445,9 +447,9 @@ const play = (row, index) => {
|
||||
if (!index) {
|
||||
index = 0;
|
||||
}
|
||||
const findIndex = Array.from(d1.childNodes).findIndex(item => item.localName == "img");
|
||||
videoInfo.player.JS_Play(preUrl, param, index).then(
|
||||
() => {
|
||||
const findIndex = Array.from(d1.childNodes).findIndex(item => item.localName == "img");
|
||||
if (findIndex !== -1) {
|
||||
d1.removeChild(d1.childNodes[findIndex]);
|
||||
console.log("播放成功", findIndex);
|
||||
@ -458,15 +460,44 @@ const play = (row, index) => {
|
||||
},
|
||||
err => {
|
||||
console.log("播放失败");
|
||||
im.src = errorPng;
|
||||
const imgHeightNum = 20;
|
||||
const imgWidthNum = 150;
|
||||
im.style.width = imgWidthNum + "px";
|
||||
im.style.height = imgHeightNum + "px";
|
||||
const positionNum = imgHeightNum / 2 - imgHeightNum;
|
||||
const positionWidthNum = imgWidthNum / 2 - imgWidthNum;
|
||||
im.style.marginLeft = positionWidthNum + "px";
|
||||
im.style.marginTop = positionNum + "px";
|
||||
// im.src = errorPng;
|
||||
// const imgHeightNum = 20;
|
||||
// const imgWidthNum = 150;
|
||||
// im.style.width = imgWidthNum + "px";
|
||||
// im.style.height = imgHeightNum + "px";
|
||||
// const positionNum = imgHeightNum / 2 - imgHeightNum;
|
||||
// const positionWidthNum = imgWidthNum / 2 - imgWidthNum;
|
||||
// im.style.marginLeft = positionWidthNum + "px";
|
||||
// im.style.marginTop = positionNum + "px";
|
||||
if (findIndex !== -1) {
|
||||
d1.removeChild(d1.childNodes[findIndex]);
|
||||
let ndiv = document.createElement("div"); //创建图片
|
||||
const reloadBtn = document.createElement("div");
|
||||
|
||||
// 创建图片元素
|
||||
const reloadIcon = document.createElement("img");
|
||||
reloadIcon.src = reloadImg; // 替换为你的图片路径
|
||||
|
||||
reloadBtn.textContent = "重新加载";
|
||||
reloadBtn.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
onReload(row.id);
|
||||
});
|
||||
|
||||
// 将图片添加到按钮
|
||||
reloadBtn.appendChild(reloadIcon);
|
||||
|
||||
ndiv.innerHTML = `
|
||||
${row.status == 2 ? "工单任务未关闭或现场网络信号弱" : "预览失败,请检查设备网络"}
|
||||
`;
|
||||
ndiv.style.position = "absolute";
|
||||
ndiv.style.top = "50%";
|
||||
ndiv.style.left = "50%";
|
||||
ndiv.style.transform = "translate(-50%, -50%)";
|
||||
ndiv.className = "classImg";
|
||||
ndiv.appendChild(reloadBtn);
|
||||
d1.appendChild(ndiv); //图片挂载到div上
|
||||
}
|
||||
}
|
||||
);
|
||||
videoInfo.player.JS_SetConnectTimeOut(index, 60).then(
|
||||
@ -481,9 +512,14 @@ const play = (row, index) => {
|
||||
);
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 分屏,这里我太懒了,就循环了一个视频流
|
||||
*/
|
||||
const onReload = (id) => {
|
||||
console.log("重新加载", id);
|
||||
// 这里添加重新加载的逻辑
|
||||
const findItem = videoInfo.devH5List.find(item => item.id === id);
|
||||
if (findItem) {
|
||||
play(findItem, videoInfo.iWndIndex);
|
||||
}
|
||||
};
|
||||
const onTwoSubmit = num => {
|
||||
// 这里的分屏,是以列来算的,如果这里参数2,那么就是横竖两列,就是4格
|
||||
videoInfo.numCount = num;
|
||||
@ -563,7 +599,7 @@ watch(
|
||||
const videoNameUp = computed(() => {
|
||||
return index => {
|
||||
const find = videoInfo.devH5List.find(item => item.eIndex === index);
|
||||
console.log(8844555, videoInfo.devH5List);
|
||||
// console.log(8844555, videoInfo.devH5List);
|
||||
return find ? find.videoName : "";
|
||||
};
|
||||
});
|
||||
@ -592,6 +628,28 @@ onBeforeUnmount(() => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.classImg) {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-size: 16px;
|
||||
width: calc(100% - 24px);
|
||||
text-align: center;
|
||||
padding: 0 12px;
|
||||
z-index: 101;
|
||||
> div {
|
||||
color: rgb(255, 255, 255);
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 6px;
|
||||
> img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.sub-wnd) {
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
@ -130,6 +130,17 @@
|
||||
<div>工作票类型</div>
|
||||
<div>{{ workTicketDetail.typeName }}</div>
|
||||
</div>
|
||||
<!-- <div class="box1">
|
||||
<div>风险状态</div>
|
||||
<div
|
||||
class="state-box"
|
||||
:class="{
|
||||
gfx_active: workTicketDetail.riskType == 2
|
||||
}"
|
||||
>
|
||||
{{ workTicketDetail.riskType == 2 ? "高风险" : "一般风险" }}
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="box1">
|
||||
<div>工作票编号</div>
|
||||
<div>{{ workTicketDetail.workTicketNumber }}</div>
|
||||
@ -227,8 +238,18 @@
|
||||
:autoplay="true"
|
||||
:controls="true"
|
||||
/> -->
|
||||
<!-- <IscPlayer :devList="[item]" :key="'player-' + item.itemId" :playerId="'player-' + item.itemId" /> -->
|
||||
<div class="videoOverview" :id="`videoOverview${item.itemId}`">
|
||||
<IscPlayer
|
||||
v-if="videoConfig.enableNotPlugin == 1"
|
||||
:devList="[
|
||||
{
|
||||
...item,
|
||||
status: workTicketDetail.status
|
||||
}
|
||||
]"
|
||||
:key="'player-' + item.itemId"
|
||||
:playerId="'player-' + item.itemId"
|
||||
/>
|
||||
<div v-else class="videoOverview" :id="`videoOverview${item.itemId}`">
|
||||
<IscPlugin
|
||||
:devList="[item]"
|
||||
:itemId="item.itemId"
|
||||
@ -381,43 +402,129 @@
|
||||
:modal="false"
|
||||
:modal-append-to-body="false"
|
||||
v-model="equipmentDialog"
|
||||
width="448px"
|
||||
width="941px"
|
||||
class="equipment-dialog"
|
||||
>
|
||||
<div class="dialog_content">
|
||||
<div class="content-left">
|
||||
<div>
|
||||
<div>设备名称</div>
|
||||
<div>{{ equipmentDetail.devName ? equipmentDetail.devName : "--" }}</div>
|
||||
<div>
|
||||
{{ equipmentDetail.devName ? equipmentDetail.devName : "--" }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>设备编号</div>
|
||||
<div>{{ equipmentDetail.devSn ? equipmentDetail.devSn : "--" }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>所属项目</div>
|
||||
<div>{{ projectSnName }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>设备状态</div>
|
||||
<div class="state-box" :class="{ 'state-box_offline': equipmentDetail.deviceState != 1 }">
|
||||
{{ equipmentDetail.deviceState == 1 ? "在线" : "离线" }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div>
|
||||
<div>风险状态</div>
|
||||
<div
|
||||
class="state-box"
|
||||
:class="{
|
||||
gfx_active: workTicketDetail.riskType == 2
|
||||
}"
|
||||
>
|
||||
{{ workTicketDetail.riskType == 2 ? "高风险" : "一般风险" }}
|
||||
</div>
|
||||
</div> -->
|
||||
<div>
|
||||
<div>SD卡容量</div>
|
||||
<div>{{ equipmentDetail.sdCardCapacity ? equipmentDetail.sdCardCapacity : "--" }}</div>
|
||||
<div>工作票类型</div>
|
||||
<div>
|
||||
{{ workTicketDetail.typeName ? workTicketDetail.typeName : "--" }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>已用容量</div>
|
||||
<div>{{ equipmentDetail.usedCapacity ? equipmentDetail.usedCapacity : "--" }}</div>
|
||||
<div>工作票编号</div>
|
||||
<div>
|
||||
{{ workTicketDetail.workTicketNumber ? workTicketDetail.workTicketNumber : "--" }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>剩余容量</div>
|
||||
<div>{{ equipmentDetail.usedCapacity ? equipmentDetail.sdCardCapacity - equipmentDetail.usedCapacity : "--" }}</div>
|
||||
<div>施工区域</div>
|
||||
<div>
|
||||
{{ workTicketDetail.constructionAreaNames ? workTicketDetail.constructionAreaNames : "--" }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>录像状态</div>
|
||||
<div class="state-box">{{ equipmentDetail.recordingStatus ? equipmentDetail.recordingStatus : "--" }}</div>
|
||||
<div>申请单位</div>
|
||||
<div>
|
||||
{{ workTicketDetail.applicantNames ? workTicketDetail.applicantNames : "--" }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>电量</div>
|
||||
<div>{{ equipmentDetail.batteryLevel ? equipmentDetail.batteryLevel : "--" }}</div>
|
||||
<div>作业人员</div>
|
||||
<div>
|
||||
{{ workTicketDetail.operator ? workTicketDetail.operator : "--" }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>施工时间</div>
|
||||
<div>
|
||||
{{ workTicketDetail.constructionTimeBegin }} -
|
||||
{{ workTicketDetail.constructionTimeEnd }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>申请时间</div>
|
||||
<div>
|
||||
{{ workTicketDetail.applicationTime ? workTicketDetail.applicationTime : "--" }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>安全措施</div>
|
||||
<div>
|
||||
{{ workTicketDetail.safetyMeasure ? workTicketDetail.safetyMeasure : "--" }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>作业内容</div>
|
||||
<div>
|
||||
{{ workTicketDetail.workContent ? workTicketDetail.workContent : "--" }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-right">
|
||||
<div class="content-right_header">附件内容</div>
|
||||
<div class="box1">
|
||||
<div>工作票附件</div>
|
||||
<div class="content-img">
|
||||
<template v-if="workTicketDetail.workTicketAttachment && workTicketDetail.workTicketAttachment.length > 0">
|
||||
<el-image
|
||||
v-for="item in workTicketDetail.workTicketAttachment"
|
||||
:key="item.url"
|
||||
:src="BASEURL + '/image/' + item.url"
|
||||
:preview-src-list="[BASEURL + '/image/' + item.url]"
|
||||
>
|
||||
</el-image>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box1">
|
||||
<div>其他附件</div>
|
||||
<div class="content-file_list">
|
||||
<div v-for="item in workTicketDetail.otherAttachment" :key="item.url">
|
||||
<div>
|
||||
<div></div>
|
||||
<div>{{ item.name }}</div>
|
||||
</div>
|
||||
<div @click="downloadFileBtn(BASEURL + '/image/' + item.url, item.name)">
|
||||
<div></div>
|
||||
<div>下载</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
@ -439,8 +546,10 @@ import {
|
||||
getWorkTicketQueryByIdApi,
|
||||
getWorkTicketHistoryListApi,
|
||||
getVideoItemInfoPoliceCameraItemApi,
|
||||
getPoliceCameraItemPageApi
|
||||
getPoliceCameraItemPageApi,
|
||||
selectAllProjectInfoList
|
||||
} from "@/api/modules/workTicket";
|
||||
import { getUseProjectVideoConfigApi } from "@/api/modules/tower";
|
||||
import dayjs from "dayjs";
|
||||
import duration from "dayjs/plugin/duration";
|
||||
dayjs.extend(duration);
|
||||
@ -513,7 +622,7 @@ const getWorkTicketCountWorkTicket = showLoading => {
|
||||
});
|
||||
};
|
||||
const workTicketInfo = reactive({
|
||||
status: "",
|
||||
status: 2,
|
||||
typeId: "",
|
||||
numberOrContent: "",
|
||||
constructionTime: [],
|
||||
@ -577,6 +686,8 @@ onMounted(() => {
|
||||
// // getWorkTicketCountWorkTicket(true);
|
||||
// }, 30000);
|
||||
getWorkTicketTypeTreePage();
|
||||
getProjectVideoConfigList();
|
||||
getSelectAllProjectInfoList();
|
||||
});
|
||||
const viewAllShow = ref(false);
|
||||
const onViewAllClick = () => {
|
||||
@ -785,7 +896,23 @@ const getVideoItemInfoPoliceCameraItem = async row => {
|
||||
if (res.code != 200) return null;
|
||||
return res.result.videoInfo;
|
||||
};
|
||||
|
||||
const videoConfig = ref({
|
||||
enableNotPlugin: 1
|
||||
});
|
||||
//查询项目各类型的视频配置信息
|
||||
const getProjectVideoConfigList = () => {
|
||||
getUseProjectVideoConfigApi({
|
||||
projectSn: store.sn
|
||||
}).then(res => {
|
||||
if (res.code == 200) {
|
||||
if (res.result) {
|
||||
videoConfig.value = res.result;
|
||||
} else {
|
||||
videoConfig.enableNotPlugin = 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
const onRefresh = () => {
|
||||
if (!viewAllShow.value) {
|
||||
onWorkTicketQuery();
|
||||
@ -820,8 +947,8 @@ const updateStatus = computed(() => {
|
||||
};
|
||||
});
|
||||
const itemListDevNameUp = computed(() => {
|
||||
return workTicketDetail.value.itemList ? workTicketDetail.value.itemList.map(item => item.devName).join('、') : ""
|
||||
})
|
||||
return workTicketDetail.value.itemList ? workTicketDetail.value.itemList.map(item => item.devName).join("、") : "";
|
||||
});
|
||||
const workTicketTypeTreeList = ref([]);
|
||||
// 获取工作票类型
|
||||
const getWorkTicketTypeTreePage = () => {
|
||||
@ -882,6 +1009,26 @@ const downloadFileBtn = (url, name) => {
|
||||
console.error(error);
|
||||
});
|
||||
};
|
||||
const projectList = ref([]);
|
||||
const getSelectAllProjectInfoList = () => {
|
||||
selectAllProjectInfoList({
|
||||
sn: store.sn
|
||||
}).then(res => {
|
||||
if (res.code == 200) {
|
||||
projectList.value = [
|
||||
{
|
||||
projectName: "全部项目",
|
||||
projectSn: store.sn
|
||||
},
|
||||
...res.result
|
||||
];
|
||||
}
|
||||
});
|
||||
};
|
||||
const projectSnName = computed(() => {
|
||||
const find = projectList.value.find(item => item.projectSn == workTicketDetail.value.projectSn);
|
||||
return find ? find.projectName : "";
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -1325,6 +1472,19 @@ const downloadFileBtn = (url, name) => {
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
.state-box {
|
||||
padding: 4px 8px;
|
||||
min-width: 40px;
|
||||
color: white;
|
||||
background-color: #88cf65;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
flex: initial !important;
|
||||
}
|
||||
.gfx_active {
|
||||
background-color: #ff0000;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
.box1-header {
|
||||
display: flex;
|
||||
@ -1634,9 +1794,98 @@ const downloadFileBtn = (url, name) => {
|
||||
.dialog_content {
|
||||
padding: 0 20px 5px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
// flex-wrap: wrap;
|
||||
.content-right {
|
||||
width: 48%;
|
||||
.content-right_header {
|
||||
font-weight: 800;
|
||||
font-size: 16px;
|
||||
color: #ffffff;
|
||||
}
|
||||
.box1 {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
padding: 10px 0;
|
||||
font-size: 14px;
|
||||
|
||||
> div:last-child {
|
||||
color: #ffffff;
|
||||
margin-left: 10px;
|
||||
flex: 1;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
> div:first-child {
|
||||
width: 70px;
|
||||
color: #a2a4af;
|
||||
}
|
||||
.content-file_list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
> div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 30px;
|
||||
padding: 0 16px 0 20px;
|
||||
background: rgba(39, 88, 192, 0.2);
|
||||
> div:first-child {
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
> div:last-child {
|
||||
width: 170px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
> div:first-child {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background: url("~@/assets/images/companyBigScreen/terminalOperation/index-icon9.png") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
> div:last-child {
|
||||
font-size: 14px;
|
||||
color: #5181f6;
|
||||
cursor: pointer;
|
||||
> div:first-child {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background: url("~@/assets/images/companyBigScreen/terminalOperation/index-icon10.png") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
> div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> div:not(:first-child) {
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.content-img {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
> .el-image:nth-child(n + 4) {
|
||||
margin-top: 20px;
|
||||
}
|
||||
> .el-image:not(:nth-child(3n + 1)) {
|
||||
margin-left: 20px;
|
||||
}
|
||||
> .el-image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.content-left {
|
||||
width: 49%;
|
||||
> div {
|
||||
width: 50%;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
font-size: 14px;
|
||||
@ -1660,12 +1909,17 @@ const downloadFileBtn = (url, name) => {
|
||||
background-color: #88cf65;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
flex: 0 !important;
|
||||
flex: initial !important;
|
||||
}
|
||||
.state-box_offline {
|
||||
background-color: #f7f7f7;
|
||||
color: #272d45 !important;
|
||||
}
|
||||
.gfx_active {
|
||||
background-color: #ff0000;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,6 +68,7 @@ import { reactive, watch, onMounted, computed, nextTick } from "vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import loadingGif from "@/assets/images/iscImage/loading.gif";
|
||||
import errorPng from "@/assets/images/iscImage/text-to-image.png";
|
||||
import reloadImg from "@/assets/images/iscImage/reload.png";
|
||||
const props = defineProps({
|
||||
devList: {
|
||||
type: Array,
|
||||
@ -110,6 +111,10 @@ const stopAllPlay = () => {
|
||||
if (controls) {
|
||||
controls.classList.remove("video-controls_flex");
|
||||
}
|
||||
const findIndex = Array.from(wnd.childNodes).findIndex(item => item.localName == "img" || item.className == "classImg");
|
||||
if (findIndex !== -1) {
|
||||
wnd.removeChild(wnd.childNodes[findIndex]);
|
||||
}
|
||||
}
|
||||
});
|
||||
videoInfo.devH5List = [];
|
||||
@ -131,7 +136,7 @@ const stopPlay = (currentWindowIndex, type) => {
|
||||
if (controls) {
|
||||
controls.classList.remove("video-controls_flex");
|
||||
}
|
||||
const findIndex = Array.from(wnd.childNodes).findIndex(item => item.localName == "img");
|
||||
const findIndex = Array.from(wnd.childNodes).findIndex(item => item.localName == "img" || item.className == "classImg");
|
||||
if (findIndex !== -1) {
|
||||
wnd.removeChild(wnd.childNodes[findIndex]);
|
||||
}
|
||||
@ -225,7 +230,8 @@ const talkbackStart = currentWindowIndex => {
|
||||
console.log(res2.data.url);
|
||||
|
||||
const url = res2.data.url.replace("hrdl.zhgdyun.com", "sp.szjxj.com");
|
||||
player.JS_StartTalk(url, {
|
||||
player
|
||||
.JS_StartTalk(url, {
|
||||
// irecordType: 1,
|
||||
// cbStreamCB: this.streamcb,
|
||||
})
|
||||
@ -376,15 +382,15 @@ const initPlayer = () => {
|
||||
if (controls) {
|
||||
// if (iWndIndex > videoInfo.devH5List.length - 1) return;
|
||||
// controls.classList.add("video-controls_flex");
|
||||
const someFlag = Array.from(wnd.childNodes).some(item => {
|
||||
return item.src;
|
||||
});
|
||||
console.log(11222233, someFlag);
|
||||
const player_playVideo = wnd.querySelector(`#player_playVideo${iWndIndex}`);
|
||||
const findFlag = Array.from(wnd.childNodes).find(item => {
|
||||
return item.id && item.id.includes("player_playVideo");
|
||||
});
|
||||
if (player_playVideo.src || someFlag || findFlag.duration == "Infinity") {
|
||||
const findImg = Array.from(wnd.childNodes).some(item => {
|
||||
return item.className == "classImg";
|
||||
});
|
||||
// console.log(8848, findFlag, findImg, player_playVideo);
|
||||
if (player_playVideo.src || findImg || findFlag.duration == "Infinity") {
|
||||
controls.classList.add("video-controls_flex");
|
||||
}
|
||||
}
|
||||
@ -507,28 +513,52 @@ const play = (row, index) => {
|
||||
if (!index) {
|
||||
index = 0;
|
||||
}
|
||||
const findIndex = Array.from(d1.childNodes).findIndex(item => item.localName == "img");
|
||||
videoInfo.player.JS_Play(preUrl, param, index).then(
|
||||
() => {
|
||||
const findIndex = Array.from(d1.childNodes).findIndex(item => item.localName == "img");
|
||||
if (findIndex !== -1) {
|
||||
d1.removeChild(d1.childNodes[findIndex]);
|
||||
console.log("播放成功", findIndex);
|
||||
}
|
||||
// 播放成功回调
|
||||
// d1.removeChild(d1.childNodes[d1.childNodes.length - 1]);
|
||||
// console.log("播放成功");
|
||||
},
|
||||
err => {
|
||||
console.log("播放失败");
|
||||
im.src = errorPng;
|
||||
const imgHeightNum = 20;
|
||||
const imgWidthNum = 150;
|
||||
im.style.width = imgWidthNum + "px";
|
||||
im.style.height = imgHeightNum + "px";
|
||||
const positionNum = imgHeightNum / 2 - imgHeightNum;
|
||||
const positionWidthNum = imgWidthNum / 2 - imgWidthNum;
|
||||
im.style.marginLeft = positionWidthNum + "px";
|
||||
im.style.marginTop = positionNum + "px";
|
||||
// im.src = errorPng;
|
||||
// const imgHeightNum = 20;
|
||||
// const imgWidthNum = 150;
|
||||
// im.style.width = imgWidthNum + "px";
|
||||
// im.style.height = imgHeightNum + "px";
|
||||
// const positionNum = imgHeightNum / 2 - imgHeightNum;
|
||||
// const positionWidthNum = imgWidthNum / 2 - imgWidthNum;
|
||||
// im.style.marginLeft = positionWidthNum + "px";
|
||||
// im.style.marginTop = positionNum + "px";
|
||||
if (findIndex !== -1) {
|
||||
d1.removeChild(d1.childNodes[findIndex]);
|
||||
let ndiv = document.createElement("div"); //创建图片
|
||||
const reloadBtn = document.createElement("div");
|
||||
|
||||
// 创建图片元素
|
||||
const reloadIcon = document.createElement("img");
|
||||
reloadIcon.src = reloadImg; // 替换为你的图片路径
|
||||
|
||||
reloadBtn.textContent = "重新加载";
|
||||
reloadBtn.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
onReload(row.id);
|
||||
});
|
||||
|
||||
// 将图片添加到按钮
|
||||
reloadBtn.appendChild(reloadIcon);
|
||||
|
||||
ndiv.innerHTML = `预览失败,请检查设备网络`;
|
||||
ndiv.style.position = "absolute";
|
||||
ndiv.style.top = "50%";
|
||||
ndiv.style.left = "50%";
|
||||
ndiv.style.transform = "translate(-50%, -50%)";
|
||||
ndiv.className = "classImg";
|
||||
ndiv.appendChild(reloadBtn);
|
||||
d1.appendChild(ndiv); //图片挂载到div上
|
||||
}
|
||||
}
|
||||
);
|
||||
videoInfo.iWndIndex =
|
||||
@ -555,9 +585,14 @@ const play = (row, index) => {
|
||||
);
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 分屏,这里我太懒了,就循环了一个视频流
|
||||
*/
|
||||
const onReload = (id) => {
|
||||
console.log("重新加载", id);
|
||||
// 这里添加重新加载的逻辑
|
||||
const findItem = videoInfo.devH5List.find(item => item.id === id);
|
||||
if (findItem) {
|
||||
play(findItem, videoInfo.iWndIndex);
|
||||
}
|
||||
};
|
||||
const onTwoSubmit = num => {
|
||||
// 这里的分屏,是以列来算的,如果这里参数2,那么就是横竖两列,就是4格
|
||||
videoInfo.numCount = num;
|
||||
@ -660,6 +695,28 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.classImg) {
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
font-size: 16px;
|
||||
width: calc(100% - 24px);
|
||||
text-align: center;
|
||||
padding: 0 12px;
|
||||
z-index: 101;
|
||||
> div {
|
||||
color: rgb(255, 255, 255);
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 6px;
|
||||
> img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.bgImage {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user