fonchain-fiee/pkg/service/bundle/logic/signContract.go
2025-02-22 15:31:21 +08:00

130 lines
3.3 KiB
Go

package logic
import (
"bytes"
"errors"
"fmt"
"fonchain-fiee/pkg/service/bundle/common"
"fonchain-fiee/pkg/service/upload"
"github.com/signintech/gopdf"
"go.uber.org/zap"
"image"
"io"
"log"
"net/http"
"os"
"time"
)
func SignContract(customerName string, contract string, signImgPath string) (outputUrl string, err error) {
filePath := customerName + "_" + time.Now().String() + ".pdf"
downloadFileErr := DownloadFile(filePath, contract)
if downloadFileErr != nil {
zap.L().Error("download file error: ", zap.Error(downloadFileErr))
//service.Error(c, errors.New(common.ErrorDownloadFile))
return outputUrl, errors.New(common.ErrorDownloadFile)
}
signFile := customerName + "signed" + "_" + time.Now().String() + ".pdf"
signErr := InsertSignature(filePath, signFile, signImgPath)
if signErr != nil {
zap.L().Error("insert signature error: ", zap.Error(signErr))
return outputUrl, errors.New(common.ErrorInsertSignature)
}
os.Remove(filePath)
outputUrl, ossErr := upload.PutBos(signFile, upload.PdfType, true)
if ossErr != nil {
return "", errors.New(common.ErrorUploadFile)
}
return outputUrl, nil
}
// InsertSignature 把用户签字内容 填充到 合同模版里面
func InsertSignature(templatePath string, outputPath string, signImgPath string) error {
pdf := gopdf.GoPdf{}
pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4})
resp, imageErr := http.Get(signImgPath)
if imageErr != nil {
return errors.New("error downloading signature image")
}
defer resp.Body.Close()
b, _err := io.ReadAll(resp.Body)
if _err != nil {
return errors.New("error reading signature image")
}
// Create a new reader from the bytes
imgReader := bytes.NewReader(b)
img, _, err := image.DecodeConfig(imgReader)
if err != nil {
return errors.New("error decoding signature image")
}
w := img.Width
h := img.Height
// 导入模板文件中的页面
err = pdf.ImportPagesFromSource(templatePath, "/MediaBox")
if err != nil {
log.Fatalf("无法导入页面: %v", err)
}
// 获取模板文件的总页数
totalPages := pdf.GetNumberOfPages()
fmt.Printf("模板文件的总页数: %d\n", totalPages)
targetPage := totalPages
// 遍历所有页
for i := 1; i <= totalPages; i++ {
tpl := pdf.ImportPage(templatePath, i, "/MediaBox")
pdf.AddPage()
pdf.UseImportedTemplate(tpl, 0, 0, gopdf.PageSizeA4.W, gopdf.PageSizeA4.H)
// 只在目标页插入签名
if i == targetPage {
imgH1, _err := gopdf.ImageHolderByBytes(b)
if _err != nil {
//zap.L().Error("SignContract err", zap.Error(err))
return errors.New("error processing signature image")
}
newWidth := 80.0
newHeight := (newWidth / float64(w)) * float64(h)
err = pdf.ImageByHolder(imgH1, 380, 540, &gopdf.Rect{W: newWidth, H: newHeight})
if err != nil {
//zap.L().Error("SignContract err", zap.Error(err))
return errors.New("error inserting signature")
}
}
}
// 生成新的 PDF
if err = pdf.WritePdf(outputPath); err != nil {
//zap.L().Error("WritePdf err", zap.Error(err))
return errors.New("error writing final PDF")
}
return nil
}
func DownloadFile(filepath string, url string) error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
return err
}