diff --git a/src/api/detail.js b/src/api/detail.js
index 2cc4dfe..2e84df8 100644
--- a/src/api/detail.js
+++ b/src/api/detail.js
@@ -120,6 +120,13 @@ export const robotApi = {
limit: params.limit
}
})
+ },
+ // 获取事件类型下拉框
+ getEventTypes: () => {
+ return service({
+ url: '/api/v1/events/getEtypeNameList',
+ method: 'get',
+ })
}
}
diff --git a/src/components/AlarmStatistics copy.vue b/src/components/AlarmStatistics copy.vue
new file mode 100644
index 0000000..df6bd63
--- /dev/null
+++ b/src/components/AlarmStatistics copy.vue
@@ -0,0 +1,403 @@
+
+
+
+
+ {{ period.label }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/AlarmStatistics.vue b/src/components/AlarmStatistics.vue
index d22f1d7..941cb83 100644
--- a/src/components/AlarmStatistics.vue
+++ b/src/components/AlarmStatistics.vue
@@ -175,33 +175,18 @@ const updateChart = () => {
},
series: [
{
- // 当没有数据时,显示一个空数据点
data: chartData.series.length > 0 ? chartData.series : [0],
type: "line",
- smooth: true,
+ smooth: false,
symbol: "circle",
symbolSize: 8,
itemStyle: {
- color: "#FF8A00",
+ color: "#fff", // 圆点白色
+ borderColor: '#FF8A00', // 橙色描边
+ borderWidth: 1,
},
lineStyle: {
- color: {
- type: "linear",
- x: 0,
- y: 0,
- x2: 0,
- y2: 1,
- colorStops: [
- {
- offset: 0,
- color: "#FF8A00",
- },
- {
- offset: 1,
- color: "rgba(255, 138, 0, 0)",
- },
- ],
- },
+ color: "#FF8A00", // 线条橙色
width: 3,
},
areaStyle: {
@@ -212,50 +197,18 @@ const updateChart = () => {
x2: 0,
y2: 1,
colorStops: [
- {
- offset: 0,
- color: "rgba(255, 138, 0, 0.3)",
- },
- {
- offset: 1,
- color: "rgba(255, 138, 0, 0)",
- },
+ { offset: 0, color: "rgba(255, 138, 0, 0.3)" },
+ { offset: 1, color: "rgba(255, 138, 0, 0)" },
],
},
},
- markPoint: chartData.series.length > 0 ? {
- symbol: "circle",
- symbolSize: 50,
- itemStyle: {
- color: {
- type: "radial",
- x: 0.5,
- y: 0.5,
- r: 0.5,
- colorStops: [
- {
- offset: 0,
- color: "rgba(255, 138, 0, 0.2)",
- },
- {
- offset: 0.8,
- color: "rgba(255, 138, 0, 0.1)",
- },
- {
- offset: 1,
- color: "rgba(255, 138, 0, 0)",
- },
- ],
- },
- },
- data: [
- {
- type: "max",
- name: "最高频率",
- label: { show: true, color: "#FF8A00", fontSize: 12 },
- },
- ],
- } : null,
+ label: {
+ show: true,
+ position: 'top',
+ color: '#FF8A00',
+ fontSize: 14,
+ fontWeight: 'bold',
+ },
},
],
};
diff --git a/src/components/common/CarouselVideoPlayer.vue b/src/components/common/CarouselVideoPlayer.vue
index 4e4d3cc..b7310c0 100644
--- a/src/components/common/CarouselVideoPlayer.vue
+++ b/src/components/common/CarouselVideoPlayer.vue
@@ -26,7 +26,7 @@
-
+
diff --git a/src/components/common/CarouselWebRTCPlayer.vue b/src/components/common/CarouselWebRTCPlayer.vue
index 70ce3e7..12a6ebc 100644
--- a/src/components/common/CarouselWebRTCPlayer.vue
+++ b/src/components/common/CarouselWebRTCPlayer.vue
@@ -24,7 +24,7 @@
-
+
diff --git a/src/components/common/CustomWebRTCPlayer.vue b/src/components/common/CustomWebRTCPlayer.vue
index 4afd605..1030e49 100644
--- a/src/components/common/CustomWebRTCPlayer.vue
+++ b/src/components/common/CustomWebRTCPlayer.vue
@@ -19,6 +19,24 @@
加载中...
{{ error }}
+
+
+
@@ -50,6 +68,57 @@ const videoRef = ref(null);
const isLoading = ref(false);
const error = ref('');
const pc = ref(null); // WebRTC连接
+const isFullscreen = ref(false); // 是否全屏
+
+// 切换全屏模式
+const toggleFullscreen = () => {
+ const container = videoRef.value?.parentElement || videoRef.value;
+
+ if (!container) return;
+
+ if (!document.fullscreenElement) {
+ // 进入全屏模式
+ if (container.requestFullscreen) {
+ container.requestFullscreen().then(() => {
+ isFullscreen.value = true;
+ }).catch(err => {
+ console.error('全屏模式出错:', err);
+ });
+ } else if (container.webkitRequestFullscreen) { // Safari
+ container.webkitRequestFullscreen();
+ isFullscreen.value = true;
+ } else if (container.msRequestFullscreen) { // IE11
+ container.msRequestFullscreen();
+ isFullscreen.value = true;
+ }
+ } else {
+ exitFullscreen();
+ }
+};
+
+// 退出全屏模式
+const exitFullscreen = () => {
+ if (document.exitFullscreen) {
+ document.exitFullscreen().then(() => {
+ isFullscreen.value = false;
+ }).catch(err => {
+ console.error('退出全屏模式出错:', err);
+ });
+ } else if (document.webkitExitFullscreen) { // Safari
+ document.webkitExitFullscreen();
+ isFullscreen.value = false;
+ } else if (document.msExitFullscreen) { // IE11
+ document.msExitFullscreen();
+ isFullscreen.value = false;
+ }
+};
+
+// 监听全屏状态变化
+const handleFullscreenChange = () => {
+ isFullscreen.value = !!document.fullscreenElement ||
+ !!document.webkitFullscreenElement ||
+ !!document.msFullscreenElement;
+};
// 初始化WebRTC连接
const initWebRTC = async () => {
@@ -249,80 +318,63 @@ const cleanupWebRTC = () => {
error.value = '';
};
-// 监听流URL变化
+// 监听streamUrl变化
watch(() => props.streamUrl, (newUrl) => {
if (newUrl) {
- console.log('流URL变化,重新初始化WebRTC:', newUrl);
+ console.log('streamUrl变化,重新初始化WebRTC:', newUrl);
initWebRTC();
} else {
- console.log('流URL为空,清理WebRTC连接');
+ console.log('streamUrl为空,清理WebRTC连接');
cleanupWebRTC();
}
-}, { immediate: true });
-
-onMounted(() => {
- console.log('CustomWebRTCPlayer组件挂载');
- if (props.streamUrl) {
- initWebRTC();
- }
});
+// 组件挂载时初始化
+onMounted(() => {
+ if (props.streamUrl) {
+ console.log('组件挂载,初始化WebRTC:', props.streamUrl);
+ initWebRTC();
+ }
+
+ // 添加全屏变化事件监听
+ document.addEventListener('fullscreenchange', handleFullscreenChange);
+ document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
+ document.addEventListener('msfullscreenchange', handleFullscreenChange);
+});
+
+// 组件卸载时清理
onUnmounted(() => {
- console.log('CustomWebRTCPlayer组件卸载');
+ console.log('组件卸载,清理WebRTC连接');
cleanupWebRTC();
+
+ // 移除全屏变化事件监听
+ document.removeEventListener('fullscreenchange', handleFullscreenChange);
+ document.removeEventListener('webkitfullscreenchange', handleFullscreenChange);
+ document.removeEventListener('msfullscreenchange', handleFullscreenChange);
+
+ // 确保退出全屏
+ if (isFullscreen.value) {
+ exitFullscreen();
+ }
});
\ No newline at end of file
+
+.loading-text {
+ color: #ffffff;
+ margin-top: 10px;
+ font-size: 14px;
+}
+
+.error-message {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ color: #ff4d4f;
+ background-color: rgba(0, 0, 0, 0.7);
+ padding: 10px 15px;
+ border-radius: 4px;
+ font-size: 14px;
+ max-width: 80%;
+ text-align: center;
+ z-index: 2;
+}
+
+.empty-state {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.video-empty-state {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+/* 控制按钮样式 */
+.control-buttons {
+ position: absolute;
+ right: 10px;
+ bottom: 10px;
+ display: flex;
+ gap: 10px;
+ z-index: 3;
+}
+
+.control-icon {
+ width: 32px;
+ height: 32px;
+ cursor: pointer;
+ opacity: 0.7;
+ transition: opacity 0.3s;
+ background-color: rgba(0, 0, 0, 0.5);
+ padding: 5px;
+ border-radius: 4px;
+}
+
+.control-icon:hover {
+ opacity: 1;
+}
+
\ No newline at end of file
diff --git a/src/views/Home.vue b/src/views/Home.vue
index acd066d..470ea0a 100644
--- a/src/views/Home.vue
+++ b/src/views/Home.vue
@@ -472,6 +472,7 @@ onMounted(() => {
/* background: rgba(0, 21, 31, 0.5); */
background: #033347;
border-radius: 4px;
+ position: relative;
}
.camera-feed img {
diff --git a/src/views/RobotDetail.vue b/src/views/RobotDetail.vue
index 7597fec..97468db 100644
--- a/src/views/RobotDetail.vue
+++ b/src/views/RobotDetail.vue
@@ -31,7 +31,7 @@
-
+
主摄像头
- - 全部告警
- - 事件告警
- - 仪表识别
+ - {{ type }}
@@ -559,12 +557,19 @@ const handleViewAll = async () => {
try {
isLoading.value = true;
- // 使用新API获取告警事件列表,每页10条
- const res = await robotApi.getAlarmDetailList({
+ // 构建接口参数
+ const params = {
number: robotId.value,
- offset: 0,
- limit: 10
- });
+ offset: (currentPage.value - 1) * pageSize.value,
+ limit: pageSize.value
+ };
+ // 如果不是全部告警,添加etypeName参数
+ if (selectedType.value && selectedType.value !== '全部告警') {
+ params.etypeName = selectedType.value;
+ }
+
+ // 使用新API获取告警事件列表
+ const res = await robotApi.getAlarmDetailList(params);
if (res.code === 200 && res.data && res.data.length > 0) {
console.log('获取告警事件列表成功:', res.data);
@@ -1055,14 +1060,18 @@ const getAlarmEventList = async () => {
// 过滤当前Tab下的告警
const filteredEventAlarms = computed(() => {
+ let list = eventAlarms.value;
+ if (selectedType.value && selectedType.value !== '全部告警') {
+ // 按类型过滤,匹配etypeName或content字段
+ list = list.filter(a => a.etypeName === selectedType.value || a.content === selectedType.value);
+ }
if (alarmTab.value === "pending") {
- // 未处理标签下显示待处理和超时未处理的告警
- return eventAlarms.value.filter((a) => a.status === "pending" || a.status === "timeout");
+ return list.filter((a) => a.status === "pending" || a.status === "timeout");
}
if (alarmTab.value === "done") {
- return eventAlarms.value.filter((a) => a.status === "done");
+ return list.filter((a) => a.status === "done");
}
- return eventAlarms.value;
+ return list;
});
const filteredMeterAlarms = computed(() => {
@@ -1172,6 +1181,17 @@ onMounted(async () => {
} catch (error) {
console.error('初始化告警数据失败:', error);
}
+
+ // 获取告警类型
+ try {
+ // 获取告警类型
+ const res = await robotApi.getEventTypes();
+ if (res.code === 200 && Array.isArray(res.data)) {
+ eventTypeOptions.value = ['全部告警', ...res.data];
+ }
+ } catch (e) {
+ console.error('获取告警类型失败', e);
+ }
});
onUnmounted(() => {
@@ -1194,6 +1214,10 @@ const closeSelect = () => {
const selectType = (type) => {
selectedType.value = type;
selectOpen.value = false;
+ // 如果"查看全部"弹窗已打开,自动刷新
+ if (showViewAllModal.value) {
+ handleViewAll();
+ }
};
// 告警详情弹窗相关
@@ -1909,6 +1933,24 @@ const handleAlarmEvent = async (alarm) => {
// 在RobotDetail.vue中添加eventListData变量,用于存储完整的告警事件列表数据
// 在currentEvent和monitorList之后添加
const eventListData = ref([]);
+
+// 告警类型选项
+const eventTypeOptions = ref(['全部告警']);
+
+// 页面加载时获取告警类型
+onMounted(async () => {
+ // ... existing code ...
+ try {
+ // 获取告警类型
+ const res = await robotApi.getEventTypes();
+ if (res.code === 200 && Array.isArray(res.data)) {
+ eventTypeOptions.value = ['全部告警', ...res.data];
+ }
+ } catch (e) {
+ console.error('获取告警类型失败', e);
+ }
+ // ... existing code ...
+});