diff --git a/backend/activation_request_W10-F5AC32003C0A160B.json b/backend/activation_request_W10-F5AC32003C0A160B.json
deleted file mode 100644
index 1a1a650a..00000000
--- a/backend/activation_request_W10-F5AC32003C0A160B.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "product": "BodyBalanceEvaluation",
- "version": "1.5.0",
- "machine_id": "W10-F5AC32003C0A160B",
- "platform": "Windows",
- "request_time": "2026-01-09T02:40:10.695573+00:00",
- "hardware_info": {
- "system": "Windows",
- "machine": "AMD64",
- "processor": "Intel64 Family 6 Model 165 Stepping 3, GenuineIntel",
- "node": "PS2020LTDYIFOO"
- },
- "company_name": "北京天宏博科技有限公司",
- "contact_info": "thb@163.com"
-}
\ No newline at end of file
diff --git a/backend/config.ini b/backend/config.ini
index 0771b414..885eb287 100644
--- a/backend/config.ini
+++ b/backend/config.ini
@@ -19,7 +19,7 @@ max_backups = 7
path = D:/BodyCheck/file/
[CAMERA1]
-enabled = True
+enable = True
device_index = 0
width = 1280
height = 720
@@ -29,8 +29,8 @@ fourcc = MJPG
backend = directshow
[CAMERA2]
-enabled = False
-device_index = 3
+enable = True
+device_index = 1
width = 1280
height = 720
fps = 30
@@ -39,7 +39,7 @@ fourcc = MJPG
backend = directshow
[FEMTOBOLT]
-enabled = False
+enable = True
algorithm_type = plt
color_resolution = 1080P
depth_mode = NFOV_2X2BINNED
@@ -50,19 +50,19 @@ fps = 15
synchronized_images_only = False
[DEVICES]
-imu_enabled = False
+imu_enable = False
imu_device_type = ble
imu_port = COM9
imu_mac_address = ef:3c:1a:0a:fe:02
imu_baudrate = 9600
-pressure_enabled = False
+pressure_enable = False
pressure_device_type = real
pressure_use_mock = False
pressure_port = COM5
pressure_baudrate = 115200
[REMOTE]
-enable = False
+enable = True
port = COM6
baudrate = 115200
timeout = 0.1
@@ -97,20 +97,12 @@ grace_days = 7
dev_mode = False
[SCREEN_RECORDING]
-# 录屏策略:ffmpeg(外部进程录制)或 threaded(内部线程录制)
strategy = ffmpeg
-# ffmpeg可执行文件绝对路径(Windows示例:D:/BodyCheck/ffmpeg/bin/ffmpeg.exe)
ffmpeg_path = D:/BodyCheck/ffmpeg/bin/ffmpeg.exe
-# 编码器:libx264(CPU)或 h264_nvenc(GPU,CPU占用更低,需显卡支持)
ffmpeg_codec = libx264
-# 编码预设:ultrafast(CPU更低、文件更大);NVENC用 p1/p2 更快
ffmpeg_preset = ultrafast
-# 编码线程数:限制CPU占用,按机器性能调整
ffmpeg_threads = 2
-# B帧数量:0可降低编码复杂度与CPU占用
ffmpeg_bframes = 0
-# 关键帧间隔(GOP,单位:帧):数值越大CPU越低,seek精度下降
ffmpeg_gop = 50
-# 是否录制鼠标:0关闭,1开启
ffmpeg_draw_mouse = 0
diff --git a/backend/database.py b/backend/database.py
index 7fc55324..d456ecb9 100644
--- a/backend/database.py
+++ b/backend/database.py
@@ -619,90 +619,7 @@ class DatabaseManager:
except Exception as e:
conn.rollback()
logger.error(f'更新会话状态失败: {e}')
- return False
-
-
- def update_session_endcheck(self, session_id: str, diagnosis_info: Optional[str] = None,
- treatment_info: Optional[str] = None,
- suggestion_info: Optional[str] = None) -> bool:
- """结束检测:根据 start_time 与当前时间计算持续时长并写入结束信息
-
- 行为:
- - 计算并保存 `duration`
- - 保存 `end_time` 为当前中国时区时间
- - 可选更新 `diagnosis_info`、`treatment_info`、`suggestion_info`
- - 设置 `status = 'checked'`
- - 同步更新患者 `updated_at`
- """
- conn = self.get_connection()
- cursor = conn.cursor()
-
- try:
- # 读取会话的开始时间与患者ID
- cursor.execute('SELECT start_time, patient_id FROM detection_sessions WHERE id = ?', (session_id,))
- row = cursor.fetchone()
- if not row:
- logger.error(f'会话不存在: {session_id}')
- return False
-
- start_time_str, patient_id = row
- if not start_time_str:
- logger.error(f'会话缺少开始时间: {session_id}')
- return False
-
- # 计算持续时间(秒)
- now_str = self.get_china_time()
- try:
- start_dt = datetime.strptime(start_time_str, '%Y-%m-%d %H:%M:%S')
- now_dt = datetime.strptime(now_str, '%Y-%m-%d %H:%M:%S')
- duration_seconds = max(0, int((now_dt - start_dt).total_seconds()))
- except Exception as e:
- logger.error(f'解析时间失败: start_time={start_time_str}, now={now_str}, error={e}')
- return False
-
- # 构造更新语句
- update_fields = [
- 'duration = ?',
- 'end_time = ?'
-
- ]
- update_values = [duration_seconds, now_str]
-
- if diagnosis_info is not None:
- update_fields.append('diagnosis_info = ?')
- update_values.append(diagnosis_info)
-
- if suggestion_info is not None:
- update_fields.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)
-
- sql = f'''UPDATE detection_sessions SET {', '.join(update_fields)} WHERE id = ?'''
- cursor.execute(sql, update_values)
-
- # 同步更新患者表的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={status}')
- return True
-
- except Exception as e:
- conn.rollback()
- logger.error(f'结束检测更新失败: {e}')
return False
-
def update_session_all_info(self, session_id: str, diagnosis_info: str = None, treatment_info: str = None, suggestion_info: str = None):
"""同时更新会话的诊断信息、处理信息、建议信息和状态"""
@@ -714,18 +631,21 @@ class DatabaseManager:
update_fields = []
update_values = []
- if diagnosis_info is not None:
+ if diagnosis_info is not None and diagnosis_info.strip() != '':
update_fields.append('diagnosis_info = ?')
update_values.append(diagnosis_info)
status='checked' #默认状态为checked:已完成检查
- if treatment_info is not None:
+ if treatment_info is not None and treatment_info.strip() != '':
update_fields.append('treatment_info = ?')
update_values.append(treatment_info)
status='completed' #处理信息不为空时,状态设为completed:已诊断处理
- if suggestion_info is not None:
+ if suggestion_info is not None and suggestion_info.strip() != '':
update_fields.append('suggestion_info = ?')
- update_values.append(suggestion_info)
+ update_values.append(suggestion_info)
+
+ update_fields.append('status = ?')
+ update_values.append(status)
if not update_fields:
logger.warning(f'没有提供要更新的信息: {session_id}')
@@ -754,11 +674,11 @@ class DatabaseManager:
updated_info.append(f'状态({status})')
logger.info(f'批量更新会话信息成功: {session_id}, 更新字段: {", ".join(updated_info)}')
-
+ return True
except Exception as e:
conn.rollback()
logger.error(f'批量更新会话信息失败: {e}')
- raise
+ return False
def _sync_patient_medical_history_from_session(self, cursor, session_id: str) -> None:
"""根据会话信息同步患者 medical_history 的 doctor/status/lastcheck_time 字段"""
@@ -806,7 +726,8 @@ class DatabaseManager:
try:
offset = (page - 1) * size
cursor.execute('''
- 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
+ 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,
+ (SELECT COUNT(*) FROM detection_data WHERE session_id = s.id) as data_count
FROM detection_sessions s
LEFT JOIN users u ON s.creator_id = u.id
WHERE s.patient_id = ? and s.status in ('checked','completed','reported')
@@ -827,7 +748,8 @@ class DatabaseManager:
'start_time': r[2],
'creator_name': r[3],
'detection_report': r[4],
- 'data_ids': r[5]
+ 'data_ids': r[5],
+ 'data_count': r[6]
}
sessions.append({
'id': item.get('id'),
@@ -835,7 +757,8 @@ class DatabaseManager:
'start_time': item.get('start_time'),
'creator_name': item.get('creator_name'),
'detection_report': item.get('detection_report'),
- 'data_ids': item.get('data_ids')
+ 'data_ids': item.get('data_ids'),
+ 'data_count': item.get('data_count', 0)
})
return sessions
@@ -1118,15 +1041,22 @@ class DatabaseManager:
return False
def has_session_detection_data(self, session_id: str) -> bool:
- """检查指定会话是否存在检测数据,用于判断单次检测是否有效"""
+ """检查指定会话是否存在检测数据或视频数据,用于判断单次检测是否有效"""
conn = self.get_connection()
cursor = conn.cursor()
try:
+ # 检查检测数据
cursor.execute('SELECT COUNT(1) FROM detection_data WHERE session_id = ?', (session_id,))
row = cursor.fetchone()
- count = row[0] if row else 0
- exists = count > 0
- logger.info(f'会话 {session_id} 检测数据存在: {exists} (count={count})')
+ data_count = row[0] if row else 0
+
+ # 检查视频数据
+ cursor.execute('SELECT COUNT(1) FROM detection_video WHERE session_id = ?', (session_id,))
+ video_row = cursor.fetchone()
+ video_count = video_row[0] if video_row else 0
+
+ exists = (data_count > 0) or (video_count > 0)
+ logger.info(f'会话 {session_id} 数据检查: data_count={data_count}, video_count={video_count}, exists={exists}')
return exists
except Exception as e:
logger.error(f'检查会话检测数据存在失败: {e}')
diff --git a/backend/devices/device_coordinator.py b/backend/devices/device_coordinator.py
index 5eb4f852..df73b117 100644
--- a/backend/devices/device_coordinator.py
+++ b/backend/devices/device_coordinator.py
@@ -159,29 +159,29 @@ class DeviceCoordinator:
futures = []
# FemtoBolt深度相机
- if self.device_configs.get('femtobolt', {}).get('enabled', False):
+ if self.device_configs.get('femtobolt', {}).get('enable', False):
future = self.executor.submit(self._init_femtobolt)
futures.append(('femtobolt', future))
# 普通相机:初始化两个实例(camera1 与 camera2)
# camera1 使用 [CAMERA1] 配置;camera2 使用 [CAMERA2](若不存在则回退为 device_index+1)
- if self.device_configs.get('camera1', {}).get('enabled', False):
+ if self.device_configs.get('camera1', {}).get('enable', False):
futures.append(('camera1', self.executor.submit(self._init_camera_by_name, 'camera1', 'CAMERA1')))
- if self.device_configs.get('camera2', {}).get('enabled', False):
+ if self.device_configs.get('camera2', {}).get('enable', False):
futures.append(('camera2', self.executor.submit(self._init_camera_by_name, 'camera2', 'CAMERA2')))
# IMU传感器
- if self.device_configs.get('imu', {}).get('enabled', False):
+ if self.device_configs.get('imu', {}).get('enable', False):
future = self.executor.submit(self._init_imu)
futures.append(('imu', future))
# 压力传感器
- if self.device_configs.get('pressure', {}).get('enabled', False):
+ if self.device_configs.get('pressure', {}).get('enable', False):
future = self.executor.submit(self._init_pressure)
futures.append(('pressure', future))
# 遥控器
- if self.device_configs.get('remote', {}).get('enabled', False):
+ if self.device_configs.get('remote', {}).get('enable', False):
future = self.executor.submit(self._init_remote)
futures.append(('remote', future))
@@ -244,8 +244,8 @@ class DeviceCoordinator:
return parser.getboolean(sec, key)
except Exception:
return fallback
- enabled = get_bool(section, 'enabled', True)
- if not enabled:
+ enable = get_bool(section, 'enable', True)
+ if not enable:
self.logger.info(f"{device_name} 未启用,跳过初始化")
return False
# 填充覆盖项
@@ -682,8 +682,8 @@ class DeviceCoordinator:
return parser.getboolean(sec, key)
except Exception:
return fallback
- enabled = get_bool(section, 'enabled', True)
- if not enabled:
+ enable = get_bool(section, 'enable', True)
+ if not enable:
raise Exception(f"{device_name} 未启用")
idx2 = get_int(section, 'device_index', None)
if idx2 is not None:
diff --git a/backend/devices/remote_control_manager.py b/backend/devices/remote_control_manager.py
index f9c58dd2..68fb6538 100644
--- a/backend/devices/remote_control_manager.py
+++ b/backend/devices/remote_control_manager.py
@@ -39,7 +39,7 @@ class RemoteControlManager(BaseDevice):
timeout = float(self.config_manager.get_config_value('REMOTE', 'timeout', fallback='0.1'))
instance_config: Dict[str, Any] = {
- 'enabled': True,
+ 'enable': True,
'port': port,
'baudrate': baudrate,
'timeout': timeout,
diff --git a/backend/devices/screen_recorder.py b/backend/devices/screen_recorder.py
index d5b63cfa..14b871eb 100644
--- a/backend/devices/screen_recorder.py
+++ b/backend/devices/screen_recorder.py
@@ -1280,7 +1280,7 @@ class RecordingManager:
'body_pose': None,
'body_image': None,
'foot_data': detection_data.get('foot_data'),
- 'foot_data_image': None,
+ 'foot_data_image': detection_data.get('foot_data_image'),
'foot1_image': None,
'foot2_image': None,
'screen_image': None,
@@ -1292,8 +1292,7 @@ class RecordingManager:
image_fields = [
('body_image', 'body'),
('foot1_image', 'foot1'),
- ('foot2_image', 'foot2'),
- ('foot_data_image', 'foot_data')
+ ('foot2_image', 'foot2')
]
for field, prefix in image_fields:
@@ -1322,11 +1321,15 @@ class RecordingManager:
except Exception as e:
self.logger.error(f'保存{field}失败: {e}')
- # 屏幕截图
- screen_image = self._capture_screen_image(data_dir, data.get('screen_location'), timestamp=timestamp)
+ # 完整屏幕截图--根据screen_location 进行截图
+ screen_image = self._capture_screen_image(data_dir, data.get('screen_location'),'screen', timestamp=timestamp)
if screen_image:
data['screen_image'] = str(os.path.join( patient_id, session_id, f"image_{timestamp}", screen_image))
-
+ # 足部压力屏幕截图——根据foot_data_image 进行截图
+ foot_data_image = self._capture_screen_image(data_dir, data.get('foot_data_image'),'foot_data', timestamp=timestamp)
+ if foot_data_image:
+ data['foot_data_image'] = str(os.path.join( patient_id, session_id, f"image_{timestamp}", foot_data_image))
+
self.logger.debug(f'数据保存完成: {session_id}, 时间戳: {timestamp}')
except Exception as e:
@@ -1336,7 +1339,7 @@ class RecordingManager:
- def _capture_screen_image(self, data_dir, screen_location, timestamp) -> Optional[str]:
+ def _capture_screen_image(self, data_dir, screen_location,type, timestamp) -> Optional[str]:
"""
采集屏幕截图,根据screen_region 进行截图
@@ -1358,7 +1361,7 @@ class RecordingManager:
# 保存截图
from pathlib import Path
- screen_filename = f'screen_{timestamp}.jpg'
+ screen_filename = f'{type}_{timestamp}.jpg'
image_path = Path(data_dir) / screen_filename
screenshot.save(str(image_path), quality=95, optimize=True)
diff --git a/backend/devices/utils/config_manager.py b/backend/devices/utils/config_manager.py
index d152e93a..3e3a94e5 100644
--- a/backend/devices/utils/config_manager.py
+++ b/backend/devices/utils/config_manager.py
@@ -143,7 +143,7 @@ class ConfigManager:
获取设备配置
Args:
- device_name: 设备名称 (camera1, camera2, femtobolt, imu, pressure)
+ device_name: 设备名称 (camera1, camera2, femtobolt, imu, pressure, remote)
Returns:
Dict[str, Any]: 设备配置字典
@@ -180,7 +180,7 @@ class ConfigManager:
Dict[str, Any]: 相机配置
"""
return {
- 'enabled': self.config.getboolean('CAMERA1', 'enabled', fallback=True),
+ 'enable': self.config.getboolean('CAMERA1', 'enable', fallback=False),
'device_index': self.config.getint('CAMERA1', 'device_index', fallback=0),
'width': self.config.getint('CAMERA1', 'width', fallback=1280),
'height': self.config.getint('CAMERA1', 'height', fallback=720),
@@ -197,7 +197,7 @@ class ConfigManager:
Dict[str, Any]:
"""
return {
- 'enabled': self.config.getboolean('CAMERA2', 'enabled', fallback=True),
+ 'enable': self.config.getboolean('CAMERA2', 'enable', fallback=False),
'device_index': self.config.getint('CAMERA2', 'device_index', fallback=0),
'width': self.config.getint('CAMERA2', 'width', fallback=1280),
'height': self.config.getint('CAMERA2', 'height', fallback=720),
@@ -214,7 +214,7 @@ class ConfigManager:
Dict[str, Any]: FemtoBolt配置
"""
return {
- 'enabled': self.config.getboolean('FEMTOBOLT', 'enabled', fallback=True),
+ 'enable': self.config.getboolean('FEMTOBOLT', 'enable', fallback=False),
'algorithm_type': self.config.get('FEMTOBOLT', 'algorithm_type', fallback='opencv'),
'color_resolution': self.config.get('FEMTOBOLT', 'color_resolution', fallback='1080P'),
'depth_mode': self.config.get('FEMTOBOLT', 'depth_mode', fallback='NFOV_UNBINNED'),
@@ -232,7 +232,7 @@ class ConfigManager:
Dict[str, Any]: IMU配置
"""
return {
- 'enabled': self.config.getboolean('DEVICES', 'imu_enabled', fallback=True),
+ 'enable': self.config.getboolean('DEVICES', 'imu_enable', fallback=False),
'device_type': self.config.get('DEVICES', 'imu_device_type', fallback='mock'),
'port': self.config.get('DEVICES', 'imu_port', fallback='COM7'),
'baudrate': self.config.getint('DEVICES', 'imu_baudrate', fallback=9600),
@@ -249,7 +249,7 @@ class ConfigManager:
Dict[str, Any]: 压力传感器配置
"""
return {
- 'enabled': self.config.getboolean('DEVICES', 'pressure_enabled', fallback=True),
+ 'enable': self.config.getboolean('DEVICES', 'pressure_enable', fallback=False),
'device_type': self.config.get('DEVICES', 'pressure_device_type', fallback='mock'),
'port': self.config.get('DEVICES', 'pressure_port', fallback='COM8'),
'baudrate': self.config.getint('DEVICES', 'pressure_baudrate', fallback=115200),
@@ -265,7 +265,7 @@ class ConfigManager:
Dict[str, Any]: 远程控制配置
"""
return {
- 'enabled': self.config.getboolean('REMOTE', 'enable', fallback=True),
+ 'enable': self.config.getboolean('REMOTE', 'enable', fallback=False),
'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),
@@ -376,7 +376,7 @@ class ConfigManager:
warnings = []
# 验证必需的配置段
- required_sections = ['DEVICES', 'CAMERA1', 'CAMERA2', 'FEMTOBOLT', 'SYSTEM']
+ required_sections = ['DEVICES', 'CAMERA1', 'CAMERA2', 'FEMTOBOLT', 'REMOTE']
for section in required_sections:
if not self.config.has_section(section):
errors.append(f"缺少必需的配置段: {section}")
@@ -395,228 +395,7 @@ class ConfigManager:
'valid': len(errors) == 0
}
- # HTTP接口设备参数设置方法
- def set_imu_config(self, config_data: Dict[str, Any]) -> Dict[str, Any]:
- """
- 设置IMU设备配置
-
- Args:
- config_data: IMU配置数据
- {
- 'device_type': 'real' | 'mock' | 'ble',
- 'port': 'COM6',
- 'baudrate': 9600,
- 'mac_address': 'ef:3c:1a:0a:fe:02'
- }
-
- Returns:
- Dict[str, Any]: 设置结果
- """
- try:
- # 验证必需参数
- if 'device_type' in config_data:
- self.set_config_value('DEVICES', 'imu_device_type', config_data['device_type'])
- if 'port' in config_data:
- self.set_config_value('DEVICES', 'imu_port', config_data['port'])
- if 'baudrate' in config_data:
- self.set_config_value('DEVICES', 'imu_baudrate', str(config_data['baudrate']))
- if 'mac_address' in config_data:
- self.set_config_value('DEVICES', 'imu_mac_address', config_data['mac_address'])
-
- # 保存配置
- self.save_config()
-
- self.logger.info(f"IMU配置已更新: {config_data}")
- return {
- 'success': True,
- 'message': 'IMU配置更新成功',
- 'config': self.get_device_config('imu')
- }
- except Exception as e:
- self.logger.error(f"设置IMU配置失败: {e}")
- return {
- 'success': False,
- 'message': f'设置IMU配置失败: {str(e)}'
- }
-
- def set_pressure_config(self, config_data: Dict[str, Any]) -> Dict[str, Any]:
- """
- 设置压力板设备配置
-
- Args:
- config_data: 压力板配置数据
- {
- 'device_type': 'real' | 'mock',
- 'use_mock': False,
- 'port': 'COM5',
- 'baudrate': 115200
- }
-
- Returns:
- Dict[str, Any]: 设置结果
- """
- try:
- # 验证必需参数
- if 'device_type' in config_data:
- self.set_config_value('DEVICES', 'pressure_device_type', config_data['device_type'])
- if 'use_mock' in config_data:
- self.set_config_value('DEVICES', 'pressure_use_mock', str(config_data['use_mock']))
- if 'port' in config_data:
- self.set_config_value('DEVICES', 'pressure_port', config_data['port'])
- if 'baudrate' in config_data:
- self.set_config_value('DEVICES', 'pressure_baudrate', str(config_data['baudrate']))
-
- # 保存配置
- self.save_config()
-
- self.logger.info(f"压力板配置已更新: {config_data}")
- return {
- 'success': True,
- 'message': '压力板配置更新成功',
- 'config': self.get_device_config('pressure')
- }
- except Exception as e:
- self.logger.error(f"设置压力板配置失败: {e}")
- return {
- 'success': False,
- 'message': f'设置压力板配置失败: {str(e)}'
- }
-
- def set_camera1_config(self, config_data: Dict[str, Any]) -> Dict[str, Any]:
- """
- 设置相机设备配置
-
- Args:
- config_data: 相机配置数据
- {
- 'device_index': 1,
- 'width': 1280,
- 'height': 720,
- 'fps': 30
- }
-
- Returns:
- Dict[str, Any]: 设置结果
- """
- try:
- # 验证必需参数
- if 'device_index' in config_data:
- self.set_config_value('CAMERA1', 'device_index', str(config_data['device_index']))
- if 'width' in config_data:
- self.set_config_value('CAMERA1', 'width', str(config_data['width']))
- if 'height' in config_data:
- self.set_config_value('CAMERA1', 'height', str(config_data['height']))
- if 'fps' in config_data:
- self.set_config_value('CAMERA1', 'fps', str(config_data['fps']))
- if 'backend' in config_data:
- self.set_config_value('CAMERA1', 'backend', str(config_data['backend']))
-
- # 保存配置
- self.save_config()
-
- self.logger.info(f"相机配置已更新: {config_data}")
- return {
- 'success': True,
- 'message': '相机配置更新成功',
- 'config': self.get_device_config('camera1')
- }
- except Exception as e:
- self.logger.error(f"设置相机配置失败: {e}")
- return {
- 'success': False,
- 'message': f'设置相机配置失败: {str(e)}'
- }
- def set_camera2_config(self, config_data: Dict[str, Any]) -> Dict[str, Any]:
- """
- 设置相机设备配置
-
- Args:
- config_data: 相机配置数据
- {
- 'device_index': 1,
- 'width': 1280,
- 'height': 720,
- 'fps': 30
- }
-
- Returns:
- Dict[str, Any]: 设置结果
- """
- try:
- # 验证必需参数
- if 'device_index' in config_data:
- self.set_config_value('CAMERA2', 'device_index', str(config_data['device_index']))
- if 'width' in config_data:
- self.set_config_value('CAMERA2', 'width', str(config_data['width']))
- if 'height' in config_data:
- self.set_config_value('CAMERA2', 'height', str(config_data['height']))
- if 'fps' in config_data:
- self.set_config_value('CAMERA2', 'fps', str(config_data['fps']))
- if 'backend' in config_data:
- self.set_config_value('CAMERA2', 'backend', str(config_data['backend']))
-
- # 保存配置
- self.save_config()
-
- self.logger.info(f"相机配置已更新: {config_data}")
- return {
- 'success': True,
- 'message': '相机配置更新成功',
- 'config': self.get_device_config('camera2')
- }
- except Exception as e:
- self.logger.error(f"设置相机配置失败: {e}")
- return {
- 'success': False,
- 'message': f'设置相机配置失败: {str(e)}'
- }
- def set_femtobolt_config(self, config_data: Dict[str, Any]) -> Dict[str, Any]:
- """
- 设置FemtoBolt设备配置
-
- Args:
- config_data: FemtoBolt配置数据
- {
- 'color_resolution': '1080P',
- 'depth_mode': 'NFOV_UNBINNED',
- 'fps': 30,
- 'depth_range_min': 1200,
- 'depth_range_max': 1500
- }
-
- Returns:
- Dict[str, Any]: 设置结果
- """
- try:
- # 验证必需参数
- if 'algorithm_type' in config_data:
- self.set_config_value('FEMTOBOLT', 'algorithm_type', config_data['algorithm_type'])
- if 'color_resolution' in config_data:
- self.set_config_value('FEMTOBOLT', 'color_resolution', config_data['color_resolution'])
- if 'depth_mode' in config_data:
- self.set_config_value('FEMTOBOLT', 'depth_mode', config_data['depth_mode'])
- if 'camera_fps' in config_data:
- self.set_config_value('FEMTOBOLT', 'camera_fps', str(config_data['camera_fps']))
- if 'depth_range_min' in config_data:
- self.set_config_value('FEMTOBOLT', 'depth_range_min', str(config_data['depth_range_min']))
- if 'depth_range_max' in config_data:
- self.set_config_value('FEMTOBOLT', 'depth_range_max', str(config_data['depth_range_max']))
-
- # 保存配置
- self.save_config()
-
- self.logger.info(f"FemtoBolt配置已更新: {config_data}")
- return {
- 'success': True,
- 'message': 'FemtoBolt配置更新成功',
- 'config': self.get_device_config('femtobolt')
- }
- except Exception as e:
- self.logger.error(f"设置FemtoBolt配置失败: {e}")
- return {
- 'success': False,
- 'message': f'设置FemtoBolt配置失败: {str(e)}'
- }
+
def get_all_device_configs(self) -> Dict[str, Any]:
"""
@@ -652,6 +431,8 @@ class ConfigManager:
if 'imu' in configs:
try:
config_data = configs['imu']
+ if 'enable' in config_data:
+ self.set_config_value('DEVICES', 'imu_enable', str(config_data['enable']))
if 'device_type' in config_data:
self.set_config_value('DEVICES', 'imu_device_type', config_data['device_type'])
if 'use_mock' in config_data:
@@ -677,6 +458,8 @@ class ConfigManager:
if 'pressure' in configs:
try:
config_data = configs['pressure']
+ if 'enable' in config_data:
+ self.set_config_value('DEVICES', 'pressure_enable', str(config_data['enable']))
if 'device_type' in config_data:
self.set_config_value('DEVICES', 'pressure_device_type', config_data['device_type'])
if 'use_mock' in config_data:
@@ -702,6 +485,8 @@ class ConfigManager:
if 'camera1' in configs:
try:
config_data = configs['camera1']
+ if 'enable' in config_data:
+ self.set_config_value('CAMERA1', 'enable', str(config_data['enable']))
if 'device_index' in config_data:
self.set_config_value('CAMERA1', 'device_index', str(config_data['device_index']))
if 'width' in config_data:
@@ -734,6 +519,8 @@ class ConfigManager:
if 'camera2' in configs:
try:
config_data = configs['camera2']
+ if 'enable' in config_data:
+ self.set_config_value('CAMERA2', 'enable', str(config_data['enable']))
if 'device_index' in config_data:
self.set_config_value('CAMERA2', 'device_index', str(config_data['device_index']))
if 'width' in config_data:
@@ -767,6 +554,8 @@ class ConfigManager:
if 'femtobolt' in configs:
try:
config_data = configs['femtobolt']
+ if 'enable' in config_data:
+ self.set_config_value('FEMTOBOLT', 'enable', str(config_data['enable']))
if 'algorithm_type' in config_data:
self.set_config_value('FEMTOBOLT', 'algorithm_type', config_data['algorithm_type'])
if 'color_resolution' in config_data:
@@ -802,8 +591,8 @@ class ConfigManager:
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 'enable' in config_data:
+ self.set_config_value('REMOTE', 'enable', str(config_data['enable']))
if 'port' in config_data:
self.set_config_value('REMOTE', 'port', config_data['port'])
if 'baudrate' in config_data:
diff --git a/backend/main.py b/backend/main.py
index 982e8550..a0aec180 100644
--- a/backend/main.py
+++ b/backend/main.py
@@ -1211,7 +1211,7 @@ class AppServer:
}), 400
# 验证数据格式
- supported_devices = ['camera1','camera2', 'femtobolt','imu','pressure']
+ supported_devices = ['camera1','camera2', 'femtobolt','imu','pressure','remote']
for device_name in data.keys():
if device_name not in supported_devices:
return jsonify({
@@ -1386,7 +1386,7 @@ class AppServer:
diagnosis_info = data.get('diagnosis_info')
treatment_info = data.get('treatment_info')
suggestion_info = data.get('suggestion_info')
- success = self.db_manager.update_session_endcheck(
+ success = self.db_manager.update_session_all_info(
session_id,
diagnosis_info=diagnosis_info,
treatment_info=treatment_info,
@@ -1534,13 +1534,6 @@ class AppServer:
suggestion_info = data.get('suggestion_info')
- # 验证至少提供一个要更新的字段
- if not any([diagnosis_info, treatment_info, suggestion_info]):
- return jsonify({
- 'success': False,
- 'error': '至少需要提供一个要更新的字段(diagnosis_info, treatment_info, suggestion_info)'
- }), 400
-
# 调用数据库管理器的批量更新方法
self.db_manager.update_session_all_info(
session_id=session_id,
@@ -1556,9 +1549,7 @@ class AppServer:
if treatment_info is not None:
updated_fields.append('处理信息')
if suggestion_info is not None:
- updated_fields.append('建议信息')
- if status is not None:
- updated_fields.append(f'状态({status})')
+ updated_fields.append('建议信息')
self.logger.info(f'会话信息保存成功: {session_id}, 更新字段: {", ".join(updated_fields)}')
diff --git a/document/串口遥控器遥控界面操作说明.md b/document/串口遥控器遥控界面操作说明.md
index 4f721397..fcb8eab5 100644
--- a/document/串口遥控器遥控界面操作说明.md
+++ b/document/串口遥控器遥控界面操作说明.md
@@ -10,7 +10,7 @@
- [REMOTE] port,缺省 COM6
- [REMOTE] baudrate,缺省 115200
- [REMOTE] timeout,缺省 0.1 秒
- - [DEVICES] remote_enabled(是否启用),缺省 true
+ - [DEVICES] remote_enable(是否启用),缺省 true
- 串口参数:115200 bps,8 数据位,1 停止位,无校验(8N1)。
## 报文格式
diff --git a/frontend/src/renderer/src/views/Detection.vue b/frontend/src/renderer/src/views/Detection.vue
index 5e0a697b..ade6bb60 100644
--- a/frontend/src/renderer/src/views/Detection.vue
+++ b/frontend/src/renderer/src/views/Detection.vue
@@ -17,15 +17,14 @@