310 lines
8.0 KiB
Go
310 lines
8.0 KiB
Go
package logic
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"fonchain-fiee/pkg/model"
|
|
"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"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
func SignContract(customerNum, contract, signImgPath, companyImgPath, contractNo, buyerName, idNo, telNum, address string, price float32, contractDuration int64) (outputUrl string, err error) {
|
|
filePath := model.MediaPath + customerNum + time.Now().Format("20060102150405") + ".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 := model.MediaPath + customerNum + "signed" + time.Now().Format("20060102150405") + ".pdf"
|
|
|
|
/*signErr := InsertSignature(filePath, signFile, signImgPath, contractNo, idNo, telNum, address, price)
|
|
if signErr != nil {
|
|
zap.L().Error("insert signature error: ", zap.Error(signErr))
|
|
return outputUrl, errors.New(common.ErrorInsertSignature)
|
|
}*/
|
|
|
|
signErr := InsertSignatureV1(filePath, signFile, signImgPath, companyImgPath, contractNo, buyerName, idNo, telNum, address, price, contractDuration)
|
|
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 InsertSignatureV1(templatePath, outputPath, signImgPath, companyImgPath, contractNo, buyerName, idNo, telNum, address string, price float32, contractDuration int64) error {
|
|
pdf := gopdf.GoPdf{}
|
|
pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4})
|
|
|
|
// 导入模板文件中的页面
|
|
err := pdf.ImportPagesFromSource(templatePath, "/MediaBox")
|
|
if err != nil {
|
|
log.Fatalf("无法导入页面: %v", err)
|
|
}
|
|
|
|
// 获取模板文件的总页数
|
|
totalPages := pdf.GetNumberOfPages()
|
|
fmt.Printf("模板文件的总页数: %d\n", totalPages)
|
|
|
|
buyerPage := 1
|
|
|
|
pricePage := 2
|
|
|
|
limitTimePage := 3
|
|
|
|
signPage := totalPages
|
|
|
|
tffErr := pdf.AddTTFFont("simfang", "./simfang.ttf")
|
|
if tffErr != nil {
|
|
log.Fatalf("加载中文字体失败: %v", tffErr)
|
|
}
|
|
|
|
// 设置字体和字号
|
|
err = pdf.SetFont("simfang", "", 14)
|
|
if err != nil {
|
|
log.Fatalf("设置字体失败: %v", err)
|
|
}
|
|
|
|
// 写 buyer info
|
|
pdf.SetPage(buyerPage)
|
|
pdf.SetX(145)
|
|
pdf.SetY(134)
|
|
pdf.Cell(nil, contractNo)
|
|
|
|
pdf.SetX(145)
|
|
pdf.SetY(159)
|
|
pdf.Cell(nil, time.Now().Format("2006-01-02"))
|
|
|
|
pdf.SetX(180)
|
|
pdf.SetY(208)
|
|
pdf.Cell(nil, buyerName)
|
|
|
|
pdf.SetX(210)
|
|
pdf.SetY(233)
|
|
pdf.Cell(nil, idNo)
|
|
|
|
pdf.SetX(200)
|
|
pdf.SetY(259)
|
|
pdf.Cell(nil, telNum)
|
|
|
|
pdf.SetX(200)
|
|
pdf.SetY(284)
|
|
pdf.Cell(nil, address)
|
|
|
|
// 填 金额
|
|
pdf.SetPage(pricePage)
|
|
pdf.SetX(379)
|
|
pdf.SetY(639)
|
|
pdf.Cell(nil, strconv.FormatFloat(float64(price), 'f', 2, 32))
|
|
|
|
// 写 有效期
|
|
t := time.Now().AddDate(int(contractDuration), 0, 0)
|
|
pdf.SetPage(limitTimePage)
|
|
pdf.SetX(327)
|
|
pdf.SetY(358)
|
|
pdf.Cell(nil, t.Format("2006"))
|
|
|
|
pdf.SetX(420)
|
|
pdf.SetY(358)
|
|
pdf.Cell(nil, t.Format("01"))
|
|
|
|
pdf.SetX(486)
|
|
pdf.SetY(358)
|
|
pdf.Cell(nil, t.Format("02"))
|
|
|
|
// 只在目标页插入签名
|
|
pdf.SetPage(signPage)
|
|
|
|
signImgResp, imageErr := http.Get(signImgPath)
|
|
if imageErr != nil {
|
|
return errors.New("error downloading signature image")
|
|
}
|
|
defer signImgResp.Body.Close()
|
|
|
|
signImgB, _err := io.ReadAll(signImgResp.Body)
|
|
if _err != nil {
|
|
return errors.New("error reading signature image")
|
|
}
|
|
|
|
// Create a new reader from the bytes
|
|
signImgReader := bytes.NewReader(signImgB)
|
|
signImg, _, err := image.DecodeConfig(signImgReader)
|
|
if err != nil {
|
|
return errors.New("error decoding signature image")
|
|
}
|
|
|
|
signImgw := signImg.Width
|
|
signImgh := signImg.Height
|
|
|
|
imgH1, _err := gopdf.ImageHolderByBytes(signImgB)
|
|
if _err != nil {
|
|
//zap.L().Error("SignContract err", zap.Error(err))
|
|
return errors.New("error processing signature image")
|
|
}
|
|
newSignWidth := 80.0
|
|
newSignHeight := (newSignWidth / float64(signImgw)) * float64(signImgh)
|
|
|
|
// buyer sign
|
|
err = pdf.ImageByHolder(imgH1, 180, 560, &gopdf.Rect{W: newSignWidth, H: newSignHeight})
|
|
if err != nil {
|
|
//zap.L().Error("SignContract err", zap.Error(err))
|
|
return errors.New("error inserting signature")
|
|
}
|
|
|
|
pdf.SetX(320)
|
|
pdf.SetY(585)
|
|
pdf.Cell(nil, time.Now().Format("2006-01-02"))
|
|
|
|
companyImgResp, companyImageErr := http.Get(companyImgPath)
|
|
if companyImageErr != nil {
|
|
return errors.New("error downloading signature image")
|
|
}
|
|
defer companyImgResp.Body.Close()
|
|
|
|
companyImgB, _err := io.ReadAll(companyImgResp.Body)
|
|
if _err != nil {
|
|
return errors.New("error reading signature image")
|
|
}
|
|
|
|
// Create a new reader from the bytes
|
|
companyImgReader := bytes.NewReader(companyImgB)
|
|
companyImg, _, err := image.DecodeConfig(companyImgReader)
|
|
if err != nil {
|
|
return errors.New("error decoding signature image")
|
|
}
|
|
|
|
companyImgw := companyImg.Width
|
|
companyImgh := companyImg.Height
|
|
|
|
companyImgH1, _err := gopdf.ImageHolderByBytes(companyImgB)
|
|
if _err != nil {
|
|
//zap.L().Error("SignContract err", zap.Error(err))
|
|
return errors.New("error processing signature image")
|
|
}
|
|
newCompanyWidth := 80.0
|
|
newCompanyHeight := (newCompanyWidth / float64(companyImgw)) * float64(companyImgh)
|
|
|
|
// seller sign
|
|
err = pdf.ImageByHolder(companyImgH1, 180, 610, &gopdf.Rect{W: newCompanyWidth, H: newCompanyHeight})
|
|
if err != nil {
|
|
//zap.L().Error("SignContract err", zap.Error(err))
|
|
return errors.New("error inserting signature")
|
|
}
|
|
|
|
pdf.SetX(320)
|
|
pdf.SetY(635)
|
|
pdf.Cell(nil, time.Now().Format("2006-01-02"))
|
|
|
|
// 生成新的 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
|
|
}
|