qnc-server-old/service/feature.go

175 lines
5.9 KiB
Go
Raw Permalink Normal View History

2024-09-14 10:48:09 +08:00
package service
import (
"encoding/json"
"fmt"
"github.com/jung-kurt/gofpdf"
"io"
"log"
"net/http"
"os"
"qnc-server/utils"
"strings"
"time"
)
const API_KEY = "aMsrBNGUJxgcgqdm3SEdcumm"
const SECRET_KEY = "sWlv2h2AWA3aAt5bjXCkE6WeA5AzpAAD"
type Feature struct {
}
// Service 函数:接受 base64 编码的图像,返回 OCR 识别结果
func (f *Feature) OCRService(imageBase64 string) (string, error) {
// 获取 Access Token
accessToken := f.GetAccessToken()
if accessToken == "" {
return "", fmt.Errorf("获取 Access Token 失败")
}
// 设置请求 URL
url := "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic?access_token=" + accessToken
// 设置请求体,包含图片的 base64 编码
payload := strings.NewReader(fmt.Sprintf("image=%s&detect_direction=false&paragraph=false&probability=false&multidirectional_recognize=false", imageBase64))
// 创建 HTTP 客户端和请求
client := &http.Client{}
req, err := http.NewRequest("POST", url, payload)
if err != nil {
return "", err
}
// 设置请求头
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("Accept", "application/json")
// 发送请求并获取响应
res, err := client.Do(req)
if err != nil {
return "", err
}
defer res.Body.Close()
// 读取响应体
body, err := io.ReadAll(res.Body)
if err != nil {
return "", err
}
return string(body), nil
}
/**
* 使用 AKSK 生成鉴权签名Access Token
* @return string 鉴权签名信息Access Token
*/
func (f *Feature) GetAccessToken() string {
url := "https://aip.baidubce.com/oauth/2.0/token"
postData := fmt.Sprintf("grant_type=client_credentials&client_id=%s&client_secret=%s", API_KEY, SECRET_KEY)
resp, err := http.Post(url, "application/x-www-form-urlencoded", strings.NewReader(postData))
if err != nil {
fmt.Println(err)
return ""
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
return ""
}
accessTokenObj := map[string]interface{}{}
_ = json.Unmarshal(body, &accessTokenObj)
return accessTokenObj["access_token"].(string)
}
func (f *Feature) GenerateSignPDF(name string, id uint, signatureBase64 string) (fileName string, err error) {
// 创建 PDF 实例A4 纸张大小
pdf := gofpdf.New("P", "mm", "A4", "")
fontPath := "simhei.ttf"
// 添加中文字体支持
pdf.AddUTF8Font("SimHei", "", fontPath) // 使用 simhei.ttf 字体
pdf.SetFont("SimHei", "", 12)
// 添加一页
pdf.AddPage()
// 插入标题,居中对齐
pdf.SetFont("SimHei", "", 20)
pdf.CellFormat(0, 10, "声明", "", 1, "C", false, 0, "") // C 表示居中对齐
pdf.Ln(12)
// 插入副标题
pdf.SetFont("SimHei", "", 14)
pdf.Cell(40, 10, "全能查声明:")
pdf.Ln(10)
// 插入正文内容,添加两字符的缩进(全角空格)
pdf.SetFont("SimHei", "", 12)
indent := "  " // 两字符的缩进,使用全角空格
pdf.MultiCell(0, 10, indent+"1、本产品所有数据均来自第三方。可能部分数据未公开数据更新延迟或信息受到限制不一定全部返回因此我们不做准确性、真实性、完整性承诺。不同数据格式及记录详细程度会存在差异此为行业正常现象。本报告仅供参考不能作为诉讼证据、决策性依据等材料请结合实际情况做出更准确的决策。", "", "", false)
pdf.Ln(3)
pdf.MultiCell(0, 10, indent+"2、本产品仅供用户本人查询或被授权查询。除非用户取得合法授权用户不得利用本产品查询他人信息。用户因未获得合法授权而擅自查询他人信息所产生的任何后果由用户自行承担责任。", "", "", false)
pdf.Ln(3)
// 插入承诺声明
pdf.SetFont("SimHei", "", 14)
pdf.Cell(40, 10, "本人承诺:")
pdf.Ln(10)
text := fmt.Sprintf("本人%s在此声明我即将通过此小程序查询的婚姻状态信息仅涉及本人。本人确认不将所得信息用作任何诉讼证据不会将所获取的信息用于任何非法用途包括但不限于欺诈、胁迫、侵犯隐私或其他违法行为不将所得信息转卖、传播给他人。本人承诺对查询结果所引发的任何后果承担全部责任。", name)
// 插入承诺内容,添加两字符的缩进
pdf.SetFont("SimHei", "", 12)
pdf.MultiCell(0, 10, indent+text, "", "", false)
pdf.Ln(10)
// 定位签名和日期到右下角
pageWidth, pageHeight := pdf.GetPageSize()
rightMargin := 20.0
bottomMargin := 20.0
// 设置签名部分的 XY 坐标,靠右下角
pdf.SetXY(pageWidth-rightMargin-40, pageHeight-bottomMargin-40) // 签名部分坐标
pdf.SetFont("SimHei", "", 12)
pdf.Cell(40, 10, "签名:")
// 解码 Base64 签名图片并保存为临时文件
var tempFileName = fmt.Sprintf("signature-%d.png", id)
signaturePath, err := utils.DecodeBase64ToPNG(signatureBase64, tempFileName)
if err != nil {
log.Printf("【签名图片生成】解码 Base64 签名图片并保存为临时文件失败:%v", err)
return "", err
}
// 在 PDF 中嵌入签名图片
pdf.ImageOptions(signaturePath, pageWidth-rightMargin-28, pageHeight-bottomMargin-40, 40, 10, false, gofpdf.ImageOptions{ImageType: "PNG"}, 0, "")
// 插入当前日期,显示在签名下方
currentDate := time.Now().Format("2006-01-02")
currentDateCN := time.Now().Format("2006年01月02日")
pdf.SetXY(pageWidth-rightMargin-40, pageHeight-bottomMargin-20)
pdf.Cell(40, 10, "日期:"+currentDateCN)
// 根据日期和 ID 动态生成文件名
outputDir := "signature"
os.MkdirAll(outputDir, os.ModePerm) // 如果不存在则创建目录
fileName = fmt.Sprintf("%s/%s_%d.pdf", outputDir, currentDate, id)
// 保存 PDF 文件
err = pdf.OutputFileAndClose(fileName)
if err != nil {
log.Printf("【签名图片生成】保存 PDF 文件失败:%v", err)
return "", err
}
// 删除临时签名图片文件
err = os.Remove(signaturePath)
if err != nil {
log.Printf("【签名图片生成】删除临时文件失败:%v", err)
}
return fileName, nil
}