animeic 2 years ago
parent
commit
066b28d7ce

+ 1 - 0
boxcost/api/IExcel.go

@@ -5,6 +5,7 @@ type IExcel interface {
 	SetContent(content interface{})
 	SetTitle(title string)
 	SetRow(row int)
+	SetIsPdf(isPdf string)
 	GetRow() int
 	Draws()
 }

+ 4 - 0
boxcost/api/bill-produce-excel.go

@@ -614,6 +614,10 @@ func (b *ProduceBillExcel) SetTitle(title string) {
 func (b *ProduceBillExcel) SetRow(row int) {
 	b.Row = row
 }
+
+func (b *ProduceBillExcel) SetIsPdf(isPdf string) {
+	b.IsPdf = isPdf
+}
 func (b *ProduceBillExcel) GetRow() int {
 	return b.Row
 }

+ 2 - 0
boxcost/api/bill-produce.go

@@ -289,6 +289,8 @@ func DownProduceBill(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 		if err != nil {
 			return nil, errors.New("转化pdf失败")
 		}
+
+		defer res.Body.Close()
 		c.Header("Content-Type", "application/octet-stream")
 		c.Header("Content-Disposition", "attachment; filename="+"bill.pdf")
 		c.Header("Content-Transfer-Encoding", "binary")

+ 3 - 0
boxcost/api/bill-product-excel.go

@@ -531,6 +531,9 @@ func (b *ProductBillExcel) SetTitle(title string) {
 func (b *ProductBillExcel) SetRow(row int) {
 	b.Row = row
 }
+func (b *ProductBillExcel) SetIsPdf(isPdf string) {
+	b.IsPdf = isPdf
+}
 func (b *ProductBillExcel) GetRow() int {
 	return b.Row
 }

+ 1 - 0
boxcost/api/bill-product.go

@@ -292,6 +292,7 @@ func DownProductBill(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 		if err != nil {
 			return nil, errors.New("转化pdf失败")
 		}
+		defer res.Body.Close()
 		c.Header("Content-Type", "application/octet-stream")
 		c.Header("Content-Disposition", "attachment; filename="+"bill.pdf")
 		c.Header("Content-Transfer-Encoding", "binary")

+ 3 - 0
boxcost/api/bill-purchase-excel.go

@@ -481,6 +481,9 @@ func (b *PurchaseBillExcel) SetTitle(title string) {
 func (b *PurchaseBillExcel) SetRow(row int) {
 	b.Row = row
 }
+func (b *PurchaseBillExcel) SetIsPdf(isPdf string) {
+	b.IsPdf = isPdf
+}
 func (b *PurchaseBillExcel) GetRow() int {
 	return b.Row
 }

+ 1 - 0
boxcost/api/bill.go

@@ -262,6 +262,7 @@ func DownLoadBills(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 			fmt.Println(err)
 			return nil, errors.New("转化pdf失败")
 		}
+		defer res.Body.Close()
 		c.Header("Content-Type", "application/octet-stream")
 		c.Header("Content-Disposition", "attachment; filename="+"bill.pdf")
 		c.Header("Content-Transfer-Encoding", "binary")

+ 214 - 2
boxcost/api/plan.go

@@ -1,11 +1,15 @@
 package api
 
 import (
+	"archive/zip"
 	"box-cost/db/model"
 	"box-cost/db/repo"
 	"box-cost/log"
 	"errors"
 	"fmt"
+	"io"
+	"os"
+	"path/filepath"
 	"strings"
 	"time"
 
@@ -37,6 +41,8 @@ func ProductPlan(r *GinRouter) {
 	// r.GET("/bill/plan/download", DownLoadCompBills)
 	r.GET("/bill/plan/download", DownLoadPlanBills)
 
+	r.GET("/bill/plan/downloadPdf", DownLoadPlanBillsPdf)
+
 	// 生产成本表
 	r.GET("/plan/cost/download", DownLoadPlanCost)
 
@@ -104,9 +110,8 @@ func DownLoadPlanBills(c *gin.Context, apictx *ApiSession) (interface{}, error)
 	}
 	// 获取所有stages单据id
 	billIds := make([]string, 0)
-	curComp := &model.PackComponent{}
 	for _, comp := range plan.Pack.Components {
-		if comp.Id == "" || len(curComp.Stages) == 0 {
+		if comp.Id == "" || len(comp.Stages) == 0 {
 			continue
 		}
 		for _, stage := range comp.Stages {
@@ -230,6 +235,213 @@ func DownLoadPlanBills(c *gin.Context, apictx *ApiSession) (interface{}, error)
 
 	return nil, nil
 }
+func DownLoadPlanBillsPdf(c *gin.Context, apictx *ApiSession) (interface{}, error) {
+	_planId := c.Query("id")
+	planId, err := primitive.ObjectIDFromHex(_planId)
+	if err != nil {
+		return nil, errors.New("planId错误")
+	}
+	plan := model.ProductPlan{}
+	found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
+		CollectName: repo.CollectionProductPlan,
+		Query:       repo.Map{"_id": planId},
+	}, &plan)
+	if !found || err != nil {
+		return nil, errors.New("数据未找到")
+	}
+	// 获取所有stages单据id
+	billIds := make([]string, 0)
+	for _, comp := range plan.Pack.Components {
+		if comp.Id == "" || len(comp.Stages) == 0 {
+			continue
+		}
+		for _, stage := range comp.Stages {
+			billId, _ := primitive.ObjectIDFromHex(stage.BillId)
+			if !billId.IsZero() {
+				billIds = append(billIds, fmt.Sprintf("%d_%s", stage.BillType, stage.BillId))
+			}
+		}
+
+	}
+	// 去重单据号
+	typeBillIds := removeDuplicationSort(billIds)
+	if len(typeBillIds) < 1 {
+		return nil, errors.New("未找到单据信息")
+	}
+
+	companyName := getCompanyName(apictx)
+	planName := plan.Name
+	// 打包pdf的缓存目录
+	saveTmpDir := fmt.Sprintf("tmp1/%s", planName)
+
+	if isExistDir(saveTmpDir) {
+		os.RemoveAll(saveTmpDir)
+	}
+	// 记录文件数量
+	fileNum := 0
+	for _, tId := range typeBillIds {
+		productName := ""
+		supplierName := ""
+		f := excelize.NewFile()
+		index := f.NewSheet("Sheet1")
+		f.SetActiveSheet(index)
+		f.SetDefaultFont("宋体")
+
+		tidArr := strings.Split(tId, "_")
+		var billExcel IExcel
+		// 采购
+		billId, _ := primitive.ObjectIDFromHex(tidArr[1])
+		if tidArr[0] == "1" {
+			purchase := model.PurchaseBill{}
+			found, _ := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
+				CollectName: repo.CollectionBillPurchase,
+				Query:       repo.Map{"_id": billId},
+			}, &purchase)
+			if found {
+				billExcel = NewPurchaseBill(f)
+				if purchase.Reviewed == 1 {
+					if len(purchase.SignUsers) > 0 {
+						signs := []*model.Signature{}
+						repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
+							CollectName: repo.CollectionSignature,
+							Query:       repo.Map{"_id": bson.M{"$in": purchase.SignUsers}},
+							Sort:        bson.M{"sort": 1},
+						}, &signs)
+						billExcel.SetSignatures(signs)
+
+					}
+
+				}
+				productName = purchase.ProductName
+				supplierName = purchase.Supplier
+				billExcel.SetContent(&purchase)
+				billExcel.SetTitle(fmt.Sprintf("%s原材料采购单", companyName))
+			}
+
+		}
+		// 工艺
+		if tidArr[0] == "2" {
+			produce := model.ProduceBill{}
+			found, _ := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
+				CollectName: repo.CollectionBillProduce,
+				Query:       repo.Map{"_id": billId},
+			}, &produce)
+			if found {
+				billExcel = NewProduceBill(f)
+				if produce.Reviewed == 1 {
+					if len(produce.SignUsers) > 0 {
+						signs := []*model.Signature{}
+						repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
+							CollectName: repo.CollectionSignature,
+							Query:       repo.Map{"_id": bson.M{"$in": produce.SignUsers}},
+							Sort:        bson.M{"sort": 1},
+						}, &signs)
+						billExcel.SetSignatures(signs)
+					}
+
+				}
+				productName = produce.ProductName
+				supplierName = produce.Supplier
+				billExcel.SetContent(&produce)
+				billExcel.SetTitle(fmt.Sprintf("%s加工单", companyName))
+			}
+
+		}
+		// 成品采购
+		if tidArr[0] == "3" {
+			product := model.ProductBill{}
+			found, _ := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
+				CollectName: repo.CollectionBillProduct,
+				Query:       repo.Map{"_id": billId},
+			}, &product)
+			if found {
+				billExcel = NewProductBill(f)
+				if product.Reviewed == 1 {
+					if len(product.SignUsers) > 0 {
+						signs := []*model.Signature{}
+						repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
+							CollectName: repo.CollectionSignature,
+							Query:       repo.Map{"_id": bson.M{"$in": product.SignUsers}},
+							Sort:        bson.M{"sort": 1},
+						}, &signs)
+						billExcel.SetSignatures(signs)
+					}
+
+				}
+				productName = product.ProductName
+				supplierName = product.Supplier
+				billExcel.SetContent(&product)
+				billExcel.SetTitle(companyName)
+			}
+		}
+		if billExcel == nil {
+			continue
+		}
+		billExcel.SetIsPdf("true")
+		billExcel.Draws()
+		buf, _ := f.WriteToBuffer()
+		res, err := excelToPdf(buf, apictx.Svc.Conf.PdfApiAddr)
+		if err != nil {
+			fmt.Println(err)
+			log.Error(err)
+			return nil, errors.New("转化pdf失败")
+		}
+		body := res.Body
+		byteData, err := io.ReadAll(body)
+		if err != nil {
+			fmt.Println(err)
+			return nil, err
+		}
+		targePdfName := fmt.Sprintf("%s-%s.pdf", productName, supplierName)
+		err = savePdfToTmp(saveTmpDir, targePdfName, byteData)
+		if err != nil {
+			return nil, err
+		}
+		fileNum++
+	}
+	fmt.Println("fileNum: ", fileNum)
+	c.Header("Content-Type", "application/octet-stream")
+	c.Header("Content-Disposition", "attachment; filename="+planName+".zip")
+	c.Header("Content-Transfer-Encoding", "binary")
+
+	archive := zip.NewWriter(c.Writer)
+	defer archive.Close()
+	// 遍历路径信息
+	filepath.Walk(saveTmpDir, func(path string, info os.FileInfo, _ error) error {
+
+		// 如果是源路径,提前进行下一个遍历
+		if path == saveTmpDir {
+			return nil
+		}
+
+		// 获取:文件头信息
+		header, _ := zip.FileInfoHeader(info)
+		header.Name = strings.TrimPrefix(path, saveTmpDir+`/`)
+
+		// 判断:文件是不是文件夹
+		if info.IsDir() {
+			header.Name += `/`
+		} else {
+			// 设置:zip的文件压缩算法
+			header.Method = zip.Deflate
+		}
+
+		// 创建:压缩包头部信息
+		writer, _ := archive.CreateHeader(header)
+		if !info.IsDir() {
+			file, _ := os.Open(path)
+			defer file.Close()
+			io.Copy(writer, file)
+		}
+		return nil
+	})
+
+	// 删除缓存目录
+	os.RemoveAll(saveTmpDir)
+
+	return nil, nil
+}
+
 func DownLoadCompBills(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	_planId := c.Query("id")
 	compId := c.Query("compId")

+ 16 - 0
boxcost/api/print.go

@@ -49,6 +49,22 @@ func Printr(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 
 }
 
+// buf, _ := f.WriteToBuffer()
+// 		res, err := excelToPdf(buf, apictx.Svc.Conf.PdfApiAddr)
+// 		if err != nil {
+// 			return nil, errors.New("转化pdf失败")
+// 		}
+// 		body := res.Body
+// 		byteData, err := io.ReadAll(body)
+// 		if err != nil {
+// 			return nil, err
+// 		}
+// 		defer res.Body.Close()
+// 		// os.Mkdir("tmp", 0666)
+// 		if err := os.WriteFile("aaa.pdf", byteData, 0666); err != nil {
+// 			log.Fatal(err)
+// 		}
+
 // // 去重相邻元素
 // func removeDuplicationSort(arr []string) []string {
 // 	length := len(arr)

+ 30 - 0
boxcost/api/utils.go

@@ -3,10 +3,12 @@ package api
 import (
 	"box-cost/db/model"
 	"box-cost/db/repo"
+	"box-cost/log"
 	"bytes"
 	"fmt"
 	"math/rand"
 	"net/http"
+	"os"
 	"time"
 	"unsafe"
 
@@ -17,6 +19,34 @@ import (
 
 var SignatureDir string = "https://www.3dqueen.cloud/box/v1/boxcost/public/"
 
+// 保存文件为pdf
+func savePdfToTmp(saveTmpDir, fileName string, data []byte) error {
+
+	err := os.MkdirAll(saveTmpDir, os.ModePerm)
+	if err != nil {
+		log.Error(err)
+		return err
+	}
+	fullFileName := fmt.Sprintf("%s/%s", saveTmpDir, fileName)
+	if err := os.WriteFile(fullFileName, data, 0666); err != nil {
+		log.Error(err)
+		return err
+	}
+	return nil
+
+}
+
+func isExistDir(dir string) bool {
+	_, err := os.Stat(dir)
+	if err != nil {
+		if os.IsExist(err) {
+			return true
+		}
+		return false
+	}
+	return true
+}
+
 // 去重相邻元素
 func removeDuplicationSort(arr []string) []string {
 	length := len(arr)

+ 17 - 0
boxcost/boxcost.log

@@ -19,3 +19,20 @@
 {"level":"info","timestamp":"2023-02-21 12:23:02","message":"[<nil>]","service_name":"boxcost"}
 {"level":"info","timestamp":"2023-02-21 12:25:42","message":"[error decoding key papers.0.price: cannot decode string into a float32 or float64 type]","service_name":"boxcost"}
 {"level":"info","timestamp":"2023-02-21 14:15:57","message":"[<nil>]","service_name":"boxcost"}
+{"level":"fatal","timestamp":"2023-03-09 16:26:05","message":"[open tmp/aaa.pdf: no such file or directory]","service_name":"boxcost"}
+{"level":"fatal","timestamp":"2023-03-09 16:27:15","message":"[open tmp/aaa.pdf: permission denied]","service_name":"boxcost"}
+{"level":"fatal","timestamp":"2023-03-09 16:27:27","message":"[open tmp/aaa.pdf: permission denied]","service_name":"boxcost"}
+{"level":"fatal","timestamp":"2023-03-09 16:28:02","message":"[open tmp/aaa.pdf: permission denied]","service_name":"boxcost"}
+{"level":"error","timestamp":"2023-03-09 17:20:57","message":"[fstatat tmp/喜乐: permission denied]","service_name":"boxcost"}
+{"level":"error","timestamp":"2023-03-09 17:27:10","message":"[fstatat tmp/喜乐: permission denied]","service_name":"boxcost"}
+{"level":"error","timestamp":"2023-03-09 17:31:58","message":"[fstatat tmp/喜乐: permission denied]","service_name":"boxcost"}
+{"level":"error","timestamp":"2023-03-09 17:32:09","message":"[mkdir tmp/喜乐: permission denied]","service_name":"boxcost"}
+{"level":"error","timestamp":"2023-03-09 17:33:07","message":"[mkdir tmp/喜乐: permission denied]","service_name":"boxcost"}
+{"level":"error","timestamp":"2023-03-09 17:36:16","message":"[mkdir tmp/喜乐: permission denied]","service_name":"boxcost"}
+{"level":"error","timestamp":"2023-03-09 17:39:03","message":"[mkdir tmp/喜乐: permission denied]","service_name":"boxcost"}
+{"level":"error","timestamp":"2023-03-09 17:41:12","message":"[mkdir ./tmp/喜乐: permission denied]","service_name":"boxcost"}
+{"level":"error","timestamp":"2023-03-09 17:42:25","message":"[mkdir ./tmp/喜乐: permission denied]","service_name":"boxcost"}
+{"level":"error","timestamp":"2023-03-09 17:43:09","message":"[mkdir ./tmp/喜乐: permission denied]","service_name":"boxcost"}
+{"level":"error","timestamp":"2023-03-09 17:43:54","message":"[mkdir ./tmp/addd: permission denied]","service_name":"boxcost"}
+{"level":"error","timestamp":"2023-03-10 09:48:29","message":"[Post \"http://localhost:3001/convert/office\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)]","service_name":"boxcost"}
+{"level":"error","timestamp":"2023-03-10 09:49:12","message":"[Post \"http://localhost:3001/convert/office\": context deadline exceeded (Client.Timeout exceeded while awaiting headers)]","service_name":"boxcost"}