-
{{ alarm.time }}
-
+
{{ alarm.time.replace("T", " ") }}
+
{{ alarm.level }}
{{ alarm.content }}
-
超时
+
超时
- 已处理
+ 已处理
@@ -239,16 +269,16 @@ import EnvDataGrid from "@/components/detail/EnvDataGrid.vue";
import TaskList from "@/components/detail/TaskList.vue";
import CameraSection from "@/components/detail/CameraSection.vue";
import AddData from "@/components/detail/AddData.vue";
-import AlarmActions from '@/components/AlarmActions.vue'
-import AlarmDetailModal from '@/components/dialog/AlarmDetailModal.vue'
-import EventDetailModal from '@/components/dialog/EventDetailModal.vue'
-import TimeDisplay from '@/components/common/TimeDisplay.vue';
-import { robotApi } from '@/api/detail';
-import WebSocketClient from '@/utils/websocket';
-import CustomWebRTCPlayer from '@/components/common/CustomWebRTCPlayer.vue';
-import ConfirmDialog from '@/components/dialog/ConfirmDialog.vue';
-import EmptyState from '@/components/common/EmptyState.vue';
-import emptyList from '@/assets/img/empty_list.png';
+import AlarmActions from "@/components/AlarmActions.vue";
+import AlarmDetailModal from "@/components/dialog/AlarmDetailModal.vue";
+import EventDetailModal from "@/components/dialog/EventDetailModal.vue";
+import TimeDisplay from "@/components/common/TimeDisplay.vue";
+import { robotApi } from "@/api/detail";
+import WebSocketClient from "@/utils/websocket";
+import CustomWebRTCPlayer from "@/components/common/CustomWebRTCPlayer.vue";
+import ConfirmDialog from "@/components/dialog/ConfirmDialog.vue";
+import EmptyState from "@/components/common/EmptyState.vue";
+import emptyList from "@/assets/img/empty_list.png";
const router = useRouter();
const route = useRoute();
const robotId = ref(route.params.id || "X32305000019");
@@ -261,12 +291,12 @@ const currentDate = ref("2025.12.15 星期五");
const groupInfo = ref([
{ icon: "./img/info1.png", label: "当前分组", value: "室外巡检" },
{ icon: "./img/info2.png", label: "当前班次", value: "00:00-23:59" },
- { icon: "./img/info3.png", label: "当前人员", value: "员工1" }
+ { icon: "./img/info3.png", label: "当前人员", value: "员工1" },
]);
const addData = ref([
- { label: "累计运行", value: "1253h" },
- { label: "累计里程", value: "137.8km" },
- { label: "充电次数", value: "305" }
+ { label: "累计运行", value: "1253h" },
+ { label: "累计里程", value: "137.8km" },
+ { label: "充电次数", value: "305" },
]);
// 机器人信息数据
@@ -275,7 +305,7 @@ const robotInfoItems = ref([
{ label: "电量:", value: "47 %" },
{ label: "电池电压:", value: "5 v" },
{ label: "运行模式:", value: "充电中" },
- { label: "急停:", value: "关闭" }
+ { label: "急停:", value: "关闭" },
]);
// 环境数据
@@ -283,12 +313,12 @@ const envData = ref([
{ icon: "./img/pic1.png", label: "温度", value: "33°C" },
{ icon: "./img/pic2.png", label: "湿度", value: "33°C" },
{ icon: "./img/pic3.png", label: "PM2.5", value: "37ug/m3" },
- { icon: "./img/pic4.png", label: "PM10", value: "43ug/m3" }
+ { icon: "./img/pic4.png", label: "PM10", value: "43ug/m3" },
]);
// 任务列表数据
// const tasks = ref([
-// { area: "A区设备巡检任务", time: "2025-05-01 12:30:50", status: "已完成", type: "completed" },
+// { area: "A区设备巡检任务", time: "2025-05-01 12:30:50", status: "已完成", type: "completed" },
// { area: "B区监控压力巡检", time: "2025-05-01 12:30:00", status: "进行中", type: "running" },
// { area: "C区监控管压任务", time: "2025-05-01 12:30:50", status: "进行中", type: "running" },
// { area: "A区设备巡检任务", time: "2025-05-01 12:30:00", status: "已完成", type: "completed" },
@@ -312,24 +342,21 @@ const tasks = ref([]);
// 获取任务列表的异步函数
const fetchTasks = async (robotId) => {
try {
- const res = await robotApi.getRobotTaskList({ robotId: robotId});
+ const res = await robotApi.getRobotTaskList({ robotId: robotId });
if (res.code === 200 && Array.isArray(res.data)) {
// 适配后端字段到前端字段
- tasks.value = res.data.map(item => ({
- area: item.taskName || '',
- time: item.times || '',
- status: item.status === '0' ? '待执行' : '执行中',
- type: item.status === '0' ? 'pending' : 'running'
+ tasks.value = res.data.map((item) => ({
+ area: item.taskName || "",
+ time: item.times || "",
+ status: item.status === "0" ? "待执行" : "执行中",
+ type: item.status === "0" ? "pending" : "running",
}));
- console.log("--------------------------------",tasks.value);
-
+ console.log("--------------------------------", tasks.value);
} else {
tasks.value = [];
-
}
} catch (error) {
tasks.value = [];
-
}
};
// 摄像头控制函数
@@ -348,22 +375,22 @@ const isUnmounting = ref(false);
const goBack = () => {
// Set unmounting flag to prevent reconnection
isUnmounting.value = true;
-
+
// 关闭WebSocket连接
if (wsClient) {
- console.log('关闭WebSocket连接');
+ console.log("关闭WebSocket连接");
wsClient.close();
wsClient = null;
}
-
+
// 清空视频流地址,触发WebRTCPlayer组件卸载
- console.log('清空视频流地址,释放WebRTC资源');
+ console.log("清空视频流地址,释放WebRTC资源");
streamUrls.value = {
- ptz: '',
- front: '',
- therm: ''
+ ptz: "",
+ front: "",
+ therm: "",
};
-
+
// 延迟一小段时间再导航,确保资源被释放
setTimeout(() => {
router.push("/");
@@ -547,7 +574,10 @@ const meterAlarms = computed(() =>
// 统计数量,包括超时未处理的告警
// 这些计算属性将不再直接用于显示,而是作为备用和调试用途
const pendingCountComputed = computed(
- () => alarmList.value.filter((a) => a.status === "pending" || a.status === "timeout").length
+ () =>
+ alarmList.value.filter(
+ (a) => a.status === "pending" || a.status === "timeout"
+ ).length
);
const doneCountComputed = computed(
() => alarmList.value.filter((a) => a.status === "done").length
@@ -569,10 +599,10 @@ const pageSize = ref(999);
// Tab切换
const alarmTab = ref("pending"); // "pending" | "done"
const setAlarmTab = async (tab) => {
+ isLoading.value = true; // 1. 优先设置loading
alarmTab.value = tab;
-
- // 切换标签时重新获取告警列表和数量
- await getAlarmEventList();
+ alarmList.value = []; // 2. 立即清空数据,防止旧数据闪现
+ await getAlarmEventList(); // 3. 请求新数据
await getAlarmEventCount();
};
@@ -580,52 +610,53 @@ const setAlarmTab = async (tab) => {
const handleViewAll = async () => {
try {
isLoading.value = true;
-
+
// 构建接口参数
const params = {
number: robotId.value,
offset: (currentPage.value - 1) * pageSize.value,
- limit: pageSize.value
+ limit: pageSize.value,
};
// 如果不是全部告警,添加etypeName参数
- if (selectedType.value && selectedType.value !== '全部告警') {
+ 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);
-
+ console.log("获取告警事件列表成功:", res.data);
+
// 将API返回的数据传递给EventDetailModal组件
showViewAllModal.value = true;
-
+
// 更新告警事件列表数据
currentEvent.value = {
- mainImage: res.data[0].imagePreview || '',
+ mainImage: res.data[0].imagePreview || "",
subImages: res.data[0].imageList || [],
- type: res.data[0].etypeName || '',
- time: res.data[0].createTime || '',
+ type: res.data[0].etypeName || "",
+ time: res.data[0].createTime || "",
robotName: res.data[0].name || robotId.value,
- status: res.data[0].handle === '1' ? '已处理' : '未处理'
+ status: res.data[0].handle === "1" ? "已处理" : "未处理",
};
-
+
// 更新monitorList,右侧显示所有告警事件
- monitorList.value = res.data.map(item => ({
- title: item.etypeName || '未知告警',
- image: item.imagePreview || ''
+ monitorList.value = res.data.map((item) => ({
+ title: item.etypeName || "未知告警",
+ image: item.imagePreview || "",
}));
-
+
// 将完整数据传递给弹窗组件
eventListData.value = res.data;
} else {
- console.error('获取告警事件列表失败或列表为空');
- window.$message && window.$message.error('获取告警事件列表失败或列表为空');
+ console.error("获取告警事件列表失败或列表为空");
+ window.$message &&
+ window.$message.error("获取告警事件列表失败或列表为空");
}
} catch (error) {
- console.error('获取告警事件列表异常:', error);
- window.$message && window.$message.error('获取告警事件列表失败');
+ console.error("获取告警事件列表异常:", error);
+ window.$message && window.$message.error("获取告警事件列表失败");
} finally {
isLoading.value = false;
}
@@ -634,34 +665,34 @@ const handleViewAll = async () => {
// 一键处理按钮
const handleProcessAll = async () => {
showConfirmDialog.value = true;
- confirmDialogMessage.value = '是否确认处理所有未处理的告警事件?';
+ confirmDialogMessage.value = "是否确认处理所有未处理的告警事件?";
};
// 添加一键处理OCR告警的方法
const handleOcrAlerts = async () => {
try {
const res = await robotApi.handleOcrAlerts({
- number: robotId.value
+ number: robotId.value,
});
if (res.code === 200) {
- console.log('一键处理OCR告警成功');
-
+ console.log("一键处理OCR告警成功");
+
// 重新获取告警列表
- if (alarmTab.value === 'pending') {
+ if (alarmTab.value === "pending") {
await getUnhandledAlarmMessages();
} else {
await getHandledAlarmMessages();
}
-
+
// 更新告警数量
await getAlarmEventCount();
-
+
return true;
}
return false;
} catch (error) {
- console.error('一键处理OCR告警失败:', error);
+ console.error("一键处理OCR告警失败:", error);
return false;
}
};
@@ -669,59 +700,64 @@ const handleOcrAlerts = async () => {
// 添加确认处理函数
const handleConfirmProcess = async () => {
try {
- console.log('开始一键处理所有告警');
-
+ console.log("开始一键处理所有告警");
+
// 分类告警
- const ocrAlarms = alarmList.value.filter(a =>
- (a.status === 'pending' || a.status === 'timeout') &&
- (a.group === "meter" || a.content === "日常巡检")
+ const ocrAlarms = alarmList.value.filter(
+ (a) =>
+ (a.status === "pending" || a.status === "timeout") &&
+ (a.group === "meter" || a.content === "日常巡检")
);
-
- const eventAlarms = alarmList.value.filter(a =>
- (a.status === 'pending' || a.status === 'timeout') &&
- a.group === "event" && a.content !== "日常巡检"
+
+ const eventAlarms = alarmList.value.filter(
+ (a) =>
+ (a.status === "pending" || a.status === "timeout") &&
+ a.group === "event" &&
+ a.content !== "日常巡检"
);
-
- console.log(`分类完成: OCR告警 ${ocrAlarms.length}个, 事件告警 ${eventAlarms.length}个`);
-
+
+ console.log(
+ `分类完成: OCR告警 ${ocrAlarms.length}个, 事件告警 ${eventAlarms.length}个`
+ );
+
// 处理OCR告警
if (ocrAlarms.length > 0) {
const ocrSuccess = await handleOcrAlerts();
- console.log(`OCR告警处理${ocrSuccess ? '成功' : '失败'}`);
+ console.log(`OCR告警处理${ocrSuccess ? "成功" : "失败"}`);
}
-
+
// 处理事件告警
if (eventAlarms.length > 0) {
- const eventIds = eventAlarms.map(a => a.id);
+ const eventIds = eventAlarms.map((a) => a.id);
const res = await robotApi.handleAlarmEvent({
- eventIds: eventIds
+ eventIds: eventIds,
});
if (res.code === 200) {
- console.log('事件告警处理成功');
+ console.log("事件告警处理成功");
// 更新本地状态
- alarmList.value = alarmList.value.map(a =>
- eventIds.includes(a.id) ? { ...a, status: 'done', isRead: true } : a
+ alarmList.value = alarmList.value.map((a) =>
+ eventIds.includes(a.id) ? { ...a, status: "done", isRead: true } : a
);
} else {
- console.error('事件告警处理失败:', res);
+ console.error("事件告警处理失败:", res);
}
}
-
+
// 重新获取告警列表
- if (alarmTab.value === 'pending') {
+ if (alarmTab.value === "pending") {
await getUnhandledAlarmMessages();
} else {
await getHandledAlarmMessages();
}
-
+
// 更新告警数量
await getAlarmEventCount();
-
+
// 关闭确认对话框
showConfirmDialog.value = false;
} catch (error) {
- console.error('一键处理失败:', error);
+ console.error("一键处理失败:", error);
// 关闭确认对话框
showConfirmDialog.value = false;
}
@@ -729,44 +765,51 @@ const handleConfirmProcess = async () => {
// 添加数据加载状态
const isLoading = ref(false);
-const loadingError = ref('');
+const loadingError = ref("");
// 获取告警数量
const getAlarmEventCount = async () => {
try {
isLoading.value = true;
- loadingError.value = '';
-
- console.log('开始获取告警数量,机器人ID:', robotId.value);
+ loadingError.value = "";
+
+ console.log("开始获取告警数量,机器人ID:", robotId.value);
const res = await robotApi.getAlarmEventCount({
- number: robotId.value
+ number: robotId.value,
});
if (res.code === 200) {
- console.log('获取告警数量成功,原始数据:', res.data);
+ console.log("获取告警数量成功,原始数据:", res.data);
alertCount.value = res.data.alert_count || 0;
processedCount.value = res.data.processed_count || 0;
allCount.value = res.data.all_count || 0; // 从接口返回的all_count中获取全部告警数量
-
+
// 直接更新显示用的计数
pendingCount.value = alertCount.value;
doneCount.value = processedCount.value;
-
- console.log('告警数量更新:', {
+
+ console.log("告警数量更新:", {
未处理: alertCount.value,
已处理: processedCount.value,
全部: allCount.value, // 添加日志输出
当前标签: alarmTab.value,
pendingCount: pendingCount.value,
- doneCount: doneCount.value
+ doneCount: doneCount.value,
});
} else {
- console.error('获取告警数量失败,错误码:', res.code, '错误信息:', res.msg || res.message);
- loadingError.value = `获取告警数量失败: ${res.msg || res.message || '未知错误'}`;
+ console.error(
+ "获取告警数量失败,错误码:",
+ res.code,
+ "错误信息:",
+ res.msg || res.message
+ );
+ loadingError.value = `获取告警数量失败: ${
+ res.msg || res.message || "未知错误"
+ }`;
}
} catch (error) {
- console.error('获取告警数量失败,异常:', error);
- loadingError.value = `获取告警数量失败: ${error.message || '未知错误'}`;
+ console.error("获取告警数量失败,异常:", error);
+ loadingError.value = `获取告警数量失败: ${error.message || "未知错误"}`;
} finally {
isLoading.value = false;
}
@@ -776,45 +819,50 @@ const getAlarmEventCount = async () => {
const getUnhandledAlarmMessages = async () => {
try {
isLoading.value = true;
- loadingError.value = '';
-
- console.log('获取未处理告警消息列表,参数:', {
+ loadingError.value = "";
+
+ console.log("获取未处理告警消息列表,参数:", {
skip: (currentPage.value - 1) * pageSize.value,
limit: pageSize.value,
- number: robotId.value
+ number: robotId.value,
});
-
+
const res = await robotApi.getUnhandledAlarmMessages({
skip: (currentPage.value - 1) * pageSize.value,
limit: pageSize.value,
- number: robotId.value
+ number: robotId.value,
});
if (res.code === 200) {
- console.log('获取未处理告警消息列表成功:', res.data);
+ console.log("获取未处理告警消息列表成功:", res.data);
// 清空现有告警列表
alarmList.value = [];
-
+
// 处理高温感知报警
- if (res.data.high_temperature_message && res.data.high_temperature_message.length > 0) {
- const highTempAlarms = res.data.high_temperature_message.map(item => ({
- id: item.eventId,
- messageId: item.messageId,
- group: "event",
- level: "I级", // 高温报警为I级
- status: "pending",
- isRead: false,
- type: "warning",
- content: "高温感知报警",
- time: formatEventTime(item.createTime),
- imageUrl: item.imageUrl || []
- }));
+ if (
+ res.data.high_temperature_message &&
+ res.data.high_temperature_message.length > 0
+ ) {
+ const highTempAlarms = res.data.high_temperature_message.map(
+ (item) => ({
+ id: item.eventId,
+ messageId: item.messageId,
+ group: "event",
+ level: "I级", // 高温报警为I级
+ status: "pending",
+ isRead: false,
+ type: "warning",
+ content: "高温感知报警",
+ time: formatEventTime(item.createTime),
+ imageUrl: item.imageUrl || [],
+ })
+ );
alarmList.value.push(...highTempAlarms);
}
-
+
// 处理吸烟报警
if (res.data.smoke_message && res.data.smoke_message.length > 0) {
- const smokeAlarms = res.data.smoke_message.map(item => ({
+ const smokeAlarms = res.data.smoke_message.map((item) => ({
id: item.eventId,
messageId: item.messageId,
group: "event",
@@ -824,14 +872,14 @@ const getUnhandledAlarmMessages = async () => {
type: "danger",
content: "吸烟报警",
time: formatEventTime(item.createTime),
- imageUrl: item.imageUrl || []
+ imageUrl: item.imageUrl || [],
}));
alarmList.value.push(...smokeAlarms);
}
-
+
// 处理长时间滞留报警
if (res.data.long_stay_message && res.data.long_stay_message.length > 0) {
- const longStayAlarms = res.data.long_stay_message.map(item => ({
+ const longStayAlarms = res.data.long_stay_message.map((item) => ({
id: item.eventId,
messageId: item.messageId,
group: "event",
@@ -841,14 +889,17 @@ const getUnhandledAlarmMessages = async () => {
type: "warning",
content: "长时间滞留报警",
time: formatEventTime(item.createTime),
- imageUrl: item.imageUrl || []
+ imageUrl: item.imageUrl || [],
}));
alarmList.value.push(...longStayAlarms);
}
-
+
// 处理空气质量报警
- if (res.data.air_quality_message && res.data.air_quality_message.length > 0) {
- const airQualityAlarms = res.data.air_quality_message.map(item => ({
+ if (
+ res.data.air_quality_message &&
+ res.data.air_quality_message.length > 0
+ ) {
+ const airQualityAlarms = res.data.air_quality_message.map((item) => ({
id: item.eventId,
messageId: item.messageId,
group: "event",
@@ -859,14 +910,17 @@ const getUnhandledAlarmMessages = async () => {
content: "空气质量报警",
time: formatEventTime(item.createTime),
imageUrl: item.imageUrl || [],
- temperature: item.temperature
+ temperature: item.temperature,
}));
alarmList.value.push(...airQualityAlarms);
}
-
+
// 处理急停按下
- if (res.data.stop_emergency_message && res.data.stop_emergency_message.length > 0) {
- const emergencyAlarms = res.data.stop_emergency_message.map(item => ({
+ if (
+ res.data.stop_emergency_message &&
+ res.data.stop_emergency_message.length > 0
+ ) {
+ const emergencyAlarms = res.data.stop_emergency_message.map((item) => ({
id: item.eventId,
messageId: item.messageId,
group: "event",
@@ -876,14 +930,17 @@ const getUnhandledAlarmMessages = async () => {
type: "danger",
content: "急停按下",
time: formatEventTime(item.createTime),
- imageUrl: item.imageUrl || []
+ imageUrl: item.imageUrl || [],
}));
alarmList.value.push(...emergencyAlarms);
}
-
+
// 处理语音未接通
- if (res.data.voice_connect_message && res.data.voice_connect_message.length > 0) {
- const voiceAlarms = res.data.voice_connect_message.map(item => ({
+ if (
+ res.data.voice_connect_message &&
+ res.data.voice_connect_message.length > 0
+ ) {
+ const voiceAlarms = res.data.voice_connect_message.map((item) => ({
id: item.eventId,
messageId: item.messageId,
group: "event",
@@ -893,14 +950,17 @@ const getUnhandledAlarmMessages = async () => {
type: "warning",
content: "语音未接通",
time: formatEventTime(item.createTime),
- imageUrl: item.imageUrl || []
+ imageUrl: item.imageUrl || [],
}));
alarmList.value.push(...voiceAlarms);
}
-
+
// 处理日常巡检(包括读表)
- if (res.data.daily_inspect_message && res.data.daily_inspect_message.length > 0) {
- const inspectAlarms = res.data.daily_inspect_message.map(item => ({
+ if (
+ res.data.daily_inspect_message &&
+ res.data.daily_inspect_message.length > 0
+ ) {
+ const inspectAlarms = res.data.daily_inspect_message.map((item) => ({
id: item.eventId,
messageId: item.messageId,
group: "meter", // 日常巡检归类为仪表类
@@ -911,17 +971,21 @@ const getUnhandledAlarmMessages = async () => {
content: "日常巡检",
time: formatEventTime(item.createTime),
imageUrl: item.imageUrl || [],
- temperature: item.temperature
+ temperature: item.temperature,
}));
alarmList.value.push(...inspectAlarms);
}
} else {
- console.error('获取未处理告警消息列表失败:', res);
- loadingError.value = `获取未处理告警消息列表失败: ${res.msg || res.message || '未知错误'}`;
+ console.error("获取未处理告警消息列表失败:", res);
+ loadingError.value = `获取未处理告警消息列表失败: ${
+ res.msg || res.message || "未知错误"
+ }`;
}
} catch (error) {
- console.error('获取未处理告警消息列表失败:', error);
- loadingError.value = `获取未处理告警消息列表失败: ${error.message || '未知错误'}`;
+ console.error("获取未处理告警消息列表失败:", error);
+ loadingError.value = `获取未处理告警消息列表失败: ${
+ error.message || "未知错误"
+ }`;
} finally {
isLoading.value = false;
}
@@ -933,34 +997,39 @@ const getHandledAlarmMessages = async () => {
const res = await robotApi.getHandledAlarmMessages({
skip: (currentPage.value - 1) * pageSize.value,
limit: pageSize.value,
- number: robotId.value
+ number: robotId.value,
});
if (res.code === 200) {
// 清空现有告警列表
alarmList.value = [];
-
+
// 处理高温感知报警
- if (res.data.high_temperature_message && res.data.high_temperature_message.length > 0) {
- const highTempAlarms = res.data.high_temperature_message.map(item => ({
- id: item.eventId,
- messageId: item.messageId,
- group: "event",
- level: "I级", // 高温报警为I级
- status: "done",
- isRead: true,
- type: "warning",
- content: "高温感知报警",
- time: formatEventTime(item.createTime),
- imageUrl: item.imageUrl || [],
- remark: item.remark
- }));
+ if (
+ res.data.high_temperature_message &&
+ res.data.high_temperature_message.length > 0
+ ) {
+ const highTempAlarms = res.data.high_temperature_message.map(
+ (item) => ({
+ id: item.eventId,
+ messageId: item.messageId,
+ group: "event",
+ level: "I级", // 高温报警为I级
+ status: "done",
+ isRead: true,
+ type: "warning",
+ content: "高温感知报警",
+ time: formatEventTime(item.createTime),
+ imageUrl: item.imageUrl || [],
+ remark: item.remark,
+ })
+ );
alarmList.value.push(...highTempAlarms);
}
-
+
// 处理吸烟报警
if (res.data.smoke_message && res.data.smoke_message.length > 0) {
- const smokeAlarms = res.data.smoke_message.map(item => ({
+ const smokeAlarms = res.data.smoke_message.map((item) => ({
id: item.eventId,
messageId: item.messageId,
group: "event",
@@ -971,14 +1040,14 @@ const getHandledAlarmMessages = async () => {
content: "吸烟报警",
time: formatEventTime(item.createTime),
imageUrl: item.imageUrl || [],
- remark: item.remark
+ remark: item.remark,
}));
alarmList.value.push(...smokeAlarms);
}
-
+
// 处理长时间滞留报警
if (res.data.long_stay_message && res.data.long_stay_message.length > 0) {
- const longStayAlarms = res.data.long_stay_message.map(item => ({
+ const longStayAlarms = res.data.long_stay_message.map((item) => ({
id: item.eventId,
messageId: item.messageId,
group: "event",
@@ -989,14 +1058,17 @@ const getHandledAlarmMessages = async () => {
content: "长时间滞留报警",
time: formatEventTime(item.createTime),
imageUrl: item.imageUrl || [],
- remark: item.remark
+ remark: item.remark,
}));
alarmList.value.push(...longStayAlarms);
}
-
+
// 处理空气质量报警
- if (res.data.air_quality_message && res.data.air_quality_message.length > 0) {
- const airQualityAlarms = res.data.air_quality_message.map(item => ({
+ if (
+ res.data.air_quality_message &&
+ res.data.air_quality_message.length > 0
+ ) {
+ const airQualityAlarms = res.data.air_quality_message.map((item) => ({
id: item.eventId,
messageId: item.messageId,
group: "event",
@@ -1008,14 +1080,17 @@ const getHandledAlarmMessages = async () => {
time: formatEventTime(item.createTime),
imageUrl: item.imageUrl || [],
temperature: item.temperature,
- remark: item.remark
+ remark: item.remark,
}));
alarmList.value.push(...airQualityAlarms);
}
-
+
// 处理急停按下
- if (res.data.stop_emergency_message && res.data.stop_emergency_message.length > 0) {
- const emergencyAlarms = res.data.stop_emergency_message.map(item => ({
+ if (
+ res.data.stop_emergency_message &&
+ res.data.stop_emergency_message.length > 0
+ ) {
+ const emergencyAlarms = res.data.stop_emergency_message.map((item) => ({
id: item.eventId,
messageId: item.messageId,
group: "event",
@@ -1026,14 +1101,17 @@ const getHandledAlarmMessages = async () => {
content: "急停按下",
time: formatEventTime(item.createTime),
imageUrl: item.imageUrl || [],
- remark: item.remark
+ remark: item.remark,
}));
alarmList.value.push(...emergencyAlarms);
}
-
+
// 处理语音未接通
- if (res.data.voice_connect_message && res.data.voice_connect_message.length > 0) {
- const voiceAlarms = res.data.voice_connect_message.map(item => ({
+ if (
+ res.data.voice_connect_message &&
+ res.data.voice_connect_message.length > 0
+ ) {
+ const voiceAlarms = res.data.voice_connect_message.map((item) => ({
id: item.eventId,
messageId: item.messageId,
group: "event",
@@ -1044,14 +1122,17 @@ const getHandledAlarmMessages = async () => {
content: "语音未接通",
time: formatEventTime(item.createTime),
imageUrl: item.imageUrl || [],
- remark: item.remark
+ remark: item.remark,
}));
alarmList.value.push(...voiceAlarms);
}
-
+
// 处理日常巡检(包括读表)
- if (res.data.daily_inspect_message && res.data.daily_inspect_message.length > 0) {
- const inspectAlarms = res.data.daily_inspect_message.map(item => ({
+ if (
+ res.data.daily_inspect_message &&
+ res.data.daily_inspect_message.length > 0
+ ) {
+ const inspectAlarms = res.data.daily_inspect_message.map((item) => ({
id: item.eventId,
messageId: item.messageId,
group: "meter", // 日常巡检归类为仪表类
@@ -1063,19 +1144,19 @@ const getHandledAlarmMessages = async () => {
time: formatEventTime(item.createTime),
imageUrl: item.imageUrl || [],
temperature: item.temperature,
- remark: item.remark
+ remark: item.remark,
}));
alarmList.value.push(...inspectAlarms);
}
}
} catch (error) {
- console.error('获取已处理告警消息列表失败:', error);
+ console.error("获取已处理告警消息列表失败:", error);
}
};
// 修改原有的获取告警事件列表函数,根据当前tab调用对应的API
const getAlarmEventList = async () => {
- if (alarmTab.value === 'pending') {
+ if (alarmTab.value === "pending") {
await getUnhandledAlarmMessages();
} else {
await getHandledAlarmMessages();
@@ -1085,9 +1166,12 @@ const getAlarmEventList = async () => {
// 过滤当前Tab下的告警
const filteredEventAlarms = computed(() => {
let list = eventAlarms.value;
- if (selectedType.value && selectedType.value !== '全部告警') {
+ if (selectedType.value && selectedType.value !== "全部告警") {
// 按类型过滤,匹配etypeName或content字段
- list = list.filter(a => a.etypeName === selectedType.value || a.content === selectedType.value);
+ list = list.filter(
+ (a) =>
+ a.etypeName === selectedType.value || a.content === selectedType.value
+ );
}
if (alarmTab.value === "pending") {
return list.filter((a) => a.status === "pending" || a.status === "timeout");
@@ -1101,7 +1185,9 @@ const filteredEventAlarms = computed(() => {
const filteredMeterAlarms = computed(() => {
if (alarmTab.value === "pending") {
// 未处理标签下显示待处理和超时未处理的告警
- return meterAlarms.value.filter((a) => a.status === "pending" || a.status === "timeout");
+ return meterAlarms.value.filter(
+ (a) => a.status === "pending" || a.status === "timeout"
+ );
}
if (alarmTab.value === "done") {
return meterAlarms.value.filter((a) => a.status === "done");
@@ -1117,7 +1203,7 @@ let scrollTimer = null;
let isHovering = ref({
alarmList: false,
meterList: false,
- taskList: false
+ taskList: false,
});
const startAutoScroll = () => {
@@ -1126,21 +1212,21 @@ const startAutoScroll = () => {
const el = alarmListRef.value;
const meterEl = meterAlarmListRef.value;
const taskEl = taskListRef.value;
-
+
if (el && !isHovering.value.alarmList) {
el.scrollTop += 1;
if (el.scrollTop >= el.scrollHeight - el.clientHeight) {
el.scrollTop = 0;
}
}
-
+
if (meterEl && !isHovering.value.meterList) {
meterEl.scrollTop += 1;
if (meterEl.scrollTop >= meterEl.scrollHeight - meterEl.clientHeight) {
meterEl.scrollTop = 0;
}
}
-
+
if (taskEl && !isHovering.value.taskList) {
taskEl.scrollTop += 1;
if (taskEl.scrollTop >= taskEl.scrollHeight - taskEl.clientHeight) {
@@ -1163,47 +1249,51 @@ const handleMouseLeave = (listType) => {
};
onMounted(async () => {
- console.log('RobotDetail组件挂载,机器人ID:', robotId.value);
-
+ console.log("RobotDetail组件挂载,机器人ID:", robotId.value);
+
// 先登录获取token
await login();
- console.log('登录成功,开始初始化数据');
-
+ console.log("登录成功,开始初始化数据");
+
// 启动自动滚动
startAutoScroll();
-
+
// 获取任务列表DOM引用
nextTick(() => {
- const taskListElement = document.querySelector('.task-list');
+ const taskListElement = document.querySelector(".task-list");
if (taskListElement) {
taskListRef.value = taskListElement;
// 为任务列表添加鼠标事件
- taskListElement.addEventListener('mouseenter', () => handleMouseEnter('taskList'));
- taskListElement.addEventListener('mouseleave', () => handleMouseLeave('taskList'));
+ taskListElement.addEventListener("mouseenter", () =>
+ handleMouseEnter("taskList")
+ );
+ taskListElement.addEventListener("mouseleave", () =>
+ handleMouseLeave("taskList")
+ );
}
});
-
+
try {
// 先获取告警数量 - 确保在获取列表前先更新数量
- console.log('开始初始化告警数据');
+ console.log("开始初始化告警数据");
await getAlarmEventCount();
- console.log('告警数量获取完成,开始获取告警列表');
-
+ console.log("告警数量获取完成,开始获取告警列表");
+
// 然后获取告警列表
await getAlarmEventList();
- console.log('告警列表获取完成');
-
+ console.log("告警列表获取完成");
+
// 再次确认计数正确 - 防止列表加载过程中数量变化
await getAlarmEventCount();
-
- console.log('数据初始化完成,当前计数:', {
+
+ console.log("数据初始化完成,当前计数:", {
pendingCount: pendingCount.value,
doneCount: doneCount.value,
alertCount: alertCount.value,
- processedCount: processedCount.value
+ processedCount: processedCount.value,
});
} catch (error) {
- console.error('初始化告警数据失败:', error);
+ console.error("初始化告警数据失败:", error);
}
// 获取告警类型
@@ -1211,10 +1301,10 @@ onMounted(async () => {
// 获取告警类型
const res = await robotApi.getEventTypes();
if (res.code === 200 && Array.isArray(res.data)) {
- eventTypeOptions.value = ['全部告警', ...res.data];
+ eventTypeOptions.value = ["全部告警", ...res.data];
}
} catch (e) {
- console.error('获取告警类型失败', e);
+ console.error("获取告警类型失败", e);
}
});
@@ -1222,8 +1312,12 @@ onUnmounted(() => {
stopAutoScroll();
// 移除任务列表的事件监听
if (taskListRef.value) {
- taskListRef.value.removeEventListener('mouseenter', () => handleMouseEnter('taskList'));
- taskListRef.value.removeEventListener('mouseleave', () => handleMouseLeave('taskList'));
+ taskListRef.value.removeEventListener("mouseenter", () =>
+ handleMouseEnter("taskList")
+ );
+ taskListRef.value.removeEventListener("mouseleave", () =>
+ handleMouseLeave("taskList")
+ );
}
});
@@ -1255,12 +1349,12 @@ const fetchAlarmDetail = async (messageId) => {
try {
const res = await robotApi.getAlarmEventDetail(messageId);
if (res.code === 200) {
- console.log('获取告警详情成功:', res.data);
+ console.log("获取告警详情成功:", res.data);
return res.data;
}
return null;
} catch (error) {
- console.error('获取告警详情失败:', error);
+ console.error("获取告警详情失败:", error);
return null;
}
};
@@ -1272,23 +1366,26 @@ const showAlarmDetail = async (alarm) => {
if (alarm.messageId) {
detailData = await fetchAlarmDetail(alarm.messageId);
}
-
+
// 合并详情数据和本地数据
currentAlarmData.value = {
- title: '告警详情',
+ title: "告警详情",
messageId: alarm.messageId,
- mainImage: detailData?.imageUrl && detailData.imageUrl.length > 0
- ? detailData.imageUrl[0]
- : (alarm.imageUrl && alarm.imageUrl.length > 0 ? alarm.imageUrl[0] : '../assets/img/camera-thumb1.jpg'),
+ mainImage:
+ detailData?.imageUrl && detailData.imageUrl.length > 0
+ ? detailData.imageUrl[0]
+ : alarm.imageUrl && alarm.imageUrl.length > 0
+ ? alarm.imageUrl[0]
+ : "../assets/img/camera-thumb1.jpg",
subImages: [],
type: alarm.content,
time: alarm.time,
robotName: detailData?.name || robotId.value,
- status: alarm.status === 'pending' ? '未处理' : '已处理',
- temperature: detailData?.temperature || alarm.temperature || '',
- remark: detailData?.remark || alarm.remark || ''
+ status: alarm.status === "pending" ? "未处理" : "已处理",
+ temperature: detailData?.temperature || alarm.temperature || "",
+ remark: detailData?.remark || alarm.remark || "",
};
-
+
// 添加视频流地址
if (detailData) {
// 添加子图片(如果有)
@@ -1299,18 +1396,19 @@ const showAlarmDetail = async (alarm) => {
} else {
currentAlarmData.value.subImages = [];
}
-
+
// 添加视频流地址
- currentAlarmData.value.flvPtz = detailData.flvPtz || '';
- currentAlarmData.value.flvTherm = detailData.flvTherm || '';
- currentAlarmData.value.flvThermLight = detailData.flvThermLight || '';
+ currentAlarmData.value.flvPtz = detailData.flvPtz || "";
+ currentAlarmData.value.flvTherm = detailData.flvTherm || "";
+ currentAlarmData.value.flvThermLight = detailData.flvThermLight || "";
} else {
// 使用本地数据
- currentAlarmData.value.subImages = alarm.imageUrl && alarm.imageUrl.length > 1
- ? alarm.imageUrl.slice(1)
- : [];
+ currentAlarmData.value.subImages =
+ alarm.imageUrl && alarm.imageUrl.length > 1
+ ? alarm.imageUrl.slice(1)
+ : [];
}
-
+
showAlarmModal.value = true;
};
@@ -1321,23 +1419,26 @@ const showMeterDetail = async (alarm) => {
if (alarm.messageId) {
detailData = await fetchAlarmDetail(alarm.messageId);
}
-
+
// 合并详情数据和本地数据
currentMeterData.value = {
- title: '仪表异常详情',
+ title: "仪表异常详情",
messageId: alarm.messageId,
- mainImage: detailData?.imageUrl && detailData.imageUrl.length > 0
- ? detailData.imageUrl[0]
- : (alarm.imageUrl && alarm.imageUrl.length > 0 ? alarm.imageUrl[0] : '../assets/img/camera-thumb1.jpg'),
+ mainImage:
+ detailData?.imageUrl && detailData.imageUrl.length > 0
+ ? detailData.imageUrl[0]
+ : alarm.imageUrl && alarm.imageUrl.length > 0
+ ? alarm.imageUrl[0]
+ : "../assets/img/camera-thumb1.jpg",
subImages: [],
type: alarm.content,
time: alarm.time,
robotName: detailData?.name || robotId.value,
- status: alarm.status === 'pending' ? '未处理' : '已处理',
- temperature: detailData?.temperature || alarm.temperature || '',
- remark: detailData?.remark || alarm.remark || ''
+ status: alarm.status === "pending" ? "未处理" : "已处理",
+ temperature: detailData?.temperature || alarm.temperature || "",
+ remark: detailData?.remark || alarm.remark || "",
};
-
+
// 添加视频流地址
if (detailData) {
// 添加子图片(如果有)
@@ -1348,24 +1449,25 @@ const showMeterDetail = async (alarm) => {
} else {
currentMeterData.value.subImages = [];
}
-
+
// 添加视频流地址
- currentMeterData.value.flvPtz = detailData.flvPtz || '';
- currentMeterData.value.flvTherm = detailData.flvTherm || '';
- currentMeterData.value.flvThermLight = detailData.flvThermLight || '';
+ currentMeterData.value.flvPtz = detailData.flvPtz || "";
+ currentMeterData.value.flvTherm = detailData.flvTherm || "";
+ currentMeterData.value.flvThermLight = detailData.flvThermLight || "";
} else {
// 使用本地数据
- currentMeterData.value.subImages = alarm.imageUrl && alarm.imageUrl.length > 1
- ? alarm.imageUrl.slice(1)
- : [];
+ currentMeterData.value.subImages =
+ alarm.imageUrl && alarm.imageUrl.length > 1
+ ? alarm.imageUrl.slice(1)
+ : [];
}
-
+
showMeterModal.value = true;
};
// 处理告警确认
const handleAlarmConfirm = async (data) => {
- console.log('确认处理告警:', data);
+ console.log("确认处理告警:", data);
// 调用处理单个告警的方法
await handleSingleAlarm(data);
showAlarmModal.value = false;
@@ -1373,7 +1475,7 @@ const handleAlarmConfirm = async (data) => {
// 处理告警上报
const handleAlarmReport = async (data) => {
- console.log('处理并上报告警:', data);
+ console.log("处理并上报告警:", data);
// 调用处理单个告警的方法
await handleSingleAlarm(data);
showAlarmModal.value = false;
@@ -1381,7 +1483,7 @@ const handleAlarmReport = async (data) => {
// 处理仪表确认
const handleMeterConfirm = async (data) => {
- console.log('确认处理仪表异常:', data);
+ console.log("确认处理仪表异常:", data);
// 调用处理单个告警的方法
await handleSingleAlarm(data);
showMeterModal.value = false;
@@ -1389,7 +1491,7 @@ const handleMeterConfirm = async (data) => {
// 处理仪表上报
const handleMeterReport = async (data) => {
- console.log('处理并上报仪表异常:', data);
+ console.log("处理并上报仪表异常:", data);
// 调用处理单个告警的方法
await handleSingleAlarm(data);
showMeterModal.value = false;
@@ -1400,95 +1502,98 @@ const handleSingleAlarm = async (data) => {
try {
// 获取当前告警的messageId
const messageId = data.messageId;
-
+
if (!messageId) {
- console.error('缺少messageId,无法处理告警');
+ console.error("缺少messageId,无法处理告警");
return;
}
-
+
const res = await robotApi.handleSingleAlarmEvent({
messageId: messageId,
- remark: data.remark || '',
- number: robotId.value
+ remark: data.remark || "",
+ number: robotId.value,
});
if (res.code === 200) {
- console.log('处理单个告警成功');
-
+ console.log("处理单个告警成功");
+
// 重新获取告警列表
await getAlarmEventList();
-
+
// 更新告警数量
await getAlarmEventCount();
}
} catch (error) {
- console.error('处理单个告警失败:', error);
+ console.error("处理单个告警失败:", error);
}
};
const showViewAllModal = ref(false);
const currentEvent = ref({
- mainImage: '../assets/img/camera-thumb1.jpg',
- subImages: ['../assets/img/camera-thumb2.jpg', '../assets/img/camera-thumb3.jpg'],
- type: '紧急避障',
- time: '2025-05-01 12:30:09',
- robotName: 'X32305000019',
- status: '未处理'
+ mainImage: "../assets/img/camera-thumb1.jpg",
+ subImages: [
+ "../assets/img/camera-thumb2.jpg",
+ "../assets/img/camera-thumb3.jpg",
+ ],
+ type: "紧急避障",
+ time: "2025-05-01 12:30:09",
+ robotName: "X32305000019",
+ status: "未处理",
});
const monitorList = ref([
- { title: '监控视图1', image: '../assets/img/camera-thumb1.jpg' },
- { title: '监控视图2', image: '../assets/img/camera-thumb2.jpg' },
- { title: '监控视图3', image: '../assets/img/camera-thumb3.jpg' },
- { title: '监控视图4', image: '../assets/img/camera-thumb1.jpg' },
- { title: '监控视图5', image: '../assets/img/camera-thumb2.jpg' },
- { title: '监控视图6', image: '../assets/img/camera-thumb3.jpg' }
+ { title: "监控视图1", image: "../assets/img/camera-thumb1.jpg" },
+ { title: "监控视图2", image: "../assets/img/camera-thumb2.jpg" },
+ { title: "监控视图3", image: "../assets/img/camera-thumb3.jpg" },
+ { title: "监控视图4", image: "../assets/img/camera-thumb1.jpg" },
+ { title: "监控视图5", image: "../assets/img/camera-thumb2.jpg" },
+ { title: "监控视图6", image: "../assets/img/camera-thumb3.jpg" },
]);
const handleConfirm = async (data) => {
- console.log('确认处理告警事件:', data);
-
+ console.log("确认处理告警事件:", data);
+
// 如果有messageId,处理单个告警事件
if (data.messageId) {
try {
const res = await robotApi.handleSingleAlarmEvent({
messageId: data.messageId,
- remark: data.remark || '',
- number: robotId.value
+ remark: data.remark || "",
+ number: robotId.value,
});
if (res.code === 200) {
- console.log('处理单个告警成功');
-
+ console.log("处理单个告警成功");
+
// 更新告警列表
await getAlarmEventList();
-
+
// 更新告警数量
await getAlarmEventCount();
-
+
// 关闭弹窗
showViewAllModal.value = false;
} else {
- console.error('处理单个告警失败:', res);
+ console.error("处理单个告警失败:", res);
}
} catch (error) {
- console.error('处理单个告警异常:', error);
+ console.error("处理单个告警异常:", error);
}
} else {
- console.log('缺少messageId,无法处理告警');
+ console.log("缺少messageId,无法处理告警");
showViewAllModal.value = false;
}
};
const handleReport = async (data) => {
- console.log('处理并上报告警事件:', data);
-
+ console.log("处理并上报告警事件:", data);
+
// 处理逻辑与handleConfirm相同,可能后续会有不同
await handleConfirm(data);
};
// 登录接口调用
-const tenantInfoId = ref('');
+const tenantInfoId = ref("");
const login = async () => {
try {
const res = await robotApi.login({
@@ -1496,13 +1601,13 @@ const login = async () => {
password: "123456",
userType: "2",
crc: "0f007401b091",
- lang: "zh_CN"
+ lang: "zh_CN",
});
if (res.code === 200) {
- localStorage.setItem('token', res.data.token);
+ localStorage.setItem("token", res.data.token);
// 更新用户信息
tenantInfoId.value = res.data.userInfo.tenantInfoId;
- console.log("tenantInfoId.value-----------",tenantInfoId.value);
+ console.log("tenantInfoId.value-----------", tenantInfoId.value);
// getGroupInfoData();
// 初始化WebSocket连接
initWebSocket();
@@ -1510,22 +1615,22 @@ const login = async () => {
}
return false;
} catch (error) {
- console.error('登录失败:', error);
+ console.error("登录失败:", error);
return false;
}
};
// 视频流地址
const streamUrls = ref({
- ptz: '', // 云台摄像头
- front: '', // 前置摄像头
- therm: '' // 热成像
+ ptz: "", // 云台摄像头
+ front: "", // 前置摄像头
+ therm: "", // 热成像
});
// 在开发环境中添加测试用的视频流地址
if (import.meta.env.DEV) {
// 仅在开发环境中设置测试地址
- console.log('开发环境,设置测试视频流地址');
+ console.log("开发环境,设置测试视频流地址");
// 这里可以设置测试用的WebRTC流地址
// 使用您的实际服务器地址
// streamUrls.value = {
@@ -1533,81 +1638,112 @@ if (import.meta.env.DEV) {
// front: 'webrtc://qvs-live.thirdmonitor.concoai.com:447/rtc/v1/play/31011500991180041301_34020000001320000002',
// therm: 'webrtc://qvs-live.thirdmonitor.concoai.com:447/rtc/v1/play/31011500991180041301_34020000001320000003'
// };
-
+
// 测试函数:手动设置流地址并测试连接
window.testWebRTC = (streamId) => {
// 使用正确的URL格式,只到/rtc/v1/play
- const baseUrl = 'webrtc://qvs-live.thirdmonitor.concoai.com:447/rtc/v1/play/';
+ const baseUrl =
+ "webrtc://qvs-live.thirdmonitor.concoai.com:447/rtc/v1/play/";
streamUrls.value = {
ptz: baseUrl + streamId,
- front: '',
- therm: ''
+ front: "",
+ therm: "",
};
- console.log('设置测试流地址:', streamUrls.value.ptz);
-
+ console.log("设置测试流地址:", streamUrls.value.ptz);
+
// 添加一个直接测试函数,用于测试不同的URL格式
window.testWebRTCFormat = (format) => {
let testUrl;
- if (format === 'short') {
+ if (format === "short") {
// 只到/rtc/v1/play
- testUrl = 'webrtc://qvs-live.thirdmonitor.concoai.com:447/rtc/v1/play';
+ testUrl = "webrtc://qvs-live.thirdmonitor.concoai.com:447/rtc/v1/play";
} else {
// 包含流ID
- testUrl = 'webrtc://qvs-live.thirdmonitor.concoai.com:447/rtc/v1/play/' + streamId;
+ testUrl =
+ "webrtc://qvs-live.thirdmonitor.concoai.com:447/rtc/v1/play/" +
+ streamId;
}
streamUrls.value = {
ptz: testUrl,
- front: '',
- therm: ''
+ front: "",
+ therm: "",
};
- console.log('测试不同URL格式:', testUrl);
+ console.log("测试不同URL格式:", testUrl);
};
};
}
// 添加上一次的状态记录
const lastStatus = ref({
- power: '',
- temperature: '',
- humidity: '',
- pm2_5: '',
- pm10: '',
- voltage: '',
- ststusName: '',
- buttonStop: '',
+ power: "",
+ temperature: "",
+ humidity: "",
+ pm2_5: "",
+ pm10: "",
+ voltage: "",
+ ststusName: "",
+ buttonStop: "",
// 添加视频流地址相关字段
- flvPtz: '',
- flvTherm: '',
- flvThermLight: ''
+ flvPtz: "",
+ flvTherm: "",
+ flvThermLight: "",
});
// 检查数据是否发生变化
const hasStatusChanged = (newData) => {
- const keys = ['power', 'temperature', 'humidity', 'pm2_5', 'pm10', 'voltage', 'ststusName', 'buttonStop'];
- const changed = keys.some(key => lastStatus.value[key] !== newData[key]);
+ const keys = [
+ "power",
+ "temperature",
+ "humidity",
+ "pm2_5",
+ "pm10",
+ "voltage",
+ "ststusName",
+ "buttonStop",
+ ];
+ const changed = keys.some((key) => lastStatus.value[key] !== newData[key]);
if (changed) {
- console.log('状态数据发生变化:', keys.filter(key => lastStatus.value[key] !== newData[key]));
+ console.log(
+ "状态数据发生变化:",
+ keys.filter((key) => lastStatus.value[key] !== newData[key])
+ );
}
return changed;
};
// 检查视频流地址是否发生变化
const hasStreamUrlsChanged = (newData) => {
- const streamKeys = ['flvPtz', 'flvTherm', 'flvThermLight'];
- const changed = streamKeys.some(key => lastStatus.value[key] !== newData[key] && newData[key]);
+ const streamKeys = ["flvPtz", "flvTherm", "flvThermLight"];
+ const changed = streamKeys.some(
+ (key) => lastStatus.value[key] !== newData[key] && newData[key]
+ );
if (changed) {
- console.log('视频流地址发生变化:', streamKeys.filter(key => lastStatus.value[key] !== newData[key] && newData[key]));
+ console.log(
+ "视频流地址发生变化:",
+ streamKeys.filter(
+ (key) => lastStatus.value[key] !== newData[key] && newData[key]
+ )
+ );
}
return changed;
};
// 更新上一次的状态
const updateLastStatus = (data) => {
- const keys = ['power', 'temperature', 'humidity', 'pm2_5', 'pm10', 'voltage', 'ststusName', 'buttonStop'];
- keys.forEach(key => {
+ const keys = [
+ "power",
+ "temperature",
+ "humidity",
+ "pm2_5",
+ "pm10",
+ "voltage",
+ "ststusName",
+ "buttonStop",
+ ];
+ keys.forEach((key) => {
lastStatus.value[key] = data[key];
});
-
+
// 更新视频流地址状态
if (data.flvPtz) lastStatus.value.flvPtz = data.flvPtz;
if (data.flvTherm) lastStatus.value.flvTherm = data.flvTherm;
@@ -1628,21 +1764,21 @@ const debounce = (fn, delay) => {
// WebSocket相关数据
let wsClient = null; // 改为全局变量
const robotInfo = ref({
- robotId: '',
- groupingId: '',
- onlineStatus: '',
- number: ''
+ robotId: "",
+ groupingId: "",
+ onlineStatus: "",
+ number: "",
});
const robotStatus = ref({
- power: '',
- temperature: '',
- humidity: '',
- pm2_5: '',
- pm10: '',
- voltage: '',
- ststusName: '',
- mileage: ''
+ power: "",
+ temperature: "",
+ humidity: "",
+ pm2_5: "",
+ pm10: "",
+ voltage: "",
+ ststusName: "",
+ mileage: "",
});
// 添加防抖处理的getRobotDetailData
@@ -1651,24 +1787,24 @@ const debouncedGetRobotDetail = debounce(async (robotId) => {
const res = await robotApi.getRobotDetail(robotId);
if (res.code === 200) {
console.log("机器人详情数据:", res.data);
-
+
// 更新视频流地址(只在地址发生变化时更新)
const streamChanged = {
ptz: res.data.flvPtz !== lastStatus.value.flvPtz,
therm: res.data.flvTherm !== lastStatus.value.flvTherm,
- front: res.data.flvThermLight !== lastStatus.value.flvThermLight
+ front: res.data.flvThermLight !== lastStatus.value.flvThermLight,
};
-
+
if (streamChanged.ptz && res.data.flvPtz) {
console.log("更新云台摄像头地址");
streamUrls.value.ptz = res.data.flvPtz;
}
-
+
if (streamChanged.therm && res.data.flvTherm) {
console.log("更新热成像摄像头地址");
streamUrls.value.therm = res.data.flvTherm;
}
-
+
if (streamChanged.front && res.data.flvThermLight) {
console.log("更新前置摄像头地址");
streamUrls.value.front = res.data.flvThermLight;
@@ -1683,39 +1819,60 @@ const debouncedGetRobotDetail = debounce(async (robotId) => {
pm10: res.data.pm10,
voltage: res.data.voltage,
ststusName: res.data.ststusName,
- mileage: res.data.totalMileage
+ mileage: res.data.totalMileage,
};
-
+
// 更新环境数据
envData.value = [
- { icon: "./img/pic1.png", label: "温度", value: `${res.data.temperature}°C` },
- { icon: "./img/pic2.png", label: "湿度", value: `${res.data.humidity}%` },
- { icon: "./img/pic3.png", label: "PM2.5", value: `${res.data.pm2_5}ug/m3` },
- { icon: "./img/pic4.png", label: "PM10", value: `${res.data.pm10}ug/m3` }
+ {
+ icon: "./img/pic1.png",
+ label: "温度",
+ value: `${res.data.temperature}°C`,
+ },
+ {
+ icon: "./img/pic2.png",
+ label: "湿度",
+ value: `${res.data.humidity}%`,
+ },
+ {
+ icon: "./img/pic3.png",
+ label: "PM2.5",
+ value: `${res.data.pm2_5}ug/m3`,
+ },
+ {
+ icon: "./img/pic4.png",
+ label: "PM10",
+ value: `${res.data.pm10}ug/m3`,
+ },
];
-
+
// 更新机器人信息
robotInfoItems.value = [
{ label: "电量:", value: `${res.data.power}%` },
{ label: "电池电压:", value: `${res.data.voltage}v` },
{ label: "运行模式:", value: res.data.ststusName },
- { label: "急停:", value: res.data.buttonStopStatus === "1" ? "关闭" : "开启" }
+ {
+ label: "急停:",
+ value: res.data.buttonStopStatus === "1" ? "关闭" : "开启",
+ },
];
-
+
// 更新累计数据
addData.value = [
{ label: "累计运行", value: `${res.data.totalRunTime}h` },
{ label: "累计里程", value: `${res.data.totalMileage}km` },
- { label: "充电次数", value: res.data.powerNums }
+ { label: "充电次数", value: res.data.powerNums },
];
-
+
// 更新lastStatus中的视频流地址
lastStatus.value.flvPtz = res.data.flvPtz || lastStatus.value.flvPtz;
- lastStatus.value.flvTherm = res.data.flvTherm || lastStatus.value.flvTherm;
- lastStatus.value.flvThermLight = res.data.flvThermLight || lastStatus.value.flvThermLight;
+ lastStatus.value.flvTherm =
+ res.data.flvTherm || lastStatus.value.flvTherm;
+ lastStatus.value.flvThermLight =
+ res.data.flvThermLight || lastStatus.value.flvThermLight;
}
} catch (error) {
- console.error('获取机器人详情失败:', error);
+ console.error("获取机器人详情失败:", error);
}
}, 1000); // 1秒的防抖时间
@@ -1723,13 +1880,13 @@ const debouncedGetRobotDetail = debounce(async (robotId) => {
const initWebSocket = () => {
// 如果组件正在卸载,不要重新连接
if (isUnmounting.value) {
- console.log('组件正在卸载,跳过WebSocket连接');
+ console.log("组件正在卸载,跳过WebSocket连接");
return;
}
// 如果已存在连接,先关闭
if (wsClient) {
- console.log('关闭已存在的WebSocket连接');
+ console.log("关闭已存在的WebSocket连接");
wsClient.close();
wsClient = null;
}
@@ -1737,48 +1894,48 @@ const initWebSocket = () => {
const timestamp = Date.now();
const userId = `rbsstaff1_${timestamp}_${tenantInfoId.value}`;
const wsUrl = `wss://rest.concoai.com/imserver/${userId}`;
-
+
wsClient = new WebSocketClient({
url: wsUrl,
onMessage: handleWebSocketMessage,
onError: (error) => {
- console.error('WebSocket错误:', error);
+ console.error("WebSocket错误:", error);
},
onClose: () => {
- console.log('WebSocket连接关闭');
+ console.log("WebSocket连接关闭");
wsClient = null;
-
+
// 只有在非卸载状态下才尝试重连
if (!isUnmounting.value) {
- console.log('尝试重新连接WebSocket...');
+ console.log("尝试重新连接WebSocket...");
setTimeout(() => {
initWebSocket();
}, 3000);
}
},
onOpen: () => {
- console.log('WebSocket连接成功');
- }
+ console.log("WebSocket连接成功");
+ },
});
-
+
wsClient.connect();
};
// 修改handleWebSocketMessage函数
const handleWebSocketMessage = (data) => {
- console.log('收到WebSocket消息:', data);
-
+ console.log("收到WebSocket消息:", data);
+
// 处理第一类消息 - 机器人基本信息
- if (data.socketType === '7') {
+ if (data.socketType === "7") {
// 避免重复处理相同的机器人信息
if (robotInfo.value.robotId !== data.robotId) {
robotInfo.value = {
robotId: data.robotId,
groupingId: data.groupingId,
onlineStatus: data.onlineStatus,
- number: data.number
+ number: data.number,
};
-
+
// 获取班组信息
getDutyInfo(data.robotId);
// 首次获取机器人详情
@@ -1786,25 +1943,25 @@ const handleWebSocketMessage = (data) => {
fetchTasks(robotInfo.value.robotId);
}
}
-
+
// 处理第二类消息 - 机器人状态信息
- if (data.socketType === '1') {
+ if (data.socketType === "1") {
// 检查关键数据是否发生变化
const statusChanged = hasStatusChanged(data);
const streamUrlsChanged = hasStreamUrlsChanged(data);
-
+
if (statusChanged || streamUrlsChanged) {
- console.log('数据发生变化,调用详情接口');
+ console.log("数据发生变化,调用详情接口");
debouncedGetRobotDetail(data.robotId);
updateLastStatus(data);
} else {
- console.log('数据未发生变化,跳过详情接口调用');
+ console.log("数据未发生变化,跳过详情接口调用");
}
}
-
+
// 处理第三类消息 - 事件未处理通知
- if (data.socketType === '2') {
- console.log('收到未处理事件通知:', data);
+ if (data.socketType === "2") {
+ console.log("收到未处理事件通知:", data);
// 将新的未处理事件添加到告警列表
const newAlarm = {
id: data.eventId,
@@ -1816,11 +1973,13 @@ const handleWebSocketMessage = (data) => {
content: data.eName,
time: formatEventTime(data.eventInsDate || data.time),
position: data.positonName,
- imageUrl: data.imgUrl
+ imageUrl: data.imgUrl,
};
-
+
// 检查是否已存在相同ID的告警
- const existingIndex = alarmList.value.findIndex(a => a.id === newAlarm.id);
+ const existingIndex = alarmList.value.findIndex(
+ (a) => a.id === newAlarm.id
+ );
if (existingIndex === -1) {
// 不存在则添加到列表头部
alarmList.value = [newAlarm, ...alarmList.value];
@@ -1828,23 +1987,25 @@ const handleWebSocketMessage = (data) => {
// 存在则更新
alarmList.value.splice(existingIndex, 1, newAlarm);
}
-
+
// 更新告警计数
- console.log('更新后的未处理告警数量:', pendingCount.value);
+ console.log("更新后的未处理告警数量:", pendingCount.value);
}
-
+
// 处理第四类消息 - 事件超时未处理通知
- if (data.socketType === '6') {
- console.log('收到超时未处理事件通知:', data);
+ if (data.socketType === "6") {
+ console.log("收到超时未处理事件通知:", data);
// 更新对应的告警状态为超时未处理
- const existingIndex = alarmList.value.findIndex(a => a.id === data.eventId);
+ const existingIndex = alarmList.value.findIndex(
+ (a) => a.id === data.eventId
+ );
if (existingIndex !== -1) {
// 更新告警状态
const updatedAlarm = {
...alarmList.value[existingIndex],
status: "timeout", // 添加一个新的状态值表示超时未处理
content: data.eName,
- time: formatEventTime(data.eventInsDate)
+ time: formatEventTime(data.eventInsDate),
};
alarmList.value.splice(existingIndex, 1, updatedAlarm);
} else {
@@ -1857,7 +2018,7 @@ const handleWebSocketMessage = (data) => {
isRead: false,
type: "danger", // 超时未处理都标记为危险级别
content: data.eName,
- time: formatEventTime(data.eventInsDate)
+ time: formatEventTime(data.eventInsDate),
};
alarmList.value = [newTimeoutAlarm, ...alarmList.value];
}
@@ -1866,13 +2027,13 @@ const handleWebSocketMessage = (data) => {
// 添加格式化事件时间的辅助函数
const formatEventTime = (timeStr) => {
- if (!timeStr) return '';
-
+ if (!timeStr) return "";
+
// 如果是格式化的日期时间字符串,直接返回
- if (timeStr.includes('-')) {
+ if (timeStr.includes("-")) {
return timeStr;
}
-
+
// 如果是yyyyMMddHHmmss格式
if (timeStr.length === 14) {
const year = timeStr.substring(0, 4);
@@ -1883,7 +2044,7 @@ const formatEventTime = (timeStr) => {
const second = timeStr.substring(12, 14);
return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
}
-
+
return timeStr;
};
@@ -1894,20 +2055,32 @@ const getDutyInfo = async (robotId) => {
if (res.code === 200) {
// 更新班组信息
groupInfo.value = [
- { icon: "./img/info1.png", label: "当前分组", value: res.data.groupName || "室外巡检" },
- { icon: "./img/info2.png", label: "当前班次", value: res.data.dutyTime || "00:00-23:59" },
- { icon: "./img/info3.png", label: "当前人员", value: res.data.dutyUser || "员工1" }
+ {
+ icon: "./img/info1.png",
+ label: "当前分组",
+ value: res.data.groupName || "室外巡检",
+ },
+ {
+ icon: "./img/info2.png",
+ label: "当前班次",
+ value: res.data.dutyTime || "00:00-23:59",
+ },
+ {
+ icon: "./img/info3.png",
+ label: "当前人员",
+ value: res.data.dutyUser || "员工1",
+ },
];
}
} catch (error) {
- console.error('获取班组信息失败:', error);
+ console.error("获取班组信息失败:", error);
}
};
// 组件卸载时关闭WebSocket连接
onUnmounted(() => {
if (wsClient) {
- console.log('组件卸载,关闭WebSocket连接');
+ console.log("组件卸载,关闭WebSocket连接");
wsClient.close();
wsClient = null;
}
@@ -1915,15 +2088,13 @@ onUnmounted(() => {
// 添加确认弹窗相关的状态
const showConfirmDialog = ref(false);
-const confirmDialogMessage = ref('');
+const confirmDialogMessage = ref("");
// 监听alarmTab变化
watch(alarmTab, async (newValue) => {
- console.log('标签切换为:', newValue);
- // 获取告警列表
+ isLoading.value = true; // 1. 优先设置loading
+ alarmList.value = []; // 2. 立即清空数据
await getAlarmEventList();
-
- // 重新获取告警数量
await getAlarmEventCount();
});
@@ -1931,27 +2102,24 @@ watch(alarmTab, async (newValue) => {
const handleAlarmEvent = async (alarm) => {
try {
// 如果是仪表类型的告警或日常巡检,直接处理,不弹窗
- if (alarm.group === "meter" || alarm.content === "日常巡检") {
- // 检查 messageId 是否存在
- if (!alarm.messageId) {
- window.$message && window.$message.error('缺少 messageId,无法处理该告警');
- return;
- }
- // 可选:添加 loading 状态
- isLoading.value = true;
- try {
- await handleSingleAlarm({ messageId: alarm.messageId });
- } catch (err) {
- window.$message && window.$message.error('处理仪表识别告警失败');
- } finally {
- isLoading.value = false;
- }
- } else {
- // 其他类型的告警弹窗详情
- await showAlarmDetail(alarm);
+
+ // 检查 messageId 是否存在
+ if (!alarm.messageId) {
+ window.$message &&
+ window.$message.error("缺少 messageId,无法处理该告警");
+ return;
+ }
+ // 可选:添加 loading 状态
+ isLoading.value = true;
+ try {
+ await handleSingleAlarm({ messageId: alarm.messageId });
+ } catch (err) {
+ window.$message && window.$message.error("处理仪表识别告警失败");
+ } finally {
+ isLoading.value = false;
}
} catch (error) {
- console.error('处理告警事件失败:', error);
+ console.error("处理告警事件失败:", error);
}
};
@@ -1960,7 +2128,7 @@ const handleAlarmEvent = async (alarm) => {
const eventListData = ref([]);
// 告警类型选项
-const eventTypeOptions = ref(['全部告警']);
+const eventTypeOptions = ref(["全部告警"]);
// 页面加载时获取告警类型
onMounted(async () => {
@@ -1968,12 +2136,11 @@ onMounted(async () => {
// 获取告警类型
const res = await robotApi.getEventTypes();
if (res.code === 200 && Array.isArray(res.data)) {
- eventTypeOptions.value = ['全部告警', ...res.data];
+ eventTypeOptions.value = ["全部告警", ...res.data];
}
} catch (e) {
- console.error('获取告警类型失败', e);
+ console.error("获取告警类型失败", e);
}
-
});
@@ -1990,14 +2157,14 @@ onMounted(async () => {
/* 主体内容样式 */
.main-content {
display: flex;
- height: calc(100vh - 50px);
- padding:32px;
+ height: calc(100% - 100px);
+ padding: 32px;
gap: 10px;
}
/* 左侧面板 */
.left-panel {
- width: 25rem;
+ width: 400px;
display: flex;
flex-direction: column;
gap: 15px;
@@ -2033,12 +2200,14 @@ onMounted(async () => {
/* 右侧面板 */
.right-panel {
- width: 25rem;
+ width: 400px;
display: flex;
flex-direction: column;
gap: 10px;
}
-
+.alarm-overview{
+ margin:10px 0;
+}
/* 告警相关样式 */
.tab-item {
padding: 10px;
@@ -2095,7 +2264,7 @@ onMounted(async () => {
.alarm-time {
font-size: 12px;
- color: #00CEEA;
+ color: #00ceea;
margin-bottom: 5px;
}
@@ -2124,12 +2293,12 @@ onMounted(async () => {
display: flex;
align-items: center;
justify-content: flex-start;
- gap: 8px;
+ gap: 10px;
}
.alarm-icon {
width: 16px;
- height: 16px;
+ height: 16px;
border-radius: 50%;
}
@@ -2143,7 +2312,6 @@ onMounted(async () => {
justify-content: flex-end;
}
-
.alarm-counts {
display: flex;
align-items: center;
@@ -2188,7 +2356,7 @@ onMounted(async () => {
position: relative;
background: rgba(0, 145, 169, 0.2);
color: #b9e8ff;
- border: 1px solid #0091A9;
+ border: 1px solid #0091a9;
border-radius: 2px;
padding: 2px 14px;
font-size: 13px;
@@ -2213,7 +2381,7 @@ onMounted(async () => {
}
.process-all-btn {
- background: #0091A9;
+ background: #0091a9;
color: #b9e8ff;
border: none;
border-radius: 2px;
@@ -2240,7 +2408,7 @@ onMounted(async () => {
}
.filter-divider {
- color: #00ffff;
+ color: #b9e8ff;
margin: 0 4px;
}
@@ -2251,7 +2419,9 @@ onMounted(async () => {
flex: 1;
position: relative;
cursor: pointer;
- min-width: 120px;
+ min-width: 300px;
+ max-width: 300px;
+ width: 300px;
outline: none;
}
@@ -2276,28 +2446,44 @@ onMounted(async () => {
.alarm-select-dropdown {
position: absolute;
- right: 0;
- top: 110%;
+ right: -10px;
+ top: 130%;
background: #00273A;
- border-radius: 4px;
- box-shadow: 0 2px 8px rgba(0,0,0,0.15);
- min-width: 100px;
+ border-radius: 6px;
+ border:1px solid #335261;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+ width: 320px;
z-index: 10;
padding: 0;
margin: 0;
list-style: none;
}
+.alarm-select-dropdown li:first-child {
+ border-radius: 6px 6px 0 0;
+}
+.alarm-select-dropdown li:last-child {
+ border-radius: 0 0 6px 6px;
+}
.alarm-select-dropdown li {
- color: #b9e8ff;
- padding: 6px 16px;
+ color: #B9E8FF;
+ background: #00273A;
+ padding: 0 16px;
cursor: pointer;
white-space: nowrap;
+ font-size: 13px;
+ line-height: 36px;
+ margin: 0;
+}
+
+.alarm-select-dropdown li.active {
+ background: #0091A9;
+ color: #fff;
}
.alarm-select-dropdown li:hover {
- background: #00ffff22;
- color: #00ffff;
+ background: #005C71;
+ color: #fff;
}
.alarm-level {
@@ -2331,14 +2517,15 @@ onMounted(async () => {
flex-direction: column;
gap: 15px;
}
-.thumbnail-container1{
+.thumbnail-container1 {
height: 100%;
flex: 1;
display: flex;
flex-direction: column;
gap: 15px;
position: relative;
-
+
+ border-radius: 8px;
}
.camera-title {
font-size: 14px;
@@ -2347,15 +2534,17 @@ onMounted(async () => {
/* background: rgba(0, 21, 31, 0.3); */
background-color: rgba(0, 0, 0, 0.6);
/* border-radius: 4px 4px 0 0; */
+ border-radius: 8px;
}
.camera-feed {
- height: 55vh; /* 从60vh改为70vh */
+ height: 57vh; /* 从60vh改为70vh */
background: rgba(0, 21, 31, 0.3);
border-radius: 4px;
border: 1px solid rgba(185, 232, 255, 0.3);
position: relative;
overflow: hidden;
+ border-radius: 8px;
}
.camera-feed img {
@@ -2377,13 +2566,19 @@ onMounted(async () => {
display: flex;
flex: 1;
gap: 10px;
+
/* 移除固定高度,使用flex布局 */
}
+.camera-thumbnails img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
.thumbnail-container {
width: 100%;
background: rgba(0, 21, 31, 0.3);
- border-radius: 4px;
+ border-radius: 8px;
/* overflow: hidden; */
position: relative;
display: flex; /* 添加flex布局 */
@@ -2401,15 +2596,16 @@ onMounted(async () => {
left: 0;
right: 0;
padding: 10px 5px;
- font-size: 12px;
+ font-size: 14px;
background: rgba(0, 0, 0, 0.2);
z-index: 1;
}
.thumbnail {
width: 100%;
- flex: 1; /* 使用flex:1代替固定高度 */
-
+ border-radius: 8px !important;
+ height: 28vh;
+ position: relative;
background: rgba(0, 21, 31, 0.3);
display: flex; /* 添加flex布局 */
flex-direction: column; /* 垂直方向flex */
@@ -2438,7 +2634,7 @@ onMounted(async () => {
left: 0;
width: 100vw;
height: 100vh;
- background:url('../../assets/img/alert2.png') no-repeat;
+ background: url("../../assets/img/alert2.png") no-repeat;
background-size: 100% 100%;
display: flex;
align-items: center;
@@ -2465,7 +2661,7 @@ onMounted(async () => {
}
.title {
- color: #B9E8FF;
+ color: #b9e8ff;
font-size: 28px;
letter-spacing: 4px;
padding-left: 20px;
@@ -2498,9 +2694,10 @@ onMounted(async () => {
gap: 10px;
}
-.main-monitor, .monitor-item {
+.main-monitor,
+.monitor-item {
position: relative;
- border: 1px solid rgba(0,206,234,0.7);
+ border: 1px solid rgba(0, 206, 234, 0.7);
border-radius: 4px;
overflow: hidden;
}
@@ -2516,7 +2713,7 @@ onMounted(async () => {
width: 100%;
padding: 5px 10px;
background: rgba(0, 21, 31, 0.2);
- color: #B9E8FF;
+ color: #b9e8ff;
font-size: 12px;
z-index: 1;
}
@@ -2544,7 +2741,7 @@ onMounted(async () => {
.event-info {
background: rgba(0, 21, 31, 0.5);
- border: 1px solid rgba(0,206,234,0.7);
+ border: 1px solid rgba(0, 206, 234, 0.7);
border-radius: 4px;
}
@@ -2556,17 +2753,17 @@ onMounted(async () => {
display: flex;
align-items: center;
justify-content: space-between;
- border-bottom: 1px solid #244C60;
+ border-bottom: 1px solid #244c60;
padding: 10px;
}
.info-item .label {
- color: #B9E8FF;
+ color: #b9e8ff;
margin: 0;
}
.info-item .label:before {
- content: '';
+ content: "";
display: inline-block;
width: 10px;
height: 10px;
@@ -2576,7 +2773,7 @@ onMounted(async () => {
}
.info-item .value {
- color: #B9E8FF;
+ color: #b9e8ff;
margin: 0;
}
@@ -2589,7 +2786,7 @@ onMounted(async () => {
min-height: 130px;
background: rgba(0, 21, 31, 0.3);
border-radius: 4px;
- color: #B9E8FF;
+ color: #b9e8ff;
padding: 10px;
outline: none;
}
@@ -2637,7 +2834,7 @@ onMounted(async () => {
cursor: pointer;
font-size: 14px;
background-size: 100% 100%;
- color: #C6F4FF;
+ color: #c6f4ff;
}
.btn.cancel {
@@ -2657,7 +2854,9 @@ onMounted(async () => {
display: flex;
align-items: center;
padding: 0 32px;
- background: rgba(0, 21, 31, 0.5);
+ /* background: rgba(0, 21, 31, 0.5); */
+ background: url("../assets/img/header.png") no-repeat;
+ background-size: 100% 100%;
border-bottom: 1px solid rgba(185, 232, 255, 0.1);
}
@@ -2672,14 +2871,14 @@ onMounted(async () => {
}
.back-icon {
- width: 20px;
- height: 20px;
+ width: 32px;
+ height: 32px;
background: url("../assets/img/return.png") no-repeat;
background-size: 100% 100%;
}
.robot-id {
- font-size: var(--fsize1);
+ font-size: var(--fsize6);
font-weight: bold;
background: linear-gradient(to top, #b9e8ff 48%, #fff 80%);
-webkit-background-clip: text;
@@ -2703,4 +2902,22 @@ onMounted(async () => {
border-radius: 10px;
margin-left: 5px;
}
+.handled-text {
+ color: #00ffff;
+ font-size: var(--fsize4);
+}
+
+.loading-state {
+ text-align: center;
+ padding: 20px;
+ color: #b9e8ff;
+}
+
+.loading-text {
+ font-size: var(--fsize3);
+ color: #b9e8ff;
+ position: relative;
+ padding-left: 1.25vw; /* 24px at 1920px width */
+}
+
diff --git a/vite.config.js b/vite.config.js
index 8d1e1bd..080c6c4 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -2,19 +2,54 @@ import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from "path";
import dotenv from 'dotenv';
+
+import postcsspxtoviewport from 'postcss-px-to-viewport'
// https://vitejs.dev/config/
// 加载环境变量
-dotenv.config({
- path: process.env.NODE_ENV === 'production' ? '.env.production' : '.env.development',
-});
+// dotenv.config({
+// path: process.env.NODE_ENV === 'production' ? '.env.production' : '.env.development',
+// });
export default defineConfig({
base:'./' ,
plugins: [vue()],
- resolve: {
+ //在这配置插件内容
+ css: {
+ postcss: {
+ plugins: [
+ postcsspxtoviewport({
+ // 要转化的单位
+ unitToConvert: 'px',
+ // UI设计稿的大小
+ viewportWidth: 1920,
+ // 转换后的精度
+ unitPrecision: 6,
+ // 字体转换后的单位
+ fontViewportUnit: 'vw',
+ // 能转换的属性,*表示所有属性,!border表示border不转
+ propList: ['*'],
+ // 指定不转换为视窗单位的类名,
+ selectorBlackList: ['ignore-'],
+ // 最小转换的值,小于等于1不转
+ minPixelValue: 1,
+ // 是否在媒体查询的css代码中也进行转换,默认false
+ mediaQuery: false,
+ // 是否转换后直接更换属性值
+ replace: true,
+ // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
+ exclude: [],
+ // 包含那些文件或者特定文件
+ include: [],
+ // 是否处理横屏情况
+ landscape: false
+ }),
+ ]
+ }
+ },
+ resolve: {
alias: {
"@": resolve(__dirname, "./src")
},