#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 身体平衡评估系统 - 后端服务器 (简化版本) 专门用于PyInstaller打包的版本,移除了SocketIO功能 """ import os import sys import json import time import threading from datetime import datetime from flask import Flask, jsonify, send_file from flask import request as flask_request from flask_cors import CORS import sqlite3 import logging from pathlib import Path import cv2 import configparser # 添加当前目录到Python路径 sys.path.append(os.path.dirname(os.path.abspath(__file__))) # 导入自定义模块 from database import DatabaseManager from device_manager import DeviceManager, VideoStreamManager from utils import config as app_config # 配置日志 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler('logs/backend.log', encoding='utf-8'), logging.StreamHandler() ] ) logger = logging.getLogger(__name__) # 创建Flask应用 app = Flask(__name__) app.config['SECRET_KEY'] = 'body-balance-detection-system-2024' # 启用CORS支持 CORS(app, origins='*', supports_credentials=True, allow_headers=['Content-Type', 'Authorization'], methods=['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']) # 读取RTSP配置 config = configparser.ConfigParser() config_path = os.path.join(os.path.dirname(__file__), 'config.ini') if not os.path.exists(config_path): # 如果当前目录没有config.ini,尝试上级目录 config_path = os.path.join(os.path.dirname(__file__), '..', 'config.ini') config.read(config_path, encoding='utf-8') # 全局变量 db_manager = None device_manager = None current_detection = None detection_thread = None video_stream_manager = None def init_app(): """初始化应用""" global db_manager, device_manager, video_stream_manager try: # 初始化数据库管理器 db_path = os.path.join(os.path.dirname(__file__), 'data', 'body_balance.db') os.makedirs(os.path.dirname(db_path), exist_ok=True) db_manager = DatabaseManager(db_path) # 初始化数据库表结构 db_manager.init_database() logger.info("数据库管理器初始化成功") # 初始化设备管理器 device_manager = DeviceManager() logger.info("设备管理器初始化成功") # 初始化视频流管理器 video_stream_manager = VideoStreamManager() logger.info("视频流管理器初始化成功") logger.info("应用初始化完成") except Exception as e: logger.error(f"应用初始化失败: {e}") raise @app.route('/health', methods=['GET']) def health_check(): """健康检查接口""" return jsonify({ 'status': 'ok', 'timestamp': datetime.now().isoformat(), 'message': '身体平衡评估系统后端服务正常运行' }) @app.route('/api/health', methods=['GET']) def api_health_check(): """API健康检查接口""" return jsonify({ 'status': 'success', 'data': { 'service': '身体平衡评估系统', 'version': '1.0.0', 'timestamp': datetime.now().isoformat() } }) @app.route('/api/auth/login', methods=['POST']) def login(): """用户登录接口""" try: data = flask_request.get_json() username = data.get('username') password = data.get('password') if not username or not password: return jsonify({ 'status': 'error', 'message': '用户名和密码不能为空' }), 400 # 验证用户凭据 user = db_manager.authenticate_user(username, password) if user: return jsonify({ 'status': 'success', 'message': '登录成功', 'data': { 'user_id': user['id'], 'username': user['username'], 'role': user['role'], 'token': 'simple_token_' + str(user['id']) } }) else: return jsonify({ 'status': 'error', 'message': '用户名或密码错误' }), 401 except Exception as e: logger.error(f"登录失败: {e}") return jsonify({'status': 'error', 'message': '登录失败'}), 500 @app.route('/api/auth/register', methods=['POST']) def register(): """用户注册接口""" try: data = flask_request.get_json() username = data.get('username') password = data.get('password') email = data.get('email', '') if not username or not password: return jsonify({ 'status': 'error', 'message': '用户名和密码不能为空' }), 400 # 创建用户 user_id = db_manager.create_user(username, password, email) if user_id: return jsonify({ 'status': 'success', 'message': '注册成功', 'data': {'user_id': user_id} }) else: return jsonify({ 'status': 'error', 'message': '注册失败,用户名可能已存在' }), 400 except Exception as e: logger.error(f"注册失败: {e}") return jsonify({'status': 'error', 'message': '注册失败'}), 500 if __name__ == '__main__': try: # 初始化应用 init_app() # 启动服务器 logger.info("启动身体平衡评估系统后端服务器...") logger.info("服务器地址: http://localhost:5000") app.run( host='0.0.0.0', port=5000, debug=False, threaded=True ) except KeyboardInterrupt: logger.info("服务器已停止") except Exception as e: logger.error(f"服务器启动失败: {e}") sys.exit(1)