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 @@