From 4425239717a609ebdd1cbc3888074691eadfd8a8 Mon Sep 17 00:00:00 2001 From: techotaku39 Date: Sat, 23 May 2026 22:47:28 +0800 Subject: [PATCH] =?UTF-8?q?fix(backend):=20=E9=98=B2=E5=BE=A1=20API=20Key?= =?UTF-8?q?=20=E6=8E=A9=E7=A0=81=E6=B1=A1=E6=9F=93=E5=B9=B6=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=20EXE=20=E7=89=88=20.env=20=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - provider.py: 更新供应商时,若 api_key 包含 '*'(掩码字符), 跳过该字段,防止前端展示用的 mask_key() 值被误写入数据库。 - ffmpeg_helper.py: load_dotenv() 默认只从 CWD 查找 .env, PyInstaller 打包后 CWD 为 EXE 目录,导致 _internal/.env 被忽略。 改为遍历多个候选路径(CWD、脚本目录、项目根目录、_internal/), 确保源码和打包两种场景都能正确加载环境变量。 --- backend/app/services/provider.py | 4 ++++ backend/ffmpeg_helper.py | 32 +++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) 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 环境变量指定的路径。