Files
tyapi-server/internal/infrastructure/external/pdfgen/pdfgen_service.go
2026-01-27 16:26:48 +08:00

155 lines
3.6 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 pdfgen
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
"tyapi-server/internal/config"
"go.uber.org/zap"
)
// PDFGenService PDF生成服务客户端
type PDFGenService struct {
baseURL string
apiPath string
logger *zap.Logger
client *http.Client
}
// NewPDFGenService 创建PDF生成服务客户端
func NewPDFGenService(cfg *config.Config, logger *zap.Logger) *PDFGenService {
// 根据环境选择服务地址
var baseURL string
if cfg.App.IsProduction() {
baseURL = cfg.PDFGen.ProductionURL
} else {
baseURL = cfg.PDFGen.DevelopmentURL
}
// 如果配置为空,使用默认值
if baseURL == "" {
if cfg.App.IsProduction() {
baseURL = "http://localhost:15990"
} else {
baseURL = "http://1.117.67.95:15990"
}
}
// 获取API路径如果为空使用默认值
apiPath := cfg.PDFGen.APIPath
if apiPath == "" {
apiPath = "/api/v1/generate/guangzhou"
}
// 获取超时时间如果为0使用默认值
timeout := cfg.PDFGen.Timeout
if timeout == 0 {
timeout = 120 * time.Second
}
logger.Info("PDF生成服务已初始化",
zap.String("base_url", baseURL),
zap.String("api_path", apiPath),
zap.Duration("timeout", timeout),
)
return &PDFGenService{
baseURL: baseURL,
apiPath: apiPath,
logger: logger,
client: &http.Client{
Timeout: timeout,
},
}
}
// GeneratePDFRequest PDF生成请求
type GeneratePDFRequest struct {
Data []map[string]interface{} `json:"data"`
ReportNumber string `json:"report_number,omitempty"`
GenerateTime string `json:"generate_time,omitempty"`
}
// GeneratePDFResponse PDF生成响应
type GeneratePDFResponse struct {
PDFBytes []byte
FileName string
}
// GenerateGuangzhouPDF 生成广州大数据租赁风险PDF报告
func (s *PDFGenService) GenerateGuangzhouPDF(ctx context.Context, req *GeneratePDFRequest) (*GeneratePDFResponse, error) {
// 构建请求体
reqBody, err := json.Marshal(req)
if err != nil {
return nil, fmt.Errorf("序列化请求失败: %w", err)
}
// 构建请求URL
url := fmt.Sprintf("%s%s", s.baseURL, s.apiPath)
// 创建HTTP请求
httpReq, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(reqBody))
if err != nil {
return nil, fmt.Errorf("创建请求失败: %w", err)
}
// 设置请求头
httpReq.Header.Set("Content-Type", "application/json")
// 发送请求
s.logger.Info("开始调用PDF生成服务",
zap.String("url", url),
zap.Int("data_count", len(req.Data)),
)
resp, err := s.client.Do(httpReq)
if err != nil {
s.logger.Error("调用PDF生成服务失败",
zap.String("url", url),
zap.Error(err),
)
return nil, fmt.Errorf("调用PDF生成服务失败: %w", err)
}
defer resp.Body.Close()
// 检查HTTP状态码
if resp.StatusCode != http.StatusOK {
// 尝试读取错误信息
errorBody, _ := io.ReadAll(resp.Body)
s.logger.Error("PDF生成服务返回错误",
zap.Int("status_code", resp.StatusCode),
zap.String("error_body", string(errorBody)),
)
return nil, fmt.Errorf("PDF生成失败状态码: %d, 错误: %s", resp.StatusCode, string(errorBody))
}
// 读取PDF文件
pdfBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("读取PDF文件失败: %w", err)
}
// 生成文件名
fileName := "大数据租赁风险报告.pdf"
if req.ReportNumber != "" {
fileName = fmt.Sprintf("%s.pdf", req.ReportNumber)
}
s.logger.Info("PDF生成成功",
zap.String("file_name", fileName),
zap.Int("file_size", len(pdfBytes)),
)
return &GeneratePDFResponse{
PDFBytes: pdfBytes,
FileName: fileName,
}, nil
}