This commit is contained in:
Mrx
2026-06-09 16:20:44 +08:00
parent e7d462028e
commit 209f9630ad
6 changed files with 101 additions and 3 deletions

View File

@@ -16,6 +16,8 @@ import (
"io"
"mime/multipart"
"net/http"
"os"
"path/filepath"
"sort"
"strconv"
"strings"
@@ -38,6 +40,8 @@ const (
headerOrderCode = "X-ORDER-CODE"
headerSecretIDHdr = "secretId"
headerAESKeyHdr = "aesKey"
defaultAuthPDFStorageDir = "storage/huibo-auth-pdf"
)
// 汇博常见状态码
@@ -362,6 +366,66 @@ func decodeAndValidatePDF(base64PDF string) ([]byte, error) {
return raw, nil
}
// SaveAuthPDFLocally 解码校验后将授权 PDF 留存到本地CallAPI2 等 JSON 接口仅留存,不上传汇博)
func (s *HuiboService) SaveAuthPDFLocally(ctx context.Context, apiCode, authPDFBase64, subjectKey string) (string, error) {
pdfBytes, err := decodeAndValidatePDF(authPDFBase64)
if err != nil {
return "", err
}
transactionID := "unknown_tx"
if v, ok := ctx.Value("transaction_id").(string); ok && strings.TrimSpace(v) != "" {
transactionID = strings.TrimSpace(v)
}
dir := filepath.Join(defaultAuthPDFStorageDir, strings.TrimSpace(apiCode))
if err := os.MkdirAll(dir, 0755); err != nil {
return "", fmt.Errorf("创建授权PDF存储目录失败: %w", err)
}
filename := fmt.Sprintf("%s_%s_%s.pdf",
sanitizeAuthPDFFilenamePart(transactionID),
sanitizeAuthPDFFilenamePart(subjectKey),
time.Now().Format("20060102_150405"),
)
fullPath := filepath.Join(dir, filename)
if err := os.WriteFile(fullPath, pdfBytes, 0644); err != nil {
return "", fmt.Errorf("写入授权PDF失败: %w", err)
}
if s.logger != nil {
s.logger.LogInfo(
"汇博授权PDF已本地留存",
zap.String("api_code", apiCode),
zap.String("transaction_id", transactionID),
zap.String("path", fullPath),
zap.Int("size_bytes", len(pdfBytes)),
)
}
return fullPath, nil
}
func sanitizeAuthPDFFilenamePart(s string) string {
s = strings.TrimSpace(s)
if s == "" {
return "unknown"
}
var b strings.Builder
for _, r := range s {
switch {
case r >= 'a' && r <= 'z', r >= 'A' && r <= 'Z', r >= '0' && r <= '9', r == '-', r == '_':
b.WriteRune(r)
default:
b.WriteRune('_')
}
}
result := b.String()
if len(result) > 48 {
result = result[:48]
}
return result
}
func generateSortedParam(m map[string]string) string {
keys := make([]string, 0, len(m))
for k, v := range m {