BodyBalanceEvaluation/backend/app_minimal.py

242 lines
7.2 KiB
Python
Raw Normal View History

2025-08-13 14:17:50 +08:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
平衡体态检测系统 - 后端服务最小版本
基于Flask的本地API服务暂时移除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
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=['http://localhost:3000', 'http://127.0.0.1:3000', 'http://192.168.1.58:3000'])
# 全局变量
db_manager = None
device_manager = None
socketio = None # 暂时禁用SocketIO
def init_app():
"""初始化应用"""
global db_manager, device_manager
try:
# 创建必要的目录
os.makedirs('logs', exist_ok=True)
os.makedirs('data', exist_ok=True)
# 从配置文件读取数据库路径
db_path_config = app_config.get('DATABASE', 'path', 'data/body_balance.db')
# 对于打包后的exe确保数据库路径基于exe所在目录
if getattr(sys, 'frozen', False):
# 如果是打包后的exe使用exe所在目录
exe_dir = os.path.dirname(sys.executable)
if not os.path.isabs(db_path_config):
db_path = os.path.join(exe_dir, db_path_config)
else:
db_path = db_path_config
else:
# 如果是开发环境,使用脚本所在目录
if not os.path.isabs(db_path_config):
current_dir = os.path.dirname(os.path.abspath(__file__))
if db_path_config.startswith('backend/'):
db_path_config = db_path_config[8:] # 去掉 'backend/' 前缀
db_path = os.path.join(current_dir, db_path_config)
else:
db_path = db_path_config
# 确保数据库目录存在
db_dir = os.path.dirname(db_path)
os.makedirs(db_dir, exist_ok=True)
# 打印数据库路径信息用于调试
logger.info(f'数据库配置路径: {db_path_config}')
logger.info(f'数据库实际路径: {db_path}')
logger.info(f'数据库目录: {db_dir}')
logger.info(f'当前工作目录: {os.getcwd()}')
# 初始化数据库
db_manager = DatabaseManager(db_path)
db_manager.init_database()
# 初始化设备管理器不使用SocketIO
device_manager = DeviceManager(db_manager)
logger.info('应用初始化完成最小版本无SocketIO')
except Exception as e:
logger.error(f'应用初始化失败: {e}')
logger.warning('部分功能可能不可用,但服务将继续运行')
# ==================== 基础API ====================
@app.route('/health', methods=['GET'])
def health_check():
"""健康检查"""
return jsonify({
'status': 'ok',
'timestamp': datetime.now().isoformat(),
'version': '1.0.0-minimal',
'socketio_enabled': False
})
@app.route('/api/health', methods=['GET'])
def api_health_check():
"""API健康检查"""
return jsonify({
'status': 'ok',
'timestamp': datetime.now().isoformat(),
'version': '1.0.0-minimal',
'socketio_enabled': False
})
@app.route('/api/test', methods=['GET'])
def test_endpoint():
"""测试端点"""
return jsonify({
'message': 'Backend is running!',
'timestamp': datetime.now().isoformat(),
'database_status': 'connected' if db_manager else 'not_connected',
'device_manager_status': 'initialized' if device_manager else 'not_initialized'
})
# ==================== 认证API ====================
@app.route('/api/auth/login', methods=['POST'])
def login():
"""用户登录"""
try:
data = flask_request.get_json()
username = data.get('username')
password = data.get('password')
remember = data.get('remember', False)
if not username or not password:
return jsonify({
'success': False,
'message': '用户名或密码不能为空'
}), 400
# 简单的测试登录逻辑
if username == 'admin' and password == 'admin':
# 生成token实际项目中应使用JWT等安全token
token = f"token_{username}_{int(time.time())}"
return jsonify({
'success': True,
'message': '登录成功',
'data': {
'token': token,
'user': {
'id': 1,
'username': username,
'role': 'admin'
}
}
})
else:
return jsonify({
'success': False,
'message': '用户名或密码错误'
}), 401
except Exception as e:
logger.error(f'登录失败: {e}')
return jsonify({
'success': False,
'message': '登录过程中发生错误'
}), 500
@app.route('/api/auth/logout', methods=['POST'])
def logout():
"""用户登出"""
return jsonify({
'success': True,
'message': '登出成功'
})
# ==================== 设备API ====================
@app.route('/api/devices/status', methods=['GET'])
def get_device_status():
"""获取设备状态"""
try:
if device_manager:
status = {
'cameras': device_manager.get_camera_status(),
'sensors': device_manager.get_sensor_status()
}
else:
status = {
'cameras': {},
'sensors': {},
'error': '设备管理器未初始化'
}
return jsonify({
'success': True,
'data': status
})
except Exception as e:
logger.error(f'获取设备状态失败: {e}')
return jsonify({
'success': False,
'message': f'获取设备状态失败: {str(e)}'
}), 500
# ==================== 错误处理 ====================
@app.errorhandler(404)
def not_found(error):
return jsonify({
'success': False,
'message': '接口不存在'
}), 404
@app.errorhandler(500)
def internal_error(error):
return jsonify({
'success': False,
'message': '服务器内部错误'
}), 500
if __name__ == '__main__':
init_app()
app.run(host='0.0.0.0', port=5000, debug=True)