@@ -356,6 +356,17 @@ def _build_ui(self) -> None:
356356 bg_form .addRow ("透明度:" , bg_op_row )
357357 self ._add_collapsible (root , "settings_background" , "背景图" , bg_box , "设置主控台背景图片" )
358358
359+ # --- 日志 ---
360+ log_box = QGroupBox ("日志" )
361+ log_layout = QVBoxLayout (log_box )
362+ log_layout .addWidget (QLabel ("导出全部日志,便于反馈排查。" ))
363+ self .btn_export_log = QPushButton ("📦 导出日志" )
364+ log_row = QHBoxLayout ()
365+ log_row .addWidget (self .btn_export_log )
366+ log_row .addStretch ()
367+ log_layout .addLayout (log_row )
368+ self ._add_collapsible (root , "settings_log" , "日志" , log_box , "导出运行时日志" )
369+
359370 root .addStretch ()
360371
361372 # 日志
@@ -374,6 +385,7 @@ def _build_ui(self) -> None:
374385 self .btn_preview .clicked .connect (self ._preview_window )
375386 self .btn_save_win .clicked .connect (self ._save_window )
376387 self .btn_token_eye .clicked .connect (self ._toggle_token_visible )
388+ self .btn_export_log .clicked .connect (self ._on_export_log )
377389
378390 self ._windows : list = [] # DesktopWindow 列表(与 list_windows 行对应)
379391 self ._preview_thread : QThread | None = None
@@ -513,6 +525,39 @@ def _toggle_token_visible(self) -> None:
513525 self .edit_github_token .setEchoMode (QLineEdit .EchoMode .Password )
514526 self .btn_token_eye .setText ("👁" )
515527
528+ def _on_export_log (self ) -> None :
529+ """导出 debug/ 全部日志为 zip:弹保存对话框 → 打包 → 打开所在文件夹。"""
530+ from datetime import datetime
531+
532+ from aao .utils .logger import export_logs
533+
534+ default_name = f"aao-logs-{ datetime .now ().strftime ('%Y%m%d-%H%M%S' )} .zip"
535+ dest , _ = QFileDialog .getSaveFileName (self , "导出日志" , default_name , "ZIP 压缩包 (*.zip)" )
536+ if not dest :
537+ return
538+ try :
539+ n = export_logs (Path (dest ))
540+ except Exception as e : # noqa: BLE001
541+ logger .exception ("导出日志失败" )
542+ QMessageBox .warning (self , "导出失败" , f"导出日志失败:{ e } " )
543+ return
544+ if n == 0 :
545+ self .lbl_op .setText ("无日志可导出(debug/ 不存在)" )
546+ return
547+ self .lbl_op .setText (f"已导出 { n } 个日志文件到 { dest } " )
548+ # 打开所在文件夹并选中(Windows explorer /select)
549+ from aao .utils .runtime_paths import is_frozen
550+
551+ if is_frozen ():
552+ import subprocess
553+
554+ subprocess .Popen (["explorer" , "/select," , str (Path (dest ).resolve ())])
555+ else :
556+ from PySide6 .QtCore import QUrl
557+ from PySide6 .QtGui import QDesktopServices
558+
559+ QDesktopServices .openUrl (QUrl .fromLocalFile (str (Path (dest ).parent )))
560+
516561 def _on_theme_changed (self , idx : int ) -> None :
517562 """主题下拉切换:即时应用 + 持久化(纯 UI 偏好,无需重启或点保存按钮)。"""
518563 mode = theme .MODES [idx ]
0 commit comments