Files
tyapi-server/internal/shared/pdf/pdf_debug_tool.go
2025-12-03 12:02:47 +08:00

266 lines
7.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package pdf
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"time"
"tyapi-server/internal/domains/product/entities"
"go.uber.org/zap"
)
// PDFDebugTool PDF调试工具 - 用于输出转换前后的文档
type PDFDebugTool struct {
logger *zap.Logger
pdfGenerator *PDFGenerator
markdownConverter *MarkdownConverter
textProcessor *TextProcessor
outputDir string
}
// NewPDFDebugTool 创建PDF调试工具
func NewPDFDebugTool(logger *zap.Logger, outputDir string) *PDFDebugTool {
if outputDir == "" {
outputDir = "./pdf_debug_output"
}
textProcessor := NewTextProcessor()
markdownConverter := NewMarkdownConverter(textProcessor)
pdfGenerator := NewPDFGenerator(logger)
return &PDFDebugTool{
logger: logger,
pdfGenerator: pdfGenerator,
markdownConverter: markdownConverter,
textProcessor: textProcessor,
outputDir: outputDir,
}
}
// GenerateDebugDocuments 生成调试文档转换前的markdown和转换后的PDF
func (tool *PDFDebugTool) GenerateDebugDocuments(
ctx context.Context,
productID string,
productName, productCode, description, content string,
price float64,
doc *entities.ProductDocumentation,
) error {
// 创建输出目录
if err := os.MkdirAll(tool.outputDir, 0755); err != nil {
return fmt.Errorf("创建输出目录失败: %w", err)
}
timestamp := time.Now().Format("20060102_150405")
baseName := fmt.Sprintf("%s_%s", productID, timestamp)
// 1. 保存转换前的markdown数据
if err := tool.saveOriginalMarkdown(baseName, doc); err != nil {
tool.logger.Error("保存原始markdown失败", zap.Error(err))
return fmt.Errorf("保存原始markdown失败: %w", err)
}
// 2. 保存转换后的markdown数据预处理后
if err := tool.saveProcessedMarkdown(baseName, doc); err != nil {
tool.logger.Error("保存处理后的markdown失败", zap.Error(err))
return fmt.Errorf("保存处理后的markdown失败: %w", err)
}
// 3. 生成PDF文件
pdfBytes, err := tool.pdfGenerator.GenerateProductPDF(
ctx,
productID,
productName,
productCode,
description,
content,
price,
doc,
)
if err != nil {
tool.logger.Error("生成PDF失败", zap.Error(err))
return fmt.Errorf("生成PDF失败: %w", err)
}
// 4. 保存PDF文件
pdfPath := filepath.Join(tool.outputDir, fmt.Sprintf("%s.pdf", baseName))
if err := os.WriteFile(pdfPath, pdfBytes, 0644); err != nil {
tool.logger.Error("保存PDF文件失败", zap.Error(err))
return fmt.Errorf("保存PDF文件失败: %w", err)
}
tool.logger.Info("调试文档生成成功",
zap.String("product_id", productID),
zap.String("output_dir", tool.outputDir),
zap.String("base_name", baseName),
zap.Int("pdf_size", len(pdfBytes)),
)
return nil
}
// saveOriginalMarkdown 保存原始markdown数据
func (tool *PDFDebugTool) saveOriginalMarkdown(baseName string, doc *entities.ProductDocumentation) error {
if doc == nil {
return nil
}
var content strings.Builder
content.WriteString("# 原始Markdown数据\n\n")
content.WriteString(fmt.Sprintf("生成时间: %s\n\n", time.Now().Format("2006-01-02 15:04:05")))
content.WriteString("---\n\n")
// 请求URL
if doc.RequestURL != "" {
content.WriteString("## 请求URL\n\n")
content.WriteString(fmt.Sprintf("```\n%s\n```\n\n", doc.RequestURL))
}
// 请求方法
if doc.RequestMethod != "" {
content.WriteString("## 请求方法\n\n")
content.WriteString(fmt.Sprintf("%s\n\n", doc.RequestMethod))
}
// 基本信息
if doc.BasicInfo != "" {
content.WriteString("## 基本信息\n\n")
content.WriteString(doc.BasicInfo)
content.WriteString("\n\n")
}
// 请求参数
if doc.RequestParams != "" {
content.WriteString("## 请求参数(原始)\n\n")
content.WriteString("```markdown\n")
content.WriteString(doc.RequestParams)
content.WriteString("\n```\n\n")
}
// 响应示例
if doc.ResponseExample != "" {
content.WriteString("## 响应示例(原始)\n\n")
content.WriteString("```markdown\n")
content.WriteString(doc.ResponseExample)
content.WriteString("\n```\n\n")
}
// 返回字段
if doc.ResponseFields != "" {
content.WriteString("## 返回字段(原始)\n\n")
content.WriteString("```markdown\n")
content.WriteString(doc.ResponseFields)
content.WriteString("\n```\n\n")
}
// 错误代码
if doc.ErrorCodes != "" {
content.WriteString("## 错误代码(原始)\n\n")
content.WriteString("```markdown\n")
content.WriteString(doc.ErrorCodes)
content.WriteString("\n```\n\n")
}
// 保存文件
filePath := filepath.Join(tool.outputDir, fmt.Sprintf("%s_original.md", baseName))
return os.WriteFile(filePath, []byte(content.String()), 0644)
}
// saveProcessedMarkdown 保存处理后的markdown数据
func (tool *PDFDebugTool) saveProcessedMarkdown(baseName string, doc *entities.ProductDocumentation) error {
if doc == nil {
return nil
}
var content strings.Builder
content.WriteString("# 转换后的Markdown数据\n\n")
content.WriteString(fmt.Sprintf("生成时间: %s\n\n", time.Now().Format("2006-01-02 15:04:05")))
content.WriteString("---\n\n")
// 请求URL
if doc.RequestURL != "" {
content.WriteString("## 请求URL\n\n")
content.WriteString(fmt.Sprintf("```\n%s\n```\n\n", doc.RequestURL))
}
// 请求方法
if doc.RequestMethod != "" {
content.WriteString("## 请求方法\n\n")
content.WriteString(fmt.Sprintf("%s\n\n", doc.RequestMethod))
}
// 基本信息
if doc.BasicInfo != "" {
content.WriteString("## 基本信息\n\n")
processedBasicInfo := tool.markdownConverter.PreprocessContent(doc.BasicInfo)
content.WriteString(processedBasicInfo)
content.WriteString("\n\n")
}
// 请求参数(转换后)
if doc.RequestParams != "" {
content.WriteString("## 请求参数(转换后)\n\n")
processedParams := tool.markdownConverter.PreprocessContent(doc.RequestParams)
content.WriteString("```markdown\n")
content.WriteString(processedParams)
content.WriteString("\n```\n\n")
}
// 响应示例(转换后)
if doc.ResponseExample != "" {
content.WriteString("## 响应示例(转换后)\n\n")
processedExample := tool.markdownConverter.PreprocessContent(doc.ResponseExample)
content.WriteString("```markdown\n")
content.WriteString(processedExample)
content.WriteString("\n```\n\n")
}
// 返回字段(转换后)
if doc.ResponseFields != "" {
content.WriteString("## 返回字段(转换后)\n\n")
processedFields := tool.markdownConverter.PreprocessContent(doc.ResponseFields)
content.WriteString("```markdown\n")
content.WriteString(processedFields)
content.WriteString("\n```\n\n")
}
// 错误代码(转换后)
if doc.ErrorCodes != "" {
content.WriteString("## 错误代码(转换后)\n\n")
processedErrorCodes := tool.markdownConverter.PreprocessContent(doc.ErrorCodes)
content.WriteString("```markdown\n")
content.WriteString(processedErrorCodes)
content.WriteString("\n```\n\n")
}
// 保存文件
filePath := filepath.Join(tool.outputDir, fmt.Sprintf("%s_processed.md", baseName))
return os.WriteFile(filePath, []byte(content.String()), 0644)
}
// GenerateDebugDocumentsFromEntity 从实体生成调试文档
func (tool *PDFDebugTool) GenerateDebugDocumentsFromEntity(
ctx context.Context,
product *entities.Product,
doc *entities.ProductDocumentation,
) error {
var price float64
if !product.Price.IsZero() {
price, _ = product.Price.Float64()
}
return tool.GenerateDebugDocuments(
ctx,
product.ID,
product.Name,
product.Code,
product.Description,
product.Content,
price,
doc,
)
}