From aaf12babc36f060ca835f1d799af3e3b5251994b Mon Sep 17 00:00:00 2001 From: limengnan <420004014@qq.com> Date: Wed, 10 Sep 2025 15:12:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=BC=80=E5=A7=8B=E6=A3=80?= =?UTF-8?q?=E6=B5=8B=EF=BC=8C=E5=81=9C=E6=AD=A2=E6=A3=80=E6=B5=8B=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=BC=80=E5=A7=8B=E5=BD=95=E5=B1=8F=EF=BC=8C?= =?UTF-8?q?=E5=81=9C=E6=AD=A2=E5=BD=95=E5=B1=8F=E6=96=B9=E6=B3=95=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A0=B7=E5=BC=8F=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/renderer/src/views/Detection.vue | 353 ++++++++++-------- .../src/renderer/src/views/PatientProfile.vue | 1 + frontend/src/renderer/src/views/Recording.vue | 1 + 3 files changed, 206 insertions(+), 149 deletions(-) diff --git a/frontend/src/renderer/src/views/Detection.vue b/frontend/src/renderer/src/views/Detection.vue index 7a12bc8c..b7db3264 100644 --- a/frontend/src/renderer/src/views/Detection.vue +++ b/frontend/src/renderer/src/views/Detection.vue @@ -11,6 +11,7 @@ 实时检测 +
检测中
@@ -41,12 +42,12 @@
- + - +
@@ -61,10 +62,11 @@ 身体姿态 -
+
{{ femtoboltStatus }}
-
+
深度相机视频流 @@ -75,7 +77,7 @@ align-content: space-between; "> -
+
@@ -108,66 +110,54 @@
-
+
旋转角
-
{{ headlist.rotation }}
-
-
左:{{ +
{{ headlist.rotation }}°
+
+
左最大:{{ headPoseMaxValues.rotationLeftMax.toFixed(1) }}°
-
右:{{ - headPoseMaxValues.rotationRightMax.toFixed(1) }}°
+ +
+
+
左最大:{{ + headPoseMaxValues.rotationLeftMax.toFixed(1) }}°
+
倾斜角
-
{{ headlist.tilt }}
-
-
左:{{ +
{{ headlist.tilt }}°
+
+
左最大:{{ headPoseMaxValues.tiltLeftMax.toFixed(1) }}°
-
右:{{ + +
+
+
右最大:{{ headPoseMaxValues.tiltRightMax.toFixed(1) }}°
俯仰角
-
{{ headlist.pitch }}
-
-
俯:{{ +
{{ headlist.pitch }}°
+
+
俯最大:{{ + headPoseMaxValues.pitchDownMax.toFixed(1) }}°
+
+
+
俯最大:{{ headPoseMaxValues.pitchDownMax.toFixed(1) }}°
-
仰:{{ - headPoseMaxValues.pitchUpMax.toFixed(1) }}°
-
-
-
历史数据
-
- -
- - - - - - - - - - - - - - - -
+
-
+
@@ -180,68 +170,75 @@ pressureStatus }}
-
-
-
- 左前足 - {{ footPressure.left_front - }}% -
-
- 左后足 - {{ footPressure.left_rear }}% -
-
-
-
-
- 左足 +
+
+
+
+ 左前足 + {{ footPressure.left_front + }}%
-
- 右足 +
+ 左后足 + {{ footPressure.left_rear }}%
-
- -
-
-
-
-
-
左足总压力
-
{{ footPressure.left_total - }}%
+
+
+
+ 左足 +
+
+ 右足 +
-
-
右足总压力
-
{{ footPressure.right_total - }}%
+
+ +
+
+
+
+
+
左足总压力
+
{{ footPressure.left_total + }}%
+
+
+
右足总压力
+
{{ footPressure.right_total + }}%
+
-
-
-
- 右前足 - {{ footPressure.right_front - }}% -
-
- 右后足 - {{ footPressure.right_rear - }}% +
+
+ 右前足 + {{ footPressure.right_front + }}% +
+
+ 右后足 + {{ footPressure.right_rear + }}% +
+
-
-
+
@@ -322,7 +319,7 @@
-
+
@@ -334,7 +331,7 @@
{{ cameraStatus }}
-
+
@@ -586,19 +583,13 @@ const screenshotLoading = ref(false) const dataCollectionLoading = ref(false) const isRecording = ref(false) const cameraDialogVisible =ref(false) // 设置相机参数弹框 - - const contenGridRef =ref(null) // 实时检查整体box - const wholeBodyRef = ref(null) // 身体姿态ref const videoImgRef =ref(null) // 视频流图片ref - // 录像相关变量 let mediaRecorder = null let recordedChunks = [] let recordingStream = null - - // 患者信息(从页面获取或通过API获取) const patientInfo = ref({ id: '', @@ -693,11 +684,7 @@ const calculatedAge = ref(null) //修改 // 模拟历史数据 -const historyData = ref([ - // { id: 3, rotLeft: '-55.2°', rotRight: '54.2°', tiltLeft: '-17.7°', tiltRight: '18.2°', pitchDown: '-20.2°', pitchUp: '10.5°' }, - // { id: 2, rotLeft: '-55.8°', rotRight: '56.2°', tiltLeft: '-17.5°', tiltRight: '17.9°', pitchDown: '-21.2°', pitchUp: '12.1°' }, - // { id: 1, rotLeft: '-56.1°', rotRight: '55.7°', tiltLeft: '-17.5°', tiltRight: '18.5°', pitchDown: '-22.2°', pitchUp: '11.5°' } -]) +const historyData = ref([]) const chartoption = ref({ backgroundColor: '#242424', grid: { top: 0, right: 0, bottom: 0, left: 0 }, @@ -825,7 +812,7 @@ const startTimer = () => { if (seconds.value >= 60) { console.log('⏰ 检测时长超过10分钟,自动停止检测'); ElMessage.warning('检测时长已达到10分钟,自动停止检测'); - stopDetection(); + stopRecord() return; } @@ -1683,28 +1670,23 @@ async function handleStartStop() { } if (isStart.value) { - // 停止检测 - await stopDetection() + // 停止录制视频 + await stopRecord() } else { patientInfo.value.sessionId = null - // 开始检测 - await startDetection() + // 开始录制视频 + await startRecord() } } // 开始检测 async function startDetection() { try { console.log('🚀 正在开始检测...') - isRecording.value = true startTimer() // 验证患者信息 if (!patientInfo.value || !patientInfo.value.id) { throw new Error('缺少患者信息,无法开始检测') } - let screen_location = contenGridRef.value.getBoundingClientRect() - let femtobolt_location = wholeBodyRef.value.getBoundingClientRect() - let camera_location = videoImgRef.value.getBoundingClientRect() - let titile_height = 24 // 调用后端API开始检测 const response = await fetch(`${BACKEND_URL}/api/detection/start`, { method: 'POST', @@ -1715,10 +1697,6 @@ async function startDetection() { patient_id: patientInfo.value.id, // 可以添加其他检测参数 creator_id: creatorId.value, - screen_location:[Math.round(screen_location.x), Math.round(screen_location.y) + titile_height, Math.round(screen_location.width), Math.round(screen_location.height-titile_height)], - camera_location:[Math.round(camera_location.x), Math.round(camera_location.y)+ titile_height, Math.round(camera_location.width), Math.round(camera_location.height-titile_height)], - femtobolt_location:[Math.round(femtobolt_location.x), Math.round(femtobolt_location.y) + titile_height, Math.round(femtobolt_location.width), Math.round(femtobolt_location.height-titile_height)], - }) }) if (!response.ok) { @@ -1729,14 +1707,8 @@ async function startDetection() { if (result.success) { console.log('✅ 检测开始成功') - // 保存会话ID和检测开始时间 patientInfo.value.sessionId = result.session_id - patientInfo.value.detectionStartTime = Date.now() - console.log('✅ 检测会话创建成功,会话ID:', patientInfo.value.sessionId) - - isStart.value = true - ElMessage.success('检测已开始') } else { throw new Error(result.message || '开始检测失败') } @@ -1751,14 +1723,8 @@ async function startDetection() { // 停止检测 async function stopDetection() { try { - console.log('🛑 停止检测,会话ID:', patientInfo.value.sessionId) - resetTimer() // 计算检测持续时间 let duration = 0 - if (patientInfo.value.detectionStartTime) { - duration = Math.floor((Date.now() - patientInfo.value.detectionStartTime) / 1000) - } - // 调用后端API停止检测 const response = await fetch(`${BACKEND_URL}/api/detection/${patientInfo.value.sessionId}/stop`, { method: 'POST', @@ -1773,8 +1739,6 @@ async function stopDetection() { throw new Error(`HTTP ${response.status}: ${response.statusText}`) } isRecording.value = false - isStart.value = false - } catch (error) { console.error('❌ 停止检测失败:', error) ElMessage.error(`停止检测失败: ${error.message}`) @@ -1979,15 +1943,11 @@ const getDevicesInit = async () => { } onMounted(() => { - - console.log(wholeBodyRef.value.getBoundingClientRect()) - console.log(videoImgRef.value.getBoundingClientRect()) // 加载患者信息 loadPatientInfo() - // 页面加载时自动连接WebSocket connectWebSocket() - + startDetection() // 监听页面关闭或刷新事件 window.addEventListener('beforeunload', handleBeforeUnload) if (authStore.currentUser) { @@ -2005,11 +1965,12 @@ onUnmounted(() => { if (isRecording.value) { stopRecording() } - // 停止检测(如果正在检测) - if (isStart.value) { - stopDetection() + if(isStart.value == true){ + + stopRecord() } + stopDetection() // 页面关闭时断开WebSocket连接 disconnectWebSocket() @@ -2042,6 +2003,90 @@ onUnmounted(() => { // 移除页面关闭事件监听器 window.removeEventListener('beforeunload', handleBeforeUnload) }) + +const startRecord = async () => { // 开始录屏 + try { + console.log('🚀 正在开始录屏...') + + // 验证患者信息 + if (!patientInfo.value || !patientInfo.value.sessionId) { + throw new Error('缺少患者信息,无法开始录屏') + } + isRecording.value = true + let screen_location = contenGridRef.value.getBoundingClientRect() + let femtobolt_location = wholeBodyRef.value.getBoundingClientRect() + let camera_location = videoImgRef.value.getBoundingClientRect() + let titile_height = 24 + // 调用后端API开始录屏 + const response = await fetch(`${BACKEND_URL}/api/detection/${patientInfo.value.sessionId}/start_record`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + patient_id: patientInfo.value.sessionId, + // 可以添加其他录屏参数 + creator_id: creatorId.value, + screen_location:[Math.round(screen_location.x), Math.round(screen_location.y) + titile_height, Math.round(screen_location.width), Math.round(screen_location.height-titile_height)], + camera_location:[Math.round(camera_location.x), Math.round(camera_location.y)+ titile_height, Math.round(camera_location.width), Math.round(camera_location.height-titile_height)], + femtobolt_location:[Math.round(femtobolt_location.x), Math.round(femtobolt_location.y) + titile_height, Math.round(femtobolt_location.width), Math.round(femtobolt_location.height-titile_height)], + + }) + }) + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`) + } + + const result = await response.json() + + if (result.success) { + // 保存会话ID和检测开始时间 + patientInfo.value.detectionStartTime = Date.now() + console.log('✅ 录屏会话创建成功,会话ID:', patientInfo.value.sessionId) + isStart.value = true + ElMessage.success('录屏已开始') + } else { + throw new Error(result.message || '开始录屏失败') + } + } catch (error) { + ElMessage.error(`开始录屏失败: ${error.message}`) + throw error + } +} + +const stopRecord = async () => { // 停止录屏 + try { + resetTimer() + // 计算检测持续时间 + let duration = 0 + if (patientInfo.value.detectionStartTime) { + duration = Math.floor((Date.now() - patientInfo.value.detectionStartTime) / 1000) + } + + // 调用后端API停止检测 + const response = await fetch(`${BACKEND_URL}/api/detection/${patientInfo.value.sessionId}/stop_record`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + duration: duration + }) + }) + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`) + } + isRecording.value = false + isStart.value = false + + } catch (error) { + console.error('❌ 停止检测失败:', error) + ElMessage.error(`停止检测失败: ${error.message}`) + } +} +function routerClick(){ + router.push(`/patient/${patientInfo.value.id}`) +} \ No newline at end of file diff --git a/frontend/src/renderer/src/views/PatientProfile.vue b/frontend/src/renderer/src/views/PatientProfile.vue index a44a592e..0901d5af 100644 --- a/frontend/src/renderer/src/views/PatientProfile.vue +++ b/frontend/src/renderer/src/views/PatientProfile.vue @@ -1174,6 +1174,7 @@ onMounted(() => { .main-content { padding: 10px; display: flex; + flex-direction: column; overflow: auto; width: 100%; } diff --git a/frontend/src/renderer/src/views/Recording.vue b/frontend/src/renderer/src/views/Recording.vue index a28ee8e0..8fa27c9b 100644 --- a/frontend/src/renderer/src/views/Recording.vue +++ b/frontend/src/renderer/src/views/Recording.vue @@ -983,6 +983,7 @@ onUnmounted(() => { .main-content { flex: 1; display: flex; + flex-direction: column; overflow: hidden; }