f
This commit is contained in:
@@ -37,15 +37,17 @@ type ApiRequestService struct {
|
||||
featureModel model.FeatureModel
|
||||
productFeatureModel model.ProductFeatureModel
|
||||
tianyuanapi *tianyuanapi.Client
|
||||
authService *AuthorizationService
|
||||
}
|
||||
|
||||
// NewApiRequestService 是一个构造函数,用于初始化 ApiRequestService
|
||||
func NewApiRequestService(c config.Config, featureModel model.FeatureModel, productFeatureModel model.ProductFeatureModel, tianyuanapi *tianyuanapi.Client) *ApiRequestService {
|
||||
func NewApiRequestService(c config.Config, featureModel model.FeatureModel, productFeatureModel model.ProductFeatureModel, tianyuanapi *tianyuanapi.Client, authService *AuthorizationService) *ApiRequestService {
|
||||
return &ApiRequestService{
|
||||
config: c,
|
||||
featureModel: featureModel,
|
||||
productFeatureModel: productFeatureModel,
|
||||
tianyuanapi: tianyuanapi,
|
||||
authService: authService,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,6 +198,7 @@ var requestProcessors = map[string]func(*ApiRequestService, []byte) ([]byte, err
|
||||
"IVYZ7F3A": (*ApiRequestService).ProcessIVYZ7F3ARequest,
|
||||
"IVYZ3P9M": (*ApiRequestService).ProcessIVYZ3P9MRequest,
|
||||
"FLXG7E8F": (*ApiRequestService).ProcessFLXG7E8FRequest,
|
||||
"IVYZ4Y27": (*ApiRequestService).ProcessIVYZ4Y27Request,
|
||||
}
|
||||
|
||||
// PreprocessRequestApi 调用指定的请求处理函数
|
||||
@@ -1456,3 +1459,33 @@ func (a *ApiRequestService) ProcessFLXG7E8FRequest(params []byte) ([]byte, error
|
||||
|
||||
return convertTianyuanResponse(resp)
|
||||
}
|
||||
|
||||
// ProcessIVYZ4Y27Request 学历信息查询(需生成专用授权书PDF并Base64编码传入)
|
||||
func (a *ApiRequestService) ProcessIVYZ4Y27Request(params []byte) ([]byte, error) {
|
||||
name := gjson.GetBytes(params, "name")
|
||||
idCard := gjson.GetBytes(params, "id_card")
|
||||
if !name.Exists() || !idCard.Exists() {
|
||||
return nil, errors.New("api请求, IVYZ4Y27, 获取相关参数失败")
|
||||
}
|
||||
|
||||
// 生成专用授权书PDF并Base64编码
|
||||
userInfo := map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
}
|
||||
authFileBase64, err := a.authService.GenerateIVYZ4Y27AuthorizationBase64(userInfo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("生成IVYZ4Y27授权书失败: %v", err)
|
||||
}
|
||||
|
||||
resp, err := a.tianyuanapi.CallInterface("IVYZ4Y27", map[string]interface{}{
|
||||
"name": name.String(),
|
||||
"id_card": idCard.String(),
|
||||
"auth_authorize_file_base64": authFileBase64,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return convertTianyuanResponse(resp)
|
||||
}
|
||||
|
||||
@@ -4,11 +4,13 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
"tydata-server/app/main/api/internal/config"
|
||||
"tydata-server/app/main/model"
|
||||
@@ -329,3 +331,149 @@ func getUserInfoString(userInfo map[string]interface{}, key string) string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// generatePDFFromTemplate 从模板文件生成PDF内容
|
||||
func (s *AuthorizationService) generatePDFFromTemplate(templatePath string, data map[string]string) ([]byte, error) {
|
||||
// 查找模板文件
|
||||
tmplPaths := []string{
|
||||
templatePath,
|
||||
"/app/" + templatePath,
|
||||
"app/main/api/" + templatePath,
|
||||
"../../" + templatePath,
|
||||
"../../../" + templatePath,
|
||||
"../../../../" + templatePath,
|
||||
"../../../../../" + templatePath,
|
||||
"../../static/" + filepath.Base(templatePath),
|
||||
"../../../static/" + filepath.Base(templatePath),
|
||||
"../../../../static/" + filepath.Base(templatePath),
|
||||
}
|
||||
|
||||
var tmplFile string
|
||||
for _, p := range tmplPaths {
|
||||
if _, err := os.Stat(p); err == nil {
|
||||
tmplFile = p
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if tmplFile == "" {
|
||||
return nil, fmt.Errorf("未找到模板文件: %s", templatePath)
|
||||
}
|
||||
|
||||
// 解析模板文件
|
||||
tmpl, err := template.ParseFiles(tmplFile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "解析模板文件失败: %s", tmplFile)
|
||||
}
|
||||
|
||||
// 渲染模板
|
||||
var contentBuf bytes.Buffer
|
||||
if err := tmpl.Execute(&contentBuf, data); err != nil {
|
||||
return nil, errors.Wrapf(err, "渲染模板失败")
|
||||
}
|
||||
renderedContent := contentBuf.String()
|
||||
|
||||
// 创建PDF文档
|
||||
pdf := gofpdf.New("P", "mm", "A4", "")
|
||||
|
||||
// 加载中文字体
|
||||
fontPaths := []string{
|
||||
"static/SIMHEI.TTF",
|
||||
"/app/static/SIMHEI.TTF",
|
||||
"app/main/api/static/SIMHEI.TTF",
|
||||
"../../static/SIMHEI.TTF",
|
||||
"../../../static/SIMHEI.TTF",
|
||||
"../../../../static/SIMHEI.TTF",
|
||||
}
|
||||
|
||||
fontAdded := false
|
||||
for _, fontPath := range fontPaths {
|
||||
if _, err := os.Stat(fontPath); err == nil {
|
||||
pdf.AddUTF8Font("ChineseFont", "", fontPath)
|
||||
fontAdded = true
|
||||
logx.Infof("成功加载字体: %s", fontPath)
|
||||
break
|
||||
} else {
|
||||
logx.Debugf("字体文件不存在: %s, 错误: %v", fontPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
if !fontAdded {
|
||||
pdf.SetFont("Arial", "", 11)
|
||||
logx.Errorf("未找到中文字体文件,使用默认Arial字体,可能无法正确显示中文")
|
||||
} else {
|
||||
pdf.SetFont("ChineseFont", "", 11)
|
||||
}
|
||||
|
||||
// 设置每页Footer回调,用于在每页添加水印
|
||||
companyName := data["CompanyName"]
|
||||
if companyName == "" {
|
||||
companyName = "海南海宇大数据科技有限公司"
|
||||
}
|
||||
capturedFontAdded := fontAdded
|
||||
capturedCompanyName := companyName
|
||||
pdf.SetFooterFunc(func() {
|
||||
addWatermarkToPage(pdf, capturedFontAdded, capturedCompanyName)
|
||||
})
|
||||
|
||||
pdf.AddPage()
|
||||
|
||||
// 写入渲染后的内容
|
||||
pdf.MultiCell(0, 6, renderedContent, "", "", false)
|
||||
|
||||
// 输出PDF字节
|
||||
var pdfBuf bytes.Buffer
|
||||
if err := pdf.Output(&pdfBuf); err != nil {
|
||||
return nil, errors.Wrapf(err, "生成PDF字节数组失败")
|
||||
}
|
||||
|
||||
return pdfBuf.Bytes(), nil
|
||||
}
|
||||
|
||||
// addWatermarkToPage 给当前页面添加水印(红色公司名,居中单个水印)
|
||||
func addWatermarkToPage(pdf *gofpdf.Fpdf, fontAdded bool, companyName string) {
|
||||
if fontAdded {
|
||||
pdf.SetFont("ChineseFont", "", 40)
|
||||
} else {
|
||||
pdf.SetFont("Arial", "", 40)
|
||||
}
|
||||
pdf.SetTextColor(255, 200, 200) // 浅红色
|
||||
|
||||
// A4页面尺寸 210x297mm,水印放在页面正中央
|
||||
pageWidth, pageHeight := pdf.GetPageSize()
|
||||
x := pageWidth / 2
|
||||
y := pageHeight / 2
|
||||
|
||||
pdf.TransformBegin()
|
||||
pdf.TransformRotate(45, x, y)
|
||||
pdf.Text(x, y, companyName)
|
||||
pdf.TransformEnd()
|
||||
pdf.SetTextColor(0, 0, 0)
|
||||
}
|
||||
|
||||
// GenerateIVYZ4Y27AuthorizationBase64 生成IVYZ4Y27专用授权书PDF并返回Base64编码字符串
|
||||
func (s *AuthorizationService) GenerateIVYZ4Y27AuthorizationBase64(userInfo map[string]interface{}) (string, error) {
|
||||
name := getUserInfoString(userInfo, "name")
|
||||
idCard := getUserInfoString(userInfo, "id_card")
|
||||
if name == "" || idCard == "" {
|
||||
return "", fmt.Errorf("缺少必要的用户信息(name或id_card)")
|
||||
}
|
||||
|
||||
// 构建模板变量
|
||||
data := map[string]string{
|
||||
"CompanyName": "海南海宇大数据科技有限公司",
|
||||
"Name": name,
|
||||
"IdCard": idCard,
|
||||
"Mobile": getUserInfoString(userInfo, "mobile"),
|
||||
"Date": time.Now().Format("2006年1月2日"),
|
||||
}
|
||||
|
||||
// 从模板生成PDF
|
||||
pdfBytes, err := s.generatePDFFromTemplate("static/authorization_ivyz4y27.tmpl", data)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "生成IVYZ4Y27授权书PDF失败")
|
||||
}
|
||||
|
||||
// Base64编码
|
||||
return base64.StdEncoding.EncodeToString(pdfBytes), nil
|
||||
}
|
||||
|
||||
@@ -191,7 +191,8 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
alipayService := service.NewAliPayService(c)
|
||||
wechatPayService := service.NewWechatPayService(c, userAuthModel, service.InitTypeWxPayPubKey)
|
||||
applePayService := service.NewApplePayService(c)
|
||||
apiRequestService := service.NewApiRequestService(c, featureModel, productFeatureModel, tianyuanapi)
|
||||
authorizationService := service.NewAuthorizationService(c, authorizationDocumentModel)
|
||||
apiRequestService := service.NewApiRequestService(c, featureModel, productFeatureModel, tianyuanapi, authorizationService)
|
||||
verificationService := service.NewVerificationService(c, tianyuanapi, apiRequestService)
|
||||
asynqService := service.NewAsynqService(c)
|
||||
agentService := service.NewAgentService(c, orderModel, agentModel, agentAuditModel, agentClosureModel,
|
||||
@@ -204,7 +205,6 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
adminPromotionLinkStatsService := service.NewAdminPromotionLinkStatsService(adminPromotionLinkModel,
|
||||
adminPromotionLinkStatsTotalModel, adminPromotionLinkStatsHistoryModel)
|
||||
imageService := service.NewImageService()
|
||||
authorizationService := service.NewAuthorizationService(c, authorizationDocumentModel)
|
||||
|
||||
// ============================== 异步任务服务 ==============================
|
||||
asynqServer := asynq.NewServer(
|
||||
|
||||
Reference in New Issue
Block a user