diff --git a/app_pdf.go b/app_pdf.go index 5f5e724..3da540f 100644 --- a/app_pdf.go +++ b/app_pdf.go @@ -76,13 +76,3 @@ func (a *App) ExportHtmlFileToPDF(path string, saveName string) (map[string]inte "size": result.Size, }, nil } - -// SelectPDFSaveDirectory 选择PDF保存目录 -func (a *App) SelectPDFSaveDirectory() (string, error) { - pdfAPI, err := a.requirePdfAPI() - if err != nil { - return "", err - } - - return pdfAPI.SelectDirectory() -} diff --git a/frontend/src/api/http-transport.ts b/frontend/src/api/http-transport.ts index 4bda45e..0797bbd 100644 --- a/frontend/src/api/http-transport.ts +++ b/frontend/src/api/http-transport.ts @@ -3,6 +3,7 @@ */ import type { FsTransport, FileItem, FileOperationResult, DetectTypeResult } from './transport' +import { GetEnvVars, WriteFile } from '@bindings/u-desk/app' const CONTENT_TYPE = 'application/json' @@ -156,7 +157,19 @@ export class HttpTransport implements FsTransport { async emptyRecycleBin(): Promise {} + // HTML 的 PDF 导出与本地预览都依赖本地真实文件(导出在后端 os.Stat,预览走本地文件服务器), + // 因此把远端 HTML 文本拉到本机临时目录;其余类型保持返回原路径走 fs-agent 代理流式预览, + // 二进制内容若也走 read 接口会被当文本损坏 async downloadForPreview(path: string): Promise { - return path + if (!/\.html?$/i.test(path)) return path + const content = await this.readFile(path) + const env = await GetEnvVars() + const tempDir = env['TEMP'] || env['TMP'] || env['TMPDIR'] || '' + if (!tempDir) return path + const sep = tempDir.includes('\\') ? '\\' : '/' + const base = path.split(/[\\/]/).pop() || 'preview.html' + const localPath = `${tempDir.replace(/[\\/]+$/, '')}${sep}udesk-http-${Date.now()}-${base}` + await WriteFile({ path: localPath, content }) + return localPath } } diff --git a/frontend/src/api/transport.ts b/frontend/src/api/transport.ts index db87ef3..2d34a0f 100644 --- a/frontend/src/api/transport.ts +++ b/frontend/src/api/transport.ts @@ -81,7 +81,7 @@ export interface FsTransport { emptyRecycleBin(): Promise // 预览辅助 - /** 下载远程文件到本地临时目录,本地/HTTP 直接返回原路径 */ + /** 下载远程文件到本地临时目录,本地直接返回原路径;HTTP 仅对 HTML 落本地副本,其余类型返回原路径 */ downloadForPreview(path: string): Promise /** 下载 HTML 及其引用的资源到临时目录(OSS 实现) */ downloadSiteForPreview?(path: string): Promise diff --git a/internal/api/pdf_api.go b/internal/api/pdf_api.go index 09c3567..811c6ab 100644 --- a/internal/api/pdf_api.go +++ b/internal/api/pdf_api.go @@ -73,7 +73,7 @@ func (api *PdfAPI) ExportMarkdownToPDF(req PdfExportRequest) (*PdfExportResponse htmlContent := api.markdownToHTML(req.Content, req.Title, req.FontSize) // 使用chromedp生成PDF - pdfBuffer, err := api.generatePDFFromHTML(htmlContent, req.Title, req.PageWidth, req.PageHeight) + pdfBuffer, err := api.generatePDFFromHTML(htmlContent, req.PageWidth, req.PageHeight) if err != nil { return nil, fmt.Errorf("生成PDF失败: %v", err) } @@ -264,7 +264,7 @@ func (api *PdfAPI) markdownToHTML(markdownContent string, title string, fontSize } // generatePDFFromHTML 使用chromedp从HTML生成PDF -func (api *PdfAPI) generatePDFFromHTML(htmlContent, title string, pageWidth, pageHeight int) ([]byte, error) { +func (api *PdfAPI) generatePDFFromHTML(htmlContent string, pageWidth, pageHeight int) ([]byte, error) { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() // 配置chromedp选项 @@ -338,6 +338,10 @@ func (api *PdfAPI) generatePDFFromHTML(htmlContent, title string, pageWidth, pag return nil, fmt.Errorf("chromedp执行失败: %v", err) } + if len(buf) == 0 { + return nil, fmt.Errorf("PDF生成结果为空") + } + return buf, nil } @@ -350,6 +354,8 @@ func findChromeExecutable() (string, error) { filepath.Join(os.Getenv("USERPROFILE"), "AppData", "Local", "Google", "Chrome", "Application", "chrome.exe"), `C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe`, `C:\Program Files\Microsoft\Edge\Application\msedge.exe`, + // 按用户安装的 Edge 不落在 Program Files,LOCALAPPDATA 下才有 + filepath.Join(os.Getenv("LOCALAPPDATA"), "Microsoft", "Edge", "Application", "msedge.exe"), } for _, path := range candidates { if _, err := os.Stat(path); err == nil { @@ -520,14 +526,4 @@ func (api *PdfAPI) getDesktopDirectory() string { // 备用:当前目录 return "." -} - -// SelectDirectory 选择保存目录(简化版,实际应该使用Wails runtime) -func (api *PdfAPI) SelectDirectory() (string, error) { - // 简化版:直接返回桌面目录 - desktop := api.getDesktopDirectory() - if desktop == "." { - return "", fmt.Errorf("无法确定默认目录") - } - return desktop, nil } \ No newline at end of file