From f3495d88274ac46aa757e63d3269756edf6cc01b Mon Sep 17 00:00:00 2001 From: root <13910913995@163.com> Date: Wed, 20 Aug 2025 09:11:55 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app.py | 75 ----------- backend/main.py | 350 +++++++++++++++++++++++++++--------------------- 2 files changed, 199 insertions(+), 226 deletions(-) diff --git a/backend/app.py b/backend/app.py index ae32a17f..aaed2598 100644 --- a/backend/app.py +++ b/backend/app.py @@ -932,81 +932,6 @@ def collect_detection_data(session_id): logger.error(f'采集检测数据失败: {e}') return jsonify({'success': False, 'error': str(e)}), 500 -# ==================== 同步录制API ==================== - -@app.route('/api/recording/sync/start', methods=['POST']) -def start_sync_recording(): - """启动同步录制""" - try: - if not device_manager: - return jsonify({'success': False, 'error': '设备管理器未初始化'}), 500 - - data = flask_request.get_json() - session_id = data.get('session_id') - patient_id = data.get('patient_id') - - if not session_id or not patient_id: - return jsonify({ - 'success': False, - 'error': '缺少必要参数: session_id 和 patient_id' - }), 400 - - result = device_manager.start_recording(session_id, patient_id) - - if result['success']: - logger.info(f'同步录制已启动 - 会话ID: {session_id}, 患者ID: {patient_id}') - return jsonify(result) - else: - return jsonify(result), 500 - - except Exception as e: - logger.error(f'启动同步录制失败: {e}') - return jsonify({'success': False, 'error': str(e)}), 500 - -@app.route('/api/recording/sync/stop', methods=['POST']) -def stop_sync_recording(): - """停止同步录制""" - try: - if not device_manager: - return jsonify({'success': False, 'error': '设备管理器未初始化'}), 500 - - data = flask_request.get_json() - session_id = data.get('session_id') - video_data = data.get('videoData') # 新增接收前端传递的视频数据 - if not video_data.startswith('data:video/'): - return jsonify({ - 'success': False, - 'message': '无效的视频数据格式' - }), 400 - - # 提取base64数据 - try: - import base64 - header, encoded = video_data.split(',', 1) - video_bytes = base64.b64decode(encoded) - except Exception as e: - return jsonify({ - 'success': False, - 'message': f'视频数据解码失败: {str(e)}' - }), 400 - if not session_id: - return jsonify({ - 'success': False, - 'error': '缺少必要参数: session_id' - }), 400 - - result = device_manager.stop_recording(session_id, video_data_base64=video_bytes) - - if result['success']: - logger.info(f'同步录制已停止 - 会话ID: {session_id}') - return jsonify(result) - else: - return jsonify(result), 500 - - except Exception as e: - logger.error(f'停止同步录制失败: {e}') - return jsonify({'success': False, 'error': str(e)}), 500 - @app.route('/api/history/sessions', methods=['GET']) def get_detection_sessions(): diff --git a/backend/main.py b/backend/main.py index 05050e67..1aca4097 100644 --- a/backend/main.py +++ b/backend/main.py @@ -876,196 +876,242 @@ class AppServer: def start_detection(): """开始检测""" try: + if not self.db_manager or not self.device_coordinator: + return jsonify({'success': False, 'error': '数据库管理器或设备管理器未初始化'}), 500 + data = flask_request.get_json() patient_id = data.get('patient_id') - detection_type = data.get('detection_type', 'balance') - duration = data.get('duration', 30) + creator_id = data.get('creator_id') + if not patient_id or not creator_id: + return jsonify({'success': False, 'error': '缺少患者ID或创建人ID'}), 400 - if not patient_id: - return jsonify({'success': False, 'error': '患者ID不能为空'}), 400 + # 调用create_detection_session方法,settings传空字典 + session_id = self.db_manager.create_detection_session(patient_id, settings={}, creator_id=creator_id) - # 检查是否已有检测在进行 - if self.current_detection: - return jsonify({'success': False, 'error': '已有检测在进行中'}), 400 + # 开始同步录制 + recording_response = None + try: + recording_response = self.device_coordinator.start_recording(session_id, patient_id) + except Exception as rec_e: + self.logger.error(f'开始同步录制失败: {rec_e}') - # 启动检测 - detection_id = self.db_manager.create_detection_session( - patient_id=patient_id, - detection_type=detection_type, - duration=duration - ) + start_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') - if detection_id: - self.current_detection = { - 'id': detection_id, - 'patient_id': patient_id, - 'type': detection_type, - 'duration': duration, - 'start_time': time.time() - } - - # 启动检测线程 - self.detection_thread = threading.Thread( - target=self._detection_worker, - args=(detection_id, duration) - ) - self.detection_thread.start() - - return jsonify({ - 'success': True, - 'message': '检测已开始', - 'data': {'detection_id': detection_id} - }) - else: - return jsonify({'success': False, 'error': '创建检测会话失败'}), 500 - + return jsonify({'success': True, 'session_id': session_id, 'detectionStartTime': start_time, 'recording': recording_response}) except Exception as e: self.logger.error(f'开始检测失败: {e}') return jsonify({'success': False, 'error': str(e)}), 500 - @self.app.route('/api/detection/stop', methods=['POST']) - def stop_detection(): + @self.app.route('/api/detection//stop', methods=['POST']) + def stop_detection(session_id): """停止检测""" try: - if not self.current_detection: - return jsonify({'success': False, 'error': '没有正在进行的检测'}), 400 + if not self.db_manager or not self.device_coordinator: + self.logger.error('数据库管理器或设备管理器未初始化') + return jsonify({'success': False, 'error': '数据库管理器或设备管理器未初始化'}), 500 - # 停止检测 - detection_id = self.current_detection['id'] - self.db_manager.end_detection_session(detection_id) + if not session_id: + self.logger.error('缺少会话ID') + return jsonify({ + 'success': False, + 'error': '缺少会话ID' + }), 400 - self.current_detection = None + data = flask_request.get_json() + video_data = data['videoData'] + mime_type = data.get('mimeType', 'video/webm;codecs=vp9') # 默认webm格式 + import base64 + # 验证base64视频数据格式 + if not video_data.startswith('data:video/'): + return jsonify({ + 'success': False, + 'message': '无效的视频数据格式' + }), 400 + try: + header, encoded = video_data.split(',', 1) + video_bytes = base64.b64decode(encoded) + except Exception as e: + return jsonify({ + 'success': False, + 'message': f'视频数据解码失败: {str(e)}' + }), 400 + # 停止同步录制,传递视频数据 + try: + restrt = self.device_coordinator.stop_recording(session_id, video_data_base64=video_bytes) + self.logger.error(restrt) + except Exception as rec_e: + self.logger.error(f'停止同步录制失败: {rec_e}', exc_info=True) + raise - return jsonify({'success': True, 'message': '检测已停止'}) + # 更新会话状态为已完成 + success = self.db_manager.update_session_status(session_id, 'completed') - except Exception as e: - self.logger.error(f'停止检测失败: {e}') - return jsonify({'success': False, 'error': str(e)}), 500 - - @self.app.route('/api/detection/status', methods=['GET']) - def get_detection_status(): - """获取检测状态""" - try: - if self.current_detection: - elapsed_time = time.time() - self.current_detection['start_time'] - remaining_time = max(0, self.current_detection['duration'] - elapsed_time) - + if success: + self.logger.info(f'检测会话已停止 - 会话ID: {session_id}') return jsonify({ 'success': True, - 'data': { - 'is_detecting': True, - 'detection_id': self.current_detection['id'], - 'patient_id': self.current_detection['patient_id'], - 'type': self.current_detection['type'], - 'elapsed_time': elapsed_time, - 'remaining_time': remaining_time, - 'progress': min(100, (elapsed_time / self.current_detection['duration']) * 100) - } + '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 + + @self.app.route('/api/detection//status', methods=['GET']) + def get_detection_status(session_id): + """获取检测状态""" + try: + if not self.db_manager: + return jsonify({'success': False, 'error': '数据库管理器未初始化'}), 500 + + if not session_id: + return jsonify({ + 'success': False, + 'error': '缺少会话ID' + }), 400 + + # 获取会话数据 + session_data = self.db_manager.get_session_data(session_id) + + if session_data: + return jsonify({ + 'success': True, + 'data': session_data }) else: return jsonify({ - 'success': True, - 'data': {'is_detecting': False} - }) + 'success': False, + 'error': '会话不存在' + }), 404 except Exception as e: self.logger.error(f'获取检测状态失败: {e}') return jsonify({'success': False, 'error': str(e)}), 500 - @self.app.route('/api/detection/save-session', methods=['POST']) - def save_session_info(): - """保存会话信息""" + @self.app.route('/api/detection//save-info', methods=['POST']) + def save_session_info(session_id): + """保存会话信息(诊断、处理、建议、状态)""" try: - data = flask_request.get_json() - session_id = data.get('session_id') - session_info = data.get('session_info', {}) + if not self.db_manager: + return jsonify({'success': False, 'error': '数据库管理器未初始化'}), 500 if not session_id: - return jsonify({'success': False, 'error': '会话ID不能为空'}), 400 + return jsonify({ + 'success': False, + 'error': '缺少会话ID' + }), 400 + + # 获取请求数据 + data = flask_request.get_json() or {} + 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]): + return jsonify({ + 'success': False, + 'error': '至少需要提供一个要更新的字段(diagnosis_info, treatment_info, suggestion_info, status)' + }), 400 + + # 调用数据库管理器的批量更新方法 + self.db_manager.update_session_all_info( + session_id=session_id, + diagnosis_info=diagnosis_info, + treatment_info=treatment_info, + suggestion_info=suggestion_info, + status=status + ) + + # 构建更新信息反馈 + updated_fields = [] + if diagnosis_info is not None: + updated_fields.append('诊断信息') + 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})') + + self.logger.info(f'会话信息保存成功: {session_id}, 更新字段: {", ".join(updated_fields)}') + + return jsonify({ + 'success': True, + 'message': f'会话信息保存成功,更新字段: {", ".join(updated_fields)}', + 'data': { + 'session_id': session_id, + 'updated_fields': updated_fields + } + }) - result = self.db_manager.save_session_info(session_id, session_info) - if result: - return jsonify({'success': True, 'message': '会话信息保存成功'}) - else: - return jsonify({'success': False, 'error': '会话信息保存失败'}), 500 - except Exception as e: self.logger.error(f'保存会话信息失败: {e}') return jsonify({'success': False, 'error': str(e)}), 500 - @self.app.route('/api/detection/collect-data', methods=['POST']) - def collect_detection_data(): + @self.app.route('/api/detection//collect', methods=['POST']) + def collect_detection_data(session_id): """采集检测数据""" try: - data = flask_request.get_json() - session_id = data.get('session_id') - data_type = data.get('data_type') - data_content = data.get('data') + if not self.db_manager: + return jsonify({'success': False, 'error': '数据库管理器未初始化'}), 500 - if not all([session_id, data_type, data_content]): - return jsonify({'success': False, 'error': '参数不完整'}), 400 + if not self.device_coordinator: + return jsonify({'success': False, 'error': '设备管理器未初始化'}), 500 + + # 获取请求数据 + data = flask_request.get_json() or {} + patient_id = data.get('patient_id') + screen_image_base64 = data.get('imageData') + + # 如果没有提供patient_id,从会话信息中获取 + if not patient_id: + session_data = self.db_manager.get_session_data(session_id) + if not session_data: + return jsonify({ + 'success': False, + 'error': '检测会话不存在' + }), 404 + patient_id = session_data.get('patient_id') + + if not patient_id: + return jsonify({ + 'success': False, + 'error': '无法获取患者ID' + }), 400 + + # 调用设备管理器采集数据 + collected_data = self.device_coordinator.collect_data( + session_id=session_id, + patient_id=patient_id, + screen_image_base64=screen_image_base64 + ) + + # 将采集的数据保存到数据库 + if collected_data: + self.db_manager.save_detection_data(session_id, collected_data) + self.logger.info(f'检测数据采集并保存成功: {session_id}') + + return jsonify({ + 'success': True, + 'data': { + 'session_id': session_id, + 'timestamp': collected_data.get('timestamp'), + 'data_collected': bool(collected_data) + }, + 'message': '数据采集成功' + }) - result = self.db_manager.save_detection_data(session_id, data_type, data_content) - if result: - return jsonify({'success': True, 'message': '数据采集成功'}) - else: - return jsonify({'success': False, 'error': '数据采集失败'}), 500 - except Exception as e: self.logger.error(f'采集检测数据失败: {e}') - return jsonify({'success': False, 'error': str(e)}), 500 - - # ==================== 同步录制API ==================== - - @self.app.route('/api/sync-recording/start', methods=['POST']) - def start_sync_recording(): - """启动同步录制""" - try: - data = flask_request.get_json() - session_id = data.get('session_id') - - if not session_id: - return jsonify({'success': False, 'error': '会话ID不能为空'}), 400 - - if self.device_manager: - result = self.device_manager.start_sync_recording(session_id) - if result['success']: - self.logger.info(f'同步录制已启动 - 会话ID: {session_id}') - return jsonify(result) - else: - return jsonify(result), 500 - else: - return jsonify({'success': False, 'error': '设备管理器未初始化'}), 500 - - except Exception as e: - self.logger.error(f'启动同步录制失败: {e}') - return jsonify({'success': False, 'error': str(e)}), 500 - - @self.app.route('/api/sync-recording/stop', methods=['POST']) - def stop_sync_recording(): - """停止同步录制""" - try: - data = flask_request.get_json() - session_id = data.get('session_id') - - if not session_id: - return jsonify({'success': False, 'error': '会话ID不能为空'}), 400 - - if self.device_manager: - result = self.device_manager.stop_sync_recording(session_id) - if result['success']: - self.logger.info(f'同步录制已停止 - 会话ID: {session_id}') - return jsonify(result) - else: - return jsonify(result), 500 - else: - return jsonify({'success': False, 'error': '设备管理器未初始化'}), 500 - - except Exception as e: - self.logger.error(f'停止同步录制失败: {e}') - return jsonify({'success': False, 'error': str(e)}), 500 - - # ==================== 历史记录API ==================== + return jsonify({'success': False, 'error': str(e)}), 500 @self.app.route('/api/history/sessions', methods=['GET']) def get_detection_sessions(): @@ -1101,7 +1147,9 @@ class AppServer: @self.app.errorhandler(500) def internal_error(error): return jsonify({'success': False, 'error': '服务器内部错误'}), 500 - + + # ==================== SOCKET事件 ==================== + def _register_socketio_events(self): """注册SocketIO事件""" if self.socketio is None: