修复: Markdown导出file URL转义并加导出诊断插桩
- Markdown通道file URL整体转义,中文空格临时路径可导航 - bindings同步删除已清理的目录选择死代码 - 导出PDF链路插桩日志落.pdf-export.log,临时诊断定位后移除
This commit is contained in:
@@ -559,13 +559,6 @@ export function SaveConnectionProfile(req: $models.SaveProfileRequest): $Cancell
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* SelectPDFSaveDirectory 选择PDF保存目录
|
|
||||||
*/
|
|
||||||
export function SelectPDFSaveDirectory(): $CancellablePromise<string> {
|
|
||||||
return $Call.ByID(1403263131);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SetMainWindow 设置主窗口引用(由 main.go 在创建窗口后调用)
|
* SetMainWindow 设置主窗口引用(由 main.go 在创建窗口后调用)
|
||||||
*/
|
*/
|
||||||
|
|||||||
+48
-7
@@ -308,10 +308,11 @@ func (api *PdfAPI) generatePDFFromHTML(htmlContent string, pageWidth, pageHeight
|
|||||||
|
|
||||||
var buf []byte
|
var buf []byte
|
||||||
|
|
||||||
// 使用 file URL 加载本地HTML文件
|
// file URL 需整体转义,与 generatePDFFromLocalFile 同姿势,中文/空格临时路径才能正确导航
|
||||||
|
fileURL := (&url.URL{Scheme: "file", Path: filepath.ToSlash(htmlFile)}).String()
|
||||||
|
|
||||||
err = chromedp.Run(chromeCtx,
|
err = chromedp.Run(chromeCtx,
|
||||||
// 导航到HTML文件
|
chromedp.Navigate(fileURL),
|
||||||
chromedp.Navigate("file://"+htmlFile),
|
|
||||||
// 等待页面加载完成
|
// 等待页面加载完成
|
||||||
chromedp.WaitReady("body"),
|
chromedp.WaitReady("body"),
|
||||||
// 打印到PDF
|
// 打印到PDF
|
||||||
@@ -377,13 +378,42 @@ func findChromeExecutable() (string, error) {
|
|||||||
return "", fmt.Errorf("未找到 Chrome 或 Edge 浏览器,导出 PDF 需要安装其一")
|
return "", fmt.Errorf("未找到 Chrome 或 Edge 浏览器,导出 PDF 需要安装其一")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// appendExportLog 追加一行PDF导出诊断日志到 %USERPROFILE%\.u-desk\logs\pdf-export.log
|
||||||
|
// 临时诊断插桩:用户反馈导出转圈即停且错误无处可查,用于收口记录导出链路每个返回点,定位后整体移除
|
||||||
|
// 写日志自身失败静默,不向导出主链路传播错误
|
||||||
|
func appendExportLog(msg string) {
|
||||||
|
home := os.Getenv("USERPROFILE")
|
||||||
|
if home == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f, err := os.OpenFile(filepath.Join(home, ".u-desk", "logs", "pdf-export.log"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
fmt.Fprintf(f, "%s %s\n", time.Now().Format("2006-01-02 15:04:05"), msg)
|
||||||
|
}
|
||||||
|
|
||||||
// ExportHtmlFileToPDF 将本地HTML文件加载渲染后导出为PDF
|
// ExportHtmlFileToPDF 将本地HTML文件加载渲染后导出为PDF
|
||||||
func (api *PdfAPI) ExportHtmlFileToPDF(srcPath string, saveName string) (*PdfExportResponse, error) {
|
func (api *PdfAPI) ExportHtmlFileToPDF(srcPath string, saveName string) (resp *PdfExportResponse, err error) {
|
||||||
|
// 临时诊断插桩:defer 收口记录每个 error 返回点与最终成功结果
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
appendExportLog(fmt.Sprintf("ExportHtmlFileToPDF error=%s", err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if resp != nil {
|
||||||
|
appendExportLog(fmt.Sprintf("ExportHtmlFileToPDF ok path=%s size=%d", resp.Path, resp.Size))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
appendExportLog(fmt.Sprintf("ExportHtmlFileToPDF entry srcPath=%q saveName=%q", srcPath, saveName))
|
||||||
|
|
||||||
// 只接受实际存在的 html 文件,避免把任意路径交给 Chrome 渲染
|
// 只接受实际存在的 html 文件,避免把任意路径交给 Chrome 渲染
|
||||||
info, err := os.Stat(srcPath)
|
info, err := os.Stat(srcPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("HTML文件不存在: %s", srcPath)
|
return nil, fmt.Errorf("HTML文件不存在: %s", srcPath)
|
||||||
}
|
}
|
||||||
|
appendExportLog(fmt.Sprintf("ExportHtmlFileToPDF stat ok size=%d isDir=%v", info.Size(), info.IsDir()))
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
return nil, fmt.Errorf("目标路径是目录,不是HTML文件: %s", srcPath)
|
return nil, fmt.Errorf("目标路径是目录,不是HTML文件: %s", srcPath)
|
||||||
}
|
}
|
||||||
@@ -430,11 +460,24 @@ func (api *PdfAPI) ExportHtmlFileToPDF(srcPath string, saveName string) (*PdfExp
|
|||||||
}
|
}
|
||||||
|
|
||||||
// generatePDFFromLocalFile 用 headless Chrome 加载本地HTML文件并打印为PDF
|
// generatePDFFromLocalFile 用 headless Chrome 加载本地HTML文件并打印为PDF
|
||||||
func (api *PdfAPI) generatePDFFromLocalFile(srcPath string) ([]byte, error) {
|
func (api *PdfAPI) generatePDFFromLocalFile(srcPath string) (buf []byte, err error) {
|
||||||
|
start := time.Now()
|
||||||
|
appendExportLog(fmt.Sprintf("generatePDFFromLocalFile start srcPath=%q", srcPath))
|
||||||
|
// 临时诊断插桩:defer 收口记录结束耗时与结果
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
appendExportLog(fmt.Sprintf("generatePDFFromLocalFile end error=%s elapsed=%s", err.Error(), time.Since(start)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
appendExportLog(fmt.Sprintf("generatePDFFromLocalFile end ok bytes=%d elapsed=%s", len(buf), time.Since(start)))
|
||||||
|
}()
|
||||||
|
|
||||||
chromePath, err := findChromeExecutable()
|
chromePath, err := findChromeExecutable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
appendExportLog(fmt.Sprintf("generatePDFFromLocalFile findChromeExecutable error=%s", err.Error()))
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
appendExportLog(fmt.Sprintf("generatePDFFromLocalFile browser hit=%q", chromePath))
|
||||||
|
|
||||||
absPath, err := filepath.Abs(srcPath)
|
absPath, err := filepath.Abs(srcPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -464,8 +507,6 @@ func (api *PdfAPI) generatePDFFromLocalFile(srcPath string) ([]byte, error) {
|
|||||||
chromeCtx, chromeCancel := chromedp.NewContext(allocCtx)
|
chromeCtx, chromeCancel := chromedp.NewContext(allocCtx)
|
||||||
defer chromeCancel()
|
defer chromeCancel()
|
||||||
|
|
||||||
var buf []byte
|
|
||||||
|
|
||||||
err = chromedp.Run(chromeCtx,
|
err = chromedp.Run(chromeCtx,
|
||||||
chromedp.Navigate(fileURL),
|
chromedp.Navigate(fileURL),
|
||||||
// 先确保新文档的 body 可查询,后续 JS 才会落在正确文档上
|
// 先确保新文档的 body 可查询,后续 JS 才会落在正确文档上
|
||||||
|
|||||||
Reference in New Issue
Block a user