diff --git a/backend/app.py b/backend/app.py index 4a928f38..ae32a17f 100644 --- a/backend/app.py +++ b/backend/app.py @@ -69,8 +69,8 @@ try: ping_interval=25, manage_session=False, always_connect=False, - transports=['polling', 'websocket'], # 优先使用polling - allow_upgrades=True, # 允许升级到websocket + transports=['polling'], # 只使用polling,避免打包环境websocket问题 + allow_upgrades=False, # 禁用升级到websocket cookie=None # 禁用cookie ) diff --git a/backend/app.spec b/backend/app.spec index 03332027..0997eb73 100644 --- a/backend/app.spec +++ b/backend/app.spec @@ -4,7 +4,7 @@ block_cipher = None a = Analysis( - ['app.py'], + ['main.py'], pathex=[], binaries=[ ('dll/femtobolt/bin/k4a.dll', 'dll/femtobolt/bin'), # K4A动态库 @@ -16,11 +16,6 @@ a = Analysis( ('dll/femtobolt/bin/OrbbecSDKConfig_v1.0.xml', 'dll/femtobolt/bin'), # Orbbec配置文件 ('dll/smitsense/SMiTSenseUsb-F3.0.dll', 'dll/smitsense'), # SMiTSense传感器库 ('dll/smitsense/SMiTSenseUsbWrapper.dll', 'dll/smitsense'), # SMiTSense传感器库包装类 ], - datas=[ - ('config.ini', '.'), # 配置文件 - ('data', 'data'), # 数据文件夹 - ('dll', 'dll'), # DLL目录结构 - ], hiddenimports=[ 'flask', 'flask_socketio', diff --git a/backend/build_app.py b/backend/build_app.py index f4c871fb..4bda99e1 100644 --- a/backend/build_app.py +++ b/backend/build_app.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ -app.py 完整版打包脚本 +main.py 完整版打包脚本 使用PyInstaller将完整版Flask应用程序(包含SocketIO)打包成独立的exe文件 """ @@ -25,14 +25,14 @@ def clean_build_dirs(): print(f"⚠️ 删除 {dir_name} 失败: {e}") def create_app_spec(): - """创建app.py的PyInstaller spec文件""" + """创建main.py的PyInstaller spec文件""" spec_content = ''' # -*- mode: python ; coding: utf-8 -*- block_cipher = None a = Analysis( - ['app.py'], + ['main.py'], pathex=[], binaries=[ ('dll/femtobolt/bin/k4a.dll', 'dll/femtobolt/bin'), # K4A动态库 @@ -44,11 +44,6 @@ a = Analysis( ('dll/femtobolt/bin/OrbbecSDKConfig_v1.0.xml', 'dll/femtobolt/bin'), # Orbbec配置文件 ('dll/smitsense/SMiTSenseUsb-F3.0.dll', 'dll/smitsense'), # SMiTSense传感器库 ('dll/smitsense/SMiTSenseUsbWrapper.dll', 'dll/smitsense'), # SMiTSense传感器库包装类 ], - datas=[ - ('config.ini', '.'), # 配置文件 - ('data', 'data'), # 数据文件夹 - ('dll', 'dll'), # DLL目录结构 - ], hiddenimports=[ 'flask', 'flask_socketio', @@ -169,59 +164,29 @@ def build_exe(): print(f"✗ 构建过程出错: {e}") return False -def create_startup_script(): - """创建启动脚本""" - startup_script = '''@echo off -echo 启动身体平衡评估系统后端服务(完整版)... -echo. -echo 服务信息: -echo - HTTP API: http://localhost:5000 -echo - SocketIO: ws://localhost:5000 -echo - 管理界面: http://localhost:5000 -echo. -echo 按Ctrl+C停止服务 -echo. -cd BodyBalanceBackend -"BodyBalanceBackend.exe" -if %errorlevel% neq 0 ( - echo. - echo 服务启动失败,请检查错误信息 - pause -) -''' - - dist_dir = 'dist' - if not os.path.exists(dist_dir): - os.makedirs(dist_dir) - - with open(os.path.join(dist_dir, 'start_backend.bat'), 'w', encoding='utf-8') as f: - f.write(startup_script) - - print("✓ 创建启动脚本: dist/start_backend.bat") def create_directories(): """创建必要的目录结构""" print("创建目录结构...") - dist_dir = 'dist' - directories = ['dll', 'data', 'logs'] + directories = [ + os.path.join('dist', 'BodyBalanceBackend', 'dll'), + os.path.join('dist', 'BodyBalanceBackend', 'data'), + os.path.join('dist', 'BodyBalanceBackend', 'logs') + ] for directory in directories: - dir_path = os.path.join(dist_dir, directory) - if not os.path.exists(dir_path): - try: - os.makedirs(dir_path) - print(f"✓ 创建目录: {directory}/") - except Exception as e: - print(f"⚠️ 创建目录 {directory} 失败: {e}") + if not os.path.exists(directory): + os.makedirs(directory) + print(f"✓ 创建目录: {os.path.relpath(directory, 'dist')}/") else: - print(f"✓ 目录已存在: {directory}/") + print(f"ℹ️ 目录已存在: {os.path.relpath(directory, 'dist')}/") def copy_dll_files(): """复制DLL文件到dll目录""" print("复制DLL文件...") - dll_dir = os.path.join('dist', 'dll') + dll_dir = os.path.join('dist', 'BodyBalanceBackend', 'dll') # 查找所有DLL文件 dll_files = [] @@ -253,10 +218,11 @@ def copy_data_files(): """准备数据库文件到data目录""" print("准备数据库文件...") - data_dir = os.path.join('dist', 'data') + # 数据库文件应该复制到可执行文件同级的data目录 + data_dir = os.path.join('dist', 'BodyBalanceBackend', 'data') # 数据库文件列表 - 这些文件会在程序首次运行时自动创建 - db_files = ['body_balance.db', 'database.db'] + db_files = ['body_balance.db'] # 检查是否存在现有数据库文件,如果存在则复制 copied_count = 0 @@ -284,7 +250,7 @@ def copy_config_files(): print("复制配置文件...") config_files = ['config.ini'] - dist_dir = 'dist' + dist_dir = os.path.join('dist', 'BodyBalanceBackend') if not os.path.exists(dist_dir): os.makedirs(dist_dir) @@ -302,13 +268,13 @@ def copy_config_files(): def main(): """主函数""" print("=" * 60) - print("身体平衡评估系统 - app.py 完整版打包工具") + print("身体平衡评估系统 - main.py 完整版打包工具") print("=" * 60) print() # 检查当前目录 - if not os.path.exists('app.py'): - print("✗ 错误: 找不到 app.py 文件") + if not os.path.exists('main.py'): + print("✗ 错误: 找不到 main.py 文件") print("请确保在backend目录下运行此脚本") input("按回车键退出...") return @@ -349,8 +315,8 @@ def main(): copy_config_files() print() - # 创建启动脚本 - create_startup_script() + + print() print("🎉 打包完成!") diff --git a/backend/main.py b/backend/main.py index 7c4d17bb..902e9407 100644 --- a/backend/main.py +++ b/backend/main.py @@ -143,10 +143,10 @@ class AppServer: engineio_logger=False, ping_timeout=60, ping_interval=25, - manage_session=False, + manage_session=True, # 启用会话管理,解决打包环境会话问题 always_connect=False, - transports=['polling', 'websocket'], # 优先使用polling - allow_upgrades=True, # 允许升级到websocket + transports=['polling'], # 只使用polling,避免打包环境websocket问题 + allow_upgrades=False, # 禁用升级到websocket cookie=None # 禁用cookie ) self.logger.info('SocketIO初始化成功') @@ -179,7 +179,14 @@ class AppServer: try: # 初始化数据库管理器 self.logger.info('正在初始化数据库管理器...') - db_path = os.path.join(os.path.dirname(__file__), 'data', 'body_balance.db') + # 在打包环境中使用可执行文件的目录,在开发环境中使用脚本文件的目录 + if getattr(sys, 'frozen', False): + # 打包环境 + base_dir = os.path.dirname(sys.executable) + else: + # 开发环境 + base_dir = os.path.dirname(__file__) + db_path = os.path.join(base_dir, 'data', 'body_balance.db') os.makedirs(os.path.dirname(db_path), exist_ok=True) self.db_manager = DatabaseManager(db_path) self.db_manager.init_database() diff --git a/frontend/src/renderer/src/views/Detection.vue b/frontend/src/renderer/src/views/Detection.vue index 7684f384..b72765c0 100644 --- a/frontend/src/renderer/src/views/Detection.vue +++ b/frontend/src/renderer/src/views/Detection.vue @@ -834,7 +834,7 @@ function connectWebSocket() { // 创建主Socket.IO连接 socket = io(BACKEND_URL, { - transports: ['websocket', 'polling'], + transports: ['polling'], // 只使用polling,与后端保持一致 timeout: 10000, forceNew: true, reconnection: true, @@ -844,7 +844,7 @@ function connectWebSocket() { // 创建统一设备命名空间连接 devicesSocket = io(BACKEND_URL + '/devices', { - transports: ['websocket', 'polling'], + transports: ['polling'], // 只使用polling,与后端保持一致 timeout: 10000, forceNew: true })