From 2f57847a3f92275abcf8c1adaf186d770224c39c Mon Sep 17 00:00:00 2001 From: piratecaptain37 <132531339+piratecaptain37@users.noreply.github.com> Date: Tue, 28 Apr 2026 17:20:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=91=84=E5=83=8F=E5=A4=B4=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 + src/api/worn/camera.js | 62 ++++ src/views/index.vue | 41 ++- src/views/worn/camera/index.vue | 328 ++++++++++++++++++ .../components/CameraPlayer.vue | 177 ++++++++++ src/views/worn/warehouseDashboard/index.vue | 194 ++++++++++- 6 files changed, 784 insertions(+), 20 deletions(-) create mode 100644 src/api/worn/camera.js create mode 100644 src/views/worn/camera/index.vue create mode 100644 src/views/worn/warehouseDashboard/components/CameraPlayer.vue diff --git a/package.json b/package.json index d89e890..dac7718 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,10 @@ "clipboard": "2.0.11", "echarts": "5.6.0", "element-plus": "2.10.7", + "ezuikit-js": "^9.0.4", "file-saver": "2.0.5", "fuse.js": "6.6.2", + "hls.js": "^1.6.13", "js-beautify": "1.14.11", "js-cookie": "3.0.5", "jsencrypt": "3.3.2", diff --git a/src/api/worn/camera.js b/src/api/worn/camera.js new file mode 100644 index 0000000..4361ce9 --- /dev/null +++ b/src/api/worn/camera.js @@ -0,0 +1,62 @@ +import request from '@/utils/request' + +// 查询摄像头设备列表 +export function listCamera(query) { + return request({ + url: '/worn/camera/list', + method: 'get', + params: query + }) +} + +// 查询摄像头设备详情 +export function getCamera(id) { + return request({ + url: '/worn/camera/' + id, + method: 'get' + }) +} + +// 新增摄像头设备 +export function addCamera(data) { + return request({ + url: '/worn/camera', + method: 'post', + data + }) +} + +// 修改摄像头设备 +export function updateCamera(data) { + return request({ + url: '/worn/camera', + method: 'put', + data + }) +} + +// 删除摄像头设备 +export function delCamera(id) { + return request({ + url: '/worn/camera/' + id, + method: 'delete' + }) +} + +// 获取摄像头播放地址 +export function getCameraPlayUrl(deviceSerial) { + return request({ + url: '/worn/camera/play', + method: 'get', + params: { deviceSerial } + }) +} + +// 获取摄像头播放 token +export function getCameraPlayToken(deviceSerial) { + return request({ + url: '/worn/camera/play/token', + method: 'get', + params: { deviceSerial } + }) +} diff --git a/src/views/index.vue b/src/views/index.vue index 753b6eb..b4958fc 100644 --- a/src/views/index.vue +++ b/src/views/index.vue @@ -272,16 +272,18 @@ function handleWsMessage(data) { } function loadHomeData() { - loadHomeStat() - loadDeviceStat() - loadAlarmStat() - loadAlarmTrend() - loadAlarmType() - loadProjectPage() + return Promise.all([ + loadHomeStat(), + loadDeviceStat(), + loadAlarmStat(), + loadAlarmTrend(), + loadAlarmType(), + loadProjectPage() + ]) } function loadHomeStat() { - getHomeStat().then((res) => { + return getHomeStat().then((res) => { const data = res.data || {} overview.projectTotal = toNumber(data.projectCount, overview.projectTotal) overview.warehouseTotal = toNumber(data.warehouseCount, overview.warehouseTotal) @@ -289,7 +291,7 @@ function loadHomeStat() { } function loadDeviceStat() { - getHomeDeviceStat().then((res) => { + return getHomeDeviceStat().then((res) => { const data = res.data || {} overview.deviceTotal = toNumber(data.total, overview.deviceTotal) overview.onlineCount = toNumber(data.online, overview.onlineCount) @@ -299,7 +301,7 @@ function loadDeviceStat() { } function loadAlarmStat() { - getHomeAlarmStat().then((res) => { + return getHomeAlarmStat().then((res) => { const data = res.data || {} overview.alarmToday = toNumber(data.today, overview.alarmToday) overview.alarmUnhandled = toNumber(data.unhandled, overview.alarmUnhandled) @@ -307,7 +309,7 @@ function loadAlarmStat() { } function loadAlarmTrend() { - getHomeAlarmTrend().then((res) => { + return getHomeAlarmTrend().then((res) => { const list = Array.isArray(res.data) ? res.data : [] const maxCount = Math.max(...list.map((item) => toNumber(item.count, 0)), 1) @@ -319,14 +321,14 @@ function loadAlarmTrend() { } function loadAlarmType() { - getHomeAlarmType().then((res) => { + return getHomeAlarmType().then((res) => { const list = Array.isArray(res.data) ? res.data : [] exceptionStats.total = list.reduce((sum, item) => sum + toNumber(item.value, 0), 0) }) } function loadProjectPage() { - getHomeProjectList().then((res) => { + return getHomeProjectList().then((res) => { const list = Array.isArray(res.data) ? res.data : [] projectList.value = list.map(normalizeProject).sort(sortProjectWarehouse) if (projectPage.value > projectPageTotal.value) { @@ -354,7 +356,8 @@ function openWarehouseDetail(item) { query: { deptId: item.deptId, warehouseName: item.warehouseName, - projectName: item.name + projectName: item.name, + deviceSerial: item.deviceSerial || '' } }) } @@ -369,6 +372,7 @@ function normalizeProject(item, index) { deptId: item.deptId || item.warehouseId || item.id, name, warehouseName, + deviceSerial: item.deviceSerial || '', onlineRate: `${onlineRate}%`, status: onlineRate >= 95 ? 'normal' : 'warning' } @@ -751,9 +755,7 @@ function pushRealtimeAlarm(event) { realtimeAlarms.value = realtimeAlarms.value.slice(0, 5) } -onMounted(() => { - loadHomeData() - +onMounted(async () => { const token = getToken() if (!token || token === 'undefined' || token === 'null' || token.length < 30) { @@ -761,7 +763,12 @@ onMounted(() => { return } - connectWs(handleWsMessage) + try { + await loadHomeData() + connectWs(handleWsMessage) + } catch (error) { + console.warn('[Home] 棣栭〉鍒濆鍖栧け璐ワ紝璺宠繃 WebSocket 杩炴帴', error) + } }) onBeforeUnmount(() => { diff --git a/src/views/worn/camera/index.vue b/src/views/worn/camera/index.vue new file mode 100644 index 0000000..7eb8eb6 --- /dev/null +++ b/src/views/worn/camera/index.vue @@ -0,0 +1,328 @@ + + + diff --git a/src/views/worn/warehouseDashboard/components/CameraPlayer.vue b/src/views/worn/warehouseDashboard/components/CameraPlayer.vue new file mode 100644 index 0000000..7f5b5e2 --- /dev/null +++ b/src/views/worn/warehouseDashboard/components/CameraPlayer.vue @@ -0,0 +1,177 @@ + + + + + \ No newline at end of file diff --git a/src/views/worn/warehouseDashboard/index.vue b/src/views/worn/warehouseDashboard/index.vue index 810c5a7..77f2dbc 100644 --- a/src/views/worn/warehouseDashboard/index.vue +++ b/src/views/worn/warehouseDashboard/index.vue @@ -36,7 +36,7 @@
-
+
当前仓库暂无传感器设备
@@ -123,12 +123,60 @@ {{ item.reportTime || '暂无上报' }}
+ +
+
+
+
+
+ +
+
+ + {{ cameraReady ? '播放中' : (cameraLoading ? '加载中' : '已绑定') }} +
+
+ +
+

{{ warehouseName || '仓库摄像头' }}

+

仓库摄像头

+ {{ cameraSummaryText }} +
+ +
+
+
+ +
+

实时画面

+ +
{{ cameraError }}
+
地址有效期至 {{ cameraExpireTime }}
+
+
+ + +