From 33a5d8b3a35b6bd362c52ad944eb1c7b2a341c84 Mon Sep 17 00:00:00 2001 From: root <13910913995@163.com> Date: Fri, 9 Jan 2026 14:50:25 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E5=90=84?= =?UTF-8?q?=E7=B1=BB=E8=AE=BE=E5=A4=87=E6=98=AF=E5=90=A6enabled=E7=9A=84?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/config.ini | 2 +- backend/devices/base_device.py | 5 +---- backend/main.py | 18 ++++++++++++++++-- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/backend/config.ini b/backend/config.ini index bbdf0940..df117eef 100644 --- a/backend/config.ini +++ b/backend/config.ini @@ -20,7 +20,7 @@ path = D:/BodyCheck/file/ [CAMERA1] enabled = True -device_index = 1 +device_index = 0 width = 1280 height = 720 fps = 30 diff --git a/backend/devices/base_device.py b/backend/devices/base_device.py index b10763b2..85d17d44 100644 --- a/backend/devices/base_device.py +++ b/backend/devices/base_device.py @@ -246,10 +246,7 @@ class BaseDevice(ABC): Dict[str, Any]: 设备信息 """ with self._lock: - return self._device_info.copy() - - - + return self._device_info.copy() def _set_error(self, error_msg: str): diff --git a/backend/main.py b/backend/main.py index 449e1d5d..1550b872 100644 --- a/backend/main.py +++ b/backend/main.py @@ -246,8 +246,6 @@ class AppServer: # 初始化录制管理器 self.logger.info('正在初始化录制管理器...') - camera1_manager = self.device_managers.get('camera1') - camera2_manager = self.device_managers.get('camera2') femtobolt_manager = self.device_managers.get('femtobolt') pressure_manager = self.device_managers.get('pressure') @@ -1159,6 +1157,22 @@ class AppServer: except Exception as e: self.logger.error(f'获取设备状态失败: {e}') return jsonify({'success': False, 'error': str(e)}), 500 + + @self.app.route('/api/cameras/check', methods=['GET']) + def check_cameras(): + """检查相机可用状态""" + try: + if not self.config_manager: + return jsonify({'success': False, 'error': '配置管理器未初始化'}), 500 + + results = CameraManager.check_cameras_status(self.config_manager) + return jsonify({ + 'success': True, + 'data': results + }) + except Exception as e: + self.logger.error(f"检查相机状态失败: {e}") + return jsonify({'success': False, 'error': str(e)}), 500 # ==================== 设备配置API ==================== From 36c399c00967effce9aca5b90fbc5b413cf33fcf Mon Sep 17 00:00:00 2001 From: root <13910913995@163.com> Date: Fri, 9 Jan 2026 14:51:11 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/config.ini | 12 ++--- backend/devices/device_coordinator.py | 4 +- backend/devices/utils/config_manager.py | 52 ++++++++++++++++--- frontend/src/renderer/src/views/Detection.vue | 5 ++ 4 files changed, 58 insertions(+), 15 deletions(-) diff --git a/backend/config.ini b/backend/config.ini index df117eef..e2355d0f 100644 --- a/backend/config.ini +++ b/backend/config.ini @@ -19,7 +19,7 @@ max_backups = 7 path = D:/BodyCheck/file/ [CAMERA1] -enabled = True +enabled = False device_index = 0 width = 1280 height = 720 @@ -29,7 +29,7 @@ fourcc = MJPG backend = directshow [CAMERA2] -enabled = True +enabled = False device_index = 3 width = 1280 height = 720 @@ -39,7 +39,7 @@ fourcc = MJPG backend = directshow [FEMTOBOLT] -enabled = True +enabled = False algorithm_type = plt color_resolution = 1080P depth_mode = NFOV_2X2BINNED @@ -50,22 +50,22 @@ fps = 15 synchronized_images_only = False [DEVICES] -imu_enabled = True +imu_enabled = False imu_device_type = ble imu_port = COM9 imu_mac_address = ef:3c:1a:0a:fe:02 imu_baudrate = 9600 -pressure_enabled = True +pressure_enabled = False pressure_device_type = real pressure_use_mock = False pressure_port = COM5 pressure_baudrate = 115200 [REMOTE] +enable = False port = COM6 baudrate = 115200 timeout = 0.1 -enable = True strict_crc = False [SYSTEM] diff --git a/backend/devices/device_coordinator.py b/backend/devices/device_coordinator.py index 1e6760b9..5eb4f852 100644 --- a/backend/devices/device_coordinator.py +++ b/backend/devices/device_coordinator.py @@ -165,9 +165,9 @@ class DeviceCoordinator: # 普通相机:初始化两个实例(camera1 与 camera2) # camera1 使用 [CAMERA1] 配置;camera2 使用 [CAMERA2](若不存在则回退为 device_index+1) - if self.device_configs.get('camera1', {}).get('enabled', True): + if self.device_configs.get('camera1', {}).get('enabled', False): futures.append(('camera1', self.executor.submit(self._init_camera_by_name, 'camera1', 'CAMERA1'))) - if self.device_configs.get('camera2', {}).get('enabled', True): + if self.device_configs.get('camera2', {}).get('enabled', False): futures.append(('camera2', self.executor.submit(self._init_camera_by_name, 'camera2', 'CAMERA2'))) # IMU传感器 diff --git a/backend/devices/utils/config_manager.py b/backend/devices/utils/config_manager.py index c5895d89..d152e93a 100644 --- a/backend/devices/utils/config_manager.py +++ b/backend/devices/utils/config_manager.py @@ -163,6 +163,8 @@ class ConfigManager: config = self._get_imu_config() elif device_name == 'pressure': config = self._get_pressure_config() + elif device_name == 'remote': + config = self._get_remote_config() else: self.logger.warning(f"未知设备类型: {device_name}") @@ -255,6 +257,21 @@ class ConfigManager: 'calibration_samples': self.config.getint('DEVICES', 'pressure_calibration_samples', fallback=50) } + def _get_remote_config(self) -> Dict[str, Any]: + """ + 获取远程控制配置 + + Returns: + Dict[str, Any]: 远程控制配置 + """ + return { + 'enabled': self.config.getboolean('REMOTE', 'enable', fallback=True), + 'port': self.config.get('REMOTE', 'port', fallback='COM6'), + 'baudrate': self.config.getint('REMOTE', 'baudrate', fallback=115200), + 'timeout': self.config.getfloat('REMOTE', 'timeout', fallback=0.1), + 'strict_crc': self.config.getboolean('REMOTE', 'strict_crc', fallback=False) + } + def get_system_config(self) -> Dict[str, Any]: """ 获取系统配置 @@ -614,13 +631,7 @@ class ConfigManager: 'camera1': self.get_device_config('camera1'), 'camera2': self.get_device_config('camera2'), 'femtobolt': self.get_device_config('femtobolt'), - 'remote': { - 'enabled': self.config.getboolean('DEVICES', 'remote_enabled', fallback=True), - 'port': self.config.get('REMOTE', 'port', fallback='COM6'), - 'baudrate': self.config.getint('REMOTE', 'baudrate', fallback=115200), - 'timeout': self.config.getfloat('REMOTE', 'timeout', fallback=0.1), - 'strict_crc': self.config.getboolean('REMOTE', 'strict_crc', fallback=False) - } + 'remote': self.get_device_config('remote') } def _batch_update_device_configs(self, configs: Dict[str, Dict[str, Any]]) -> Dict[str, Any]: @@ -787,6 +798,33 @@ class ConfigManager: errors.append(f"FemtoBolt: {error_msg}") self.logger.error(error_msg) + # Remote配置 + if 'remote' in configs: + try: + config_data = configs['remote'] + if 'enabled' in config_data: + self.set_config_value('REMOTE', 'enable', str(config_data['enabled'])) + if 'port' in config_data: + self.set_config_value('REMOTE', 'port', config_data['port']) + if 'baudrate' in config_data: + self.set_config_value('REMOTE', 'baudrate', str(config_data['baudrate'])) + if 'timeout' in config_data: + self.set_config_value('REMOTE', 'timeout', str(config_data['timeout'])) + if 'strict_crc' in config_data: + self.set_config_value('REMOTE', 'strict_crc', str(config_data['strict_crc'])) + + results['remote'] = { + 'success': True, + 'message': '遥控器配置更新成功', + 'config': config_data + } + self.logger.info(f"遥控器配置已更新: {config_data}") + except Exception as e: + error_msg = f'设置遥控器配置失败: {str(e)}' + results['remote'] = {'success': False, 'message': error_msg} + errors.append(f"Remote: {error_msg}") + self.logger.error(error_msg) + # 一次性保存所有配置 if results: # 只有在有配置更新时才保存 self.save_config() diff --git a/frontend/src/renderer/src/views/Detection.vue b/frontend/src/renderer/src/views/Detection.vue index 2bc5380f..5d77171d 100644 --- a/frontend/src/renderer/src/views/Detection.vue +++ b/frontend/src/renderer/src/views/Detection.vue @@ -752,6 +752,7 @@ const cameraStatus = computed(() => (camera1Status.value === '已连接' || came const femtoboltStatus = ref('未连接') // 深度相机(FemtoBolt)设备状态 const imuStatus = ref('未连接') // IMU设备状态 const pressureStatus = ref('未连接') // 压力传感器设备状态 +const remoteStatus = ref('未连接') // 遥控器设备状态 // 为了向后兼容,保留videoStatus但映射到cameraStatus const videoStatus = computed(() => cameraStatus.value) @@ -1141,6 +1142,10 @@ function connectWebSocket() { pressureStatus.value = statusText console.log(`⚖️ 压力传感器状态: ${statusText}`) break + case 'remote': + remoteStatus.value = statusText + console.log(`📡 遥控器状态: ${statusText}`) + break default: console.warn('⚠️ 未知设备类型:', device_type) } From 7eff717256bbcd5b60fec49d64ff3ceb41308bd4 Mon Sep 17 00:00:00 2001 From: root <13910913995@163.com> Date: Fri, 9 Jan 2026 15:53:46 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=BA=86=E6=A3=80?= =?UTF-8?q?=E6=9F=A5session=E7=9A=84statsu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/config.ini | 2 +- backend/database.py | 46 +++++++++++++++++++++++---------------------- backend/main.py | 9 ++++----- 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/backend/config.ini b/backend/config.ini index e2355d0f..0771b414 100644 --- a/backend/config.ini +++ b/backend/config.ini @@ -19,7 +19,7 @@ max_backups = 7 path = D:/BodyCheck/file/ [CAMERA1] -enabled = False +enabled = True device_index = 0 width = 1280 height = 720 diff --git a/backend/database.py b/backend/database.py index 39b299fa..7fc55324 100644 --- a/backend/database.py +++ b/backend/database.py @@ -232,7 +232,7 @@ class DatabaseManager: treatment_info TEXT, -- 处理信息 remark_info TEXT, -- 备注信息 detection_report TEXT, -- 生成检测报告的存储路径 - status TEXT DEFAULT 'checking', -- 会话状态(checking/checked/diagnosed/reported) + status TEXT DEFAULT 'checking', -- 会话状态(checking/checked/completed/reported) data_ids TEXT, -- 关联的检测数据ID(逗号分隔) created_at TIMESTAMP, -- 记录创建时间 FOREIGN KEY (patient_id) REFERENCES patients (id), -- 患者表外键约束 @@ -663,23 +663,28 @@ class DatabaseManager: # 构造更新语句 update_fields = [ 'duration = ?', - 'end_time = ?', - 'status = ?' + 'end_time = ?' + ] - update_values = [duration_seconds, now_str, 'checked'] + update_values = [duration_seconds, now_str] if diagnosis_info is not None: update_fields.append('diagnosis_info = ?') - update_values.append(diagnosis_info) - - if treatment_info is not None: - update_fields.append('treatment_info = ?') - update_values.append(treatment_info) + update_values.append(diagnosis_info) if suggestion_info is not None: update_fields.append('suggestion_info = ?') - update_values.append(suggestion_info) + update_values.append(suggestion_info) + status='checked' #默认状态为checked:已完成检查 + if treatment_info is not None: #处理信息不为空时,状态设为completed:已诊断处理 + update_fields.append('treatment_info = ?') + update_values.append(treatment_info) + status='completed' + + update_fields.append('status = ?') + update_values.append(status) + # 添加会话ID到参数列表 update_values.append(session_id) @@ -688,9 +693,9 @@ class DatabaseManager: # 同步更新患者表的updated_at时间 cursor.execute('''UPDATE patients SET updated_at = ? WHERE id = ?''', (now_str, patient_id)) - + self._sync_patient_medical_history_from_session(cursor, session_id) conn.commit() - logger.info(f'结束检测并更新会话: {session_id}, duration={duration_seconds}s, status=checked') + logger.info(f'结束检测并更新会话: {session_id}, duration={duration_seconds}s, status={status}') return True except Exception as e: @@ -699,7 +704,7 @@ class DatabaseManager: return False - def update_session_all_info(self, session_id: str, diagnosis_info: str = None, treatment_info: str = None, suggestion_info: str = None, status: str = None): + def update_session_all_info(self, session_id: str, diagnosis_info: str = None, treatment_info: str = None, suggestion_info: str = None): """同时更新会话的诊断信息、处理信息、建议信息和状态""" conn = self.get_connection() cursor = conn.cursor() @@ -712,19 +717,16 @@ class DatabaseManager: if diagnosis_info is not None: update_fields.append('diagnosis_info = ?') update_values.append(diagnosis_info) - + status='checked' #默认状态为checked:已完成检查 if treatment_info is not None: update_fields.append('treatment_info = ?') update_values.append(treatment_info) + status='completed' #处理信息不为空时,状态设为completed:已诊断处理 if suggestion_info is not None: update_fields.append('suggestion_info = ?') - update_values.append(suggestion_info) - - if status is not None: - update_fields.append('status = ?') - update_values.append(status) - + update_values.append(suggestion_info) + if not update_fields: logger.warning(f'没有提供要更新的信息: {session_id}') return @@ -807,7 +809,7 @@ class DatabaseManager: SELECT s.id, s.status, s.start_time, u.name as creator_name,s.detection_report as detection_report,s.data_ids as data_ids FROM detection_sessions s LEFT JOIN users u ON s.creator_id = u.id - WHERE s.patient_id = ? + WHERE s.patient_id = ? and s.status in ('checked','completed','reported') ORDER BY s.start_time DESC LIMIT ? OFFSET ? ''', (patient_id, size, offset)) @@ -846,7 +848,7 @@ class DatabaseManager: conn = self.get_connection() cursor = conn.cursor() try: - cursor.execute('SELECT COUNT(*) FROM detection_sessions WHERE patient_id = ?', (patient_id,)) + cursor.execute("SELECT COUNT(*) FROM detection_sessions WHERE status in ('checked','completed','reported') and patient_id = ?", (patient_id,)) row = cursor.fetchone() return int(row[0]) if row else 0 except Exception as e: diff --git a/backend/main.py b/backend/main.py index 1550b872..e92c7a17 100644 --- a/backend/main.py +++ b/backend/main.py @@ -1493,13 +1493,13 @@ class AppServer: diagnosis_info = data.get('diagnosis_info') treatment_info = data.get('treatment_info') suggestion_info = data.get('suggestion_info') - status = data.get('status') + # 验证至少提供一个要更新的字段 - if not any([diagnosis_info, treatment_info, suggestion_info, status]): + if not any([diagnosis_info, treatment_info, suggestion_info]): return jsonify({ 'success': False, - 'error': '至少需要提供一个要更新的字段(diagnosis_info, treatment_info, suggestion_info, status)' + 'error': '至少需要提供一个要更新的字段(diagnosis_info, treatment_info, suggestion_info)' }), 400 # 调用数据库管理器的批量更新方法 @@ -1507,8 +1507,7 @@ class AppServer: session_id=session_id, diagnosis_info=diagnosis_info, treatment_info=treatment_info, - suggestion_info=suggestion_info, - status=status + suggestion_info=suggestion_info ) # 构建更新信息反馈