From 38fc3abcf24356e027973206cb00c55c38a50107 Mon Sep 17 00:00:00 2001 From: root <13910913995@163.com> Date: Sat, 27 Sep 2025 15:09:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=86=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E4=BF=9D=E5=AD=98=EF=BC=8C=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E4=BA=86=E9=87=8D=E5=90=AF=E8=AE=BE=E5=A4=87=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/database.py | 67 ++++++++ backend/devices/utils/config_manager.py | 2 +- backend/main.py | 159 +++++++++--------- frontend/src/renderer/src/views/Detection.vue | 4 +- frontend/src/renderer/src/views/Header.vue | 9 +- .../src/renderer/src/views/PatientProfile.vue | 4 +- 6 files changed, 160 insertions(+), 85 deletions(-) diff --git a/backend/database.py b/backend/database.py index bd43c49b..abb09be5 100644 --- a/backend/database.py +++ b/backend/database.py @@ -1551,6 +1551,73 @@ class DatabaseManager: logger.error(f'设置系统配置失败: {e}') raise + def is_empty_session(self, session_id: str) -> bool: + """检查是否为空白会话 + + 空白会话的条件: + 1. status 为 'created' + 2. screen_video_path 为空 + 3. detection_data 表中没有对应的数据 + + Args: + session_id: 会话ID + + Returns: + bool: True表示是空白会话,False表示不是 + """ + conn = self.get_connection() + cursor = conn.cursor() + + try: + # 检查会话状态和screen_video_path + cursor.execute(''' + SELECT status, screen_video_path + FROM detection_sessions + WHERE id = ? + ''', (session_id,)) + + session_row = cursor.fetchone() + if not session_row: + logging.info(f"[is_empty_session] 会话 {session_id} 不存在") + return False # 会话不存在 + + session_data = dict(session_row) + status = session_data.get('status') + screen_video_path = session_data.get('screen_video_path') + + logging.info(f"[is_empty_session] 会话 {session_id} 状态检查: status='{status}', screen_video_path='{screen_video_path}'") + + # 检查条件1:status是否为created + if status != 'checking': + logging.info(f"[is_empty_session] 会话 {session_id} 状态不是'checking',当前状态: '{status}' - 不是空白会话") + return False + + # 检查条件2:screen_video_path是否为空 + if screen_video_path and screen_video_path.strip(): + logging.info(f"[is_empty_session] 会话 {session_id} 已有录屏路径: '{screen_video_path}' - 不是空白会话") + return False + + logging.info(f"[is_empty_session] 会话 {session_id} 通过状态和录屏路径检查,继续检查检测数据") + + # 检查条件3:detection_data表中是否有对应数据 + cursor.execute(''' + SELECT COUNT(*) as count + FROM detection_data + WHERE session_id = ? + ''', (session_id,)) + + count_row = cursor.fetchone() + data_count = count_row['count'] if count_row else 0 + + logging.info(f"[is_empty_session] 会话 {session_id} 检测数据数量: {data_count}") + + # 如果没有检测数据,则认为是空白会话 + return data_count == 0 + + except Exception as e: + logger.error(f'检查空白会话失败: {e}') + return False + def close(self): """关闭数据库连接""" if self.connection: diff --git a/backend/devices/utils/config_manager.py b/backend/devices/utils/config_manager.py index 5f5a91e5..c076dcb8 100644 --- a/backend/devices/utils/config_manager.py +++ b/backend/devices/utils/config_manager.py @@ -733,7 +733,7 @@ class ConfigManager: self.logger.info("所有设备配置设置成功") return { 'success': True, - 'message': '所有设备配置设置成功', + 'message': '相机参数设置成功。重启软件系统生效!', 'results': results, 'updated_configs': self.get_all_device_configs() } diff --git a/backend/main.py b/backend/main.py index 9b027ad0..bb82bb4a 100644 --- a/backend/main.py +++ b/backend/main.py @@ -388,7 +388,8 @@ class AppServer: 'name': user['name'], 'role': 'admin' if user['user_type'] == 'admin' else 'user', 'user_type': user['user_type'], - 'avatar': '' + 'avatar': '', + 'phone': user['phone'] } # 生成token(实际项目中应使用JWT等安全token) @@ -854,7 +855,7 @@ class AppServer: }), 400 # 验证数据格式 - supported_devices = ['imu', 'pressure', 'camera', 'femtobolt'] + supported_devices = ['camera', 'femtobolt','imu','pressure'] for device_name in data.keys(): if device_name not in supported_devices: return jsonify({ @@ -865,58 +866,58 @@ class AppServer: result = self.config_manager.set_all_device_configs(data) # 如果配置设置成功,异步重启设备数据推送 - if result['success']: - def restart_devices_async(): - """异步重启设备数据推送""" - try: - self.logger.info("设备配置更新成功,异步重启设备数据推送...") - # 先停止当前的数据推送 - if self.is_pushing_data: - self.stop_device_push_data() - time.sleep(1) # 等待停止完成 + # if result['success']: + # def restart_devices_async(): + # """异步重启设备数据推送""" + # try: + # self.logger.info("设备配置更新成功,异步重启设备数据推送...") + # # 先停止当前的数据推送 + # if self.is_pushing_data: + # self.stop_device_push_data() + # time.sleep(1) # 等待停止完成 - # 为每个设备管理器重新加载配置 - self.logger.info("重新加载设备配置...") - reload_results = [] - for device_name, manager in self.device_managers.items(): - if manager is not None and hasattr(manager, 'reload_config'): - try: - success = manager.reload_config() - reload_results.append(f"{device_name}: {'成功' if success else '失败'}") - self.logger.info(f"{device_name}设备配置重新加载{'成功' if success else '失败'}") - except Exception as e: - reload_results.append(f"{device_name}: 异常 - {str(e)}") - self.logger.error(f"{device_name}设备配置重新加载异常: {e}") - else: - reload_results.append(f"{device_name}: 跳过(管理器未初始化或不支持reload_config)") + # # 为每个设备管理器重新加载配置 + # self.logger.info("重新加载设备配置...") + # reload_results = [] + # for device_name, manager in self.device_managers.items(): + # if manager is not None and hasattr(manager, 'reload_config'): + # try: + # success = manager.reload_config() + # reload_results.append(f"{device_name}: {'成功' if success else '失败'}") + # self.logger.info(f"{device_name}设备配置重新加载{'成功' if success else '失败'}") + # except Exception as e: + # reload_results.append(f"{device_name}: 异常 - {str(e)}") + # self.logger.error(f"{device_name}设备配置重新加载异常: {e}") + # else: + # reload_results.append(f"{device_name}: 跳过(管理器未初始化或不支持reload_config)") - self.logger.info(f"配置重新加载结果: {'; '.join(reload_results)}") + # self.logger.info(f"配置重新加载结果: {'; '.join(reload_results)}") - # 重新启动设备数据推送 - self.start_device_push_data() - self.logger.info("设备配置更新并重启数据推送完成") + # # 重新启动设备数据推送 + # self.start_device_push_data() + # self.logger.info("设备配置更新并重启数据推送完成") - # 通过SocketIO通知前端重启完成 - self.socketio.emit('device_restart_complete', { - 'status': 'success', - 'message': '设备重启完成', - 'reload_results': reload_results - }, namespace='/devices') + # # 通过SocketIO通知前端重启完成 + # self.socketio.emit('device_restart_complete', { + # 'status': 'success', + # 'message': '设备重启完成', + # 'reload_results': reload_results + # }, namespace='/devices') - except Exception as restart_error: - self.logger.error(f"重启设备数据推送失败: {restart_error}") - # 通过SocketIO通知前端重启失败 - self.socketio.emit('device_restart_complete', { - 'status': 'error', - 'message': f'设备重启失败: {str(restart_error)}' - }, namespace='/devices') + # except Exception as restart_error: + # self.logger.error(f"重启设备数据推送失败: {restart_error}") + # # 通过SocketIO通知前端重启失败 + # self.socketio.emit('device_restart_complete', { + # 'status': 'error', + # 'message': f'设备重启失败: {str(restart_error)}' + # }, namespace='/devices') - # 启动异步线程执行重启操作 - restart_thread = threading.Thread(target=restart_devices_async) - restart_thread.daemon = True - restart_thread.start() + # # 启动异步线程执行重启操作 + # restart_thread = threading.Thread(target=restart_devices_async) + # restart_thread.daemon = True + # restart_thread.start() - result['message'] = result.get('message', '') + ' 设备正在后台重启中,请稍候...' + # result['message'] = result.get('message', '') + ' 设备正在后台重启中,请稍候...' status_code = 200 if result['success'] else 400 return jsonify(result), status_code @@ -1009,7 +1010,6 @@ class AppServer: if not self.db_manager or not self.device_coordinator: self.logger.error('数据库管理器或设备管理器未初始化') return jsonify({'success': False, 'error': '数据库管理器或设备管理器未初始化'}), 500 - if not session_id: self.logger.error('缺少会话ID') return jsonify({ @@ -1017,40 +1017,40 @@ class AppServer: 'error': '缺少会话ID' }), 400 - # 获取请求数据中的duration参数 - data = flask_request.get_json() or {} - duration = data.get('duration') - - # 如果提供了duration,更新到数据库 - if duration is not None and isinstance(duration, (int, float)): - try: - self.db_manager.update_session_duration(session_id, int(duration)) - self.logger.info(f'更新会话持续时间: {session_id} -> {duration}秒') - except Exception as duration_error: - self.logger.error(f'更新会话持续时间失败: {duration_error}') - - # # 停止设备连接监控 - # if self.device_coordinator: - # try: - # self.device_coordinator.stop_all_connection_monitor() - # self.logger.info('检测停止,设备连接监控已停止') - # except Exception as monitor_error: - # self.logger.error(f'停止设备连接监控失败: {monitor_error}') - - success = self.db_manager.update_session_status(session_id, 'completed') - if success: - self.logger.info(f'检测会话已停止 - 会话ID: {session_id}') + if self.db_manager.is_empty_session(session_id): + # 删除空白会话 + self.db_manager.delete_detection_session(session_id) + self.logger.info(f'已删除空白会话: {session_id}') return jsonify({ 'success': True, - 'message': '检测已停止' - }) + 'message': '空白会话已删除' + }) else: - self.logger.error('停止检测失败,更新会话状态失败') - return jsonify({ - 'success': False, - 'error': '停止检测失败' - }), 500 + # 正常会话的停止流程 + # 如果提供了duration,更新到数据库 + data = flask_request.get_json() or {} + duration = data.get('duration') + if duration is not None and isinstance(duration, (int, float)): + try: + self.db_manager.update_session_duration(session_id, int(duration)) + self.logger.info(f'更新会话持续时间: {session_id} -> {duration}秒') + except Exception as duration_error: + self.logger.error(f'更新会话持续时间失败: {duration_error}') + # 更新会话状态为已完成 + success = self.db_manager.update_session_status(session_id, 'completed') + if success: + self.logger.info(f'检测会话已停止 - 会话ID: {session_id}') + return jsonify({ + 'success': True, + 'message': '检测已停止' + }) + else: + self.logger.error('停止检测失败,更新会话状态失败') + return jsonify({ + 'success': False, + 'error': '停止检测失败' + }), 500 except Exception as e: self.logger.error(f'停止检测失败: {e}', exc_info=True) return jsonify({'success': False, 'error': str(e)}), 500 @@ -1664,7 +1664,8 @@ class AppServer: is_connected: 连接状态 """ self.logger.info(f'设备状态变化: {device_name} -> {"已连接" if is_connected else "未连接"}') - self.broadcast_device_status(device_name, is_connected) + self.broadcast_device_status(device_name, is_connected) + def _detection_worker(self, detection_id, duration): diff --git a/frontend/src/renderer/src/views/Detection.vue b/frontend/src/renderer/src/views/Detection.vue index 3dff9131..bfaa74b5 100644 --- a/frontend/src/renderer/src/views/Detection.vue +++ b/frontend/src/renderer/src/views/Detection.vue @@ -1742,7 +1742,7 @@ const handleBeforeUnload = (event) => { } // 停止检测 - // stopDetection() + stopDetection() // 断开WebSocket连接 disconnectWebSocket() @@ -1924,7 +1924,7 @@ onUnmounted(() => { stopRecord() } - // stopDetection() + stopDetection() // 页面关闭时断开WebSocket连接 disconnectWebSocket() diff --git a/frontend/src/renderer/src/views/Header.vue b/frontend/src/renderer/src/views/Header.vue index 24c87d06..5c0f03bf 100644 --- a/frontend/src/renderer/src/views/Header.vue +++ b/frontend/src/renderer/src/views/Header.vue @@ -210,9 +210,16 @@ \ 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 8f4e230e..f0bbb5d5 100644 --- a/frontend/src/renderer/src/views/PatientProfile.vue +++ b/frontend/src/renderer/src/views/PatientProfile.vue @@ -4,8 +4,8 @@