diff --git a/backend/app/services/provider.py b/backend/app/services/provider.py index 0eb82cf..52b670d 100644 --- a/backend/app/services/provider.py +++ b/backend/app/services/provider.py @@ -129,6 +129,10 @@ class ProviderService: try: # 过滤掉空值 filtered_data = {k: v for k, v in data.items() if v is not None and k != 'id'} + # 防御掩码污染:前端展示时 api_key 被 mask_key() 处理过(如 a92f****...2d3a), + # 如果用户未重新输入直接保存,带星号的值不应覆盖原 key。 + if 'api_key' in filtered_data and '*' in str(filtered_data.get('api_key', '')): + filtered_data.pop('api_key') print('更新模型供应商',filtered_data) update_provider(id, **filtered_data) # 获取更新后的供应商信息 diff --git a/backend/ffmpeg_helper.py b/backend/ffmpeg_helper.py index 5653195..1254ee6 100644 --- a/backend/ffmpeg_helper.py +++ b/backend/ffmpeg_helper.py @@ -1,11 +1,41 @@ import os import subprocess +import sys from dotenv import load_dotenv from app.utils.logger import get_logger logger = get_logger(__name__) -load_dotenv() + +def _load_dotenv_from_multiple_paths(): + """尝试多个位置加载 .env,适配源码运行和 PyInstaller 打包场景。 + + PyInstaller 打包后当前工作目录是 EXE 所在目录,而源码运行时 .env + 通常在项目根目录或 backend/ 同级。遍历常见候选路径确保能命中。 + """ + candidates = [] + # 1. 当前工作目录(EXE 所在目录) + candidates.append(os.path.join(os.getcwd(), '.env')) + # 2. 本脚本所在目录(backend/) + script_dir = os.path.dirname(os.path.abspath(__file__)) + candidates.append(os.path.join(script_dir, '.env')) + # 3. 项目根目录(backend/../.env) + candidates.append(os.path.join(script_dir, '..', '.env')) + # 4. PyInstaller 打包后的 _internal/ 子目录 + if getattr(sys, 'frozen', False): + exe_dir = os.path.dirname(sys.executable) + candidates.append(os.path.join(exe_dir, '_internal', '.env')) + + for path in candidates: + normalized = os.path.normpath(path) + if os.path.isfile(normalized): + load_dotenv(normalized) + return + # 都没找到,fallback 到默认行为(从 CWD 找) + load_dotenv() + + +_load_dotenv_from_multiple_paths() def check_ffmpeg_exists() -> bool: """ 检查 ffmpeg 是否可用。优先使用 FFMPEG_BIN_PATH 环境变量指定的路径。