fix:修复一些BUG

This commit is contained in:
2025-12-13 19:44:27 +08:00
parent 9d347f9bc9
commit 93d1e8687a
18 changed files with 584 additions and 638 deletions

View File

@@ -12,30 +12,46 @@ except ImportError:
sys.exit(1)
def get_main_path():
def get_base_dir():
"""
获取程序运行的根目录
兼容:
1. PyInstaller 打包后的 .exe 环境
2. 开发环境 (假设此脚本在子文件夹中,如 utils/)
获取程序运行的基准目录 (即 EXE 所在的目录 或 开发环境的项目根目录)
用于确定 output_folder 等需要写入的路径。
"""
if getattr(sys, "frozen", False):
# --- 情况 A: 打包后的 exe ---
# exe 就在根目录下,直接取 exe 所在目录
if getattr(sys, 'frozen', False):
# 打包环境: EXE 所在目录
return os.path.dirname(sys.executable)
else:
# --- 情况 B: 开发环境 (.py) ---
# 1. 获取当前脚本的绝对路径 (例如: .../MyProject/utils/config_loader.py)
current_file_path = os.path.abspath(__file__)
# 开发环境: 项目根目录 (假设此脚本在 utils/ 文件夹中,需要向上两级)
return os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 2. 获取当前脚本所在的文件夹 (例如: .../MyProject/utils)
current_dir = os.path.dirname(current_file_path)
# 3. 【关键修改】再往上一层,获取项目根目录 (例如: .../MyProject)
# 如果你的脚本藏得更深,就再套一层 os.path.dirname
project_root = os.path.dirname(current_dir)
def get_resource_path(relative_path):
"""
智能路径获取:
1. 优先检查 EXE 旁边是否有该文件 (外部资源)。
2. 如果没有,则使用 EXE 内部打包的资源 (内部资源)。
"""
# 1. 获取外部基准路径
base_path = get_base_dir()
return project_root
# 拼接外部路径
external_path = os.path.join(base_path, relative_path)
# 如果外部文件存在,直接返回 (优先使用用户修改过的文件)
if os.path.exists(external_path):
return external_path
# 2. 如果外部不存在,且处于打包环境,则回退到内部临时目录 (sys._MEIPASS)
if getattr(sys, 'frozen', False):
# sys._MEIPASS 是 PyInstaller 解压临时文件的目录
internal_path = os.path.join(sys._MEIPASS, relative_path)
if os.path.exists(internal_path):
return internal_path
# 3. 默认返回外部路径
# (如果都没找到,让报错信息指向外部路径,提示用户文件缺失)
return external_path
# ==========================================
@@ -44,32 +60,58 @@ def get_main_path():
def load_config(config_filename="config.toml"):
"""读取 TOML 配置文件"""
# 1. 先获取正确的根目录
main_dir = get_main_path()
# 2. 拼接配置文件的绝对路径 (防止在不同目录下运行脚本时找不到配置文件)
config_path = os.path.join(main_dir, config_filename)
# 1. 智能获取配置文件路径
# (优先找 EXE 旁边的 config.toml找不到则用打包在里面的)
config_path = get_resource_path(config_filename)
if not os.path.exists(config_path):
print(f"错误: 在路径 {main_dir}找不到配置文件 {config_filename}")
print(f"尝试寻找的完整路径是: {config_path}")
print(f"错误: 找不到配置文件 {config_filename}")
print(f"尝试寻找的路径是: {config_path}")
# 如果是打包环境,提示用户可能需要把 config.toml 复制出来
if getattr(sys, 'frozen', False):
print("提示: 请确保 config.toml 位于程序同级目录下,或已正确打包。")
sys.exit(1)
try:
with open(config_path, "rb") as f:
data = toml.load(f)
# 获取基准目录(用于 output_folder
base_dir = get_base_dir()
# 将 TOML 的层级结构映射回扁平结构
# 关键点:所有的 os.path.join 都必须基于 main_dir (项目根目录)
# ⚠️ 注意:
# - 读取类文件 (模板, Excel, 图片, 字体) 使用 get_resource_path (支持内外回退)
# - 写入类文件夹 (output_folder) 使用 os.path.join(base_dir, ...) (必须在外部)
config = {
"root_path": main_dir, # 方便调试,把根目录也存进去
"source_file": os.path.join(
main_dir, "templates", data["paths"]["source_file"]
"root_path": base_dir,
# --- 资源文件 (使用智能路径) ---
# 假设 config.toml 里写的是 "report_template.pptx",文件在 templates 文件夹下
"source_file": get_resource_path(
os.path.join("templates", data["paths"]["source_file"])
),
"output_folder": os.path.join(main_dir, data["paths"]["output_folder"]),
"excel_file": os.path.join(main_dir, data["paths"]["excel_file"]),
"image_folder": os.path.join(main_dir, data["paths"]["image_folder"]),
"fonts_dir": os.path.join(main_dir, data["paths"]["fonts_dir"]),
# 假设 config.toml 里写的是 "names.xlsx",文件在 data 文件夹下
# 如果 config.toml 里写的是 "data/names.xlsx",则不需要 os.path.join("data", ...)
"excel_file": get_resource_path(
os.path.join("data", data["paths"]["excel_file"])
),
"image_folder": get_resource_path(
os.path.join("data", data["paths"]["image_folder"])
),
"fonts_dir": get_resource_path(
os.path.join(data["paths"]["fonts_dir"])
),
# --- 输出文件夹 (必须强制在外部,不能指向临时目录) ---
"output_folder": os.path.join(base_dir, data["paths"]["output_folder"]),
# --- 其他配置 ---
"class_name": data["class_info"]["class_name"],
"teachers": data["class_info"]["teachers"],
"default_comment": data["defaults"].get("default_comment", "暂无评语"),
@@ -77,6 +119,12 @@ def load_config(config_filename="config.toml"):
"ai": data["ai"],
}
return config
except KeyError as e:
print(f"配置文件格式错误,缺少键值: {e}")
sys.exit(1)
except Exception as e:
print(f"读取配置文件出错: {e}")
import traceback
traceback.print_exc()
sys.exit(1)