Explorar el Código

update report

animeic hace 2 años
padre
commit
6f7f07ab89
Se han modificado 4 ficheros con 1059 adiciones y 176 borrados
  1. 293 0
      boxcost/api/report-produce-excel.go
  2. 306 0
      boxcost/api/report-purchase-excel.go
  3. 452 170
      boxcost/api/report.go
  4. 8 6
      boxcost/db/model/bill.go

+ 293 - 0
boxcost/api/report-produce-excel.go

@@ -0,0 +1,293 @@
+package api
+
+import (
+	"box-cost/db/model"
+	"fmt"
+	"strconv"
+
+	"github.com/xuri/excelize/v2"
+)
+
+type ReportProduceExcel struct {
+	Offset int
+	Row    int
+
+	Title string //标题
+
+	Excel *excelize.File
+
+	SheetName string
+
+	AlignCenterStyle int
+
+	Content *model.ProduceBill
+
+	BudgetCount float64
+	RealCount   float64
+}
+
+func (b *ReportProduceExcel) drawTitle() error {
+	// 设置外边距
+	marginLeft := excelize.PageMarginLeft(0.15)
+	b.Excel.SetPageMargins(b.SheetName, marginLeft)
+	tileIndex := b.Offset + 1
+	startCell := fmt.Sprintf("A%d", tileIndex)
+	err := b.Excel.MergeCell(b.SheetName, startCell, fmt.Sprintf("L%d", tileIndex))
+	if err != nil {
+		return err
+	}
+
+	style, err := b.Excel.NewStyle(&excelize.Style{
+		Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
+		Font:      &excelize.Font{Bold: true, Size: 18}})
+	if err != nil {
+		return err
+	}
+	err = b.Excel.SetCellStyle(b.SheetName, startCell, startCell, style)
+	if err != nil {
+		return err
+	}
+	b.Excel.SetRowHeight(b.SheetName, tileIndex, 23)
+	b.Excel.SetCellValue(b.SheetName, startCell, b.Title)
+	return nil
+}
+
+func (b *ReportProduceExcel) drawSubTitles() error {
+	row := b.Offset + 2
+
+	styleLeft, err := b.Excel.NewStyle(&excelize.Style{
+		Alignment: &excelize.Alignment{Horizontal: "left", Vertical: "center"},
+		Font:      &excelize.Font{Size: 11}})
+	if err != nil {
+		return err
+	}
+	styleRight, err := b.Excel.NewStyle(&excelize.Style{
+		Alignment: &excelize.Alignment{Horizontal: "right", Vertical: "center"},
+		Font:      &excelize.Font{Size: 11}})
+	if err != nil {
+		return err
+	}
+
+	var drawLeft = func(rowIndex int, value string) error {
+		//左边1
+		left1Cell := fmt.Sprintf("A%d", rowIndex)
+		err = b.Excel.MergeCell(b.SheetName, left1Cell, fmt.Sprintf("E%d", rowIndex))
+		if err != nil {
+			return err
+		}
+		err = b.Excel.SetCellStyle(b.SheetName, left1Cell, left1Cell, styleLeft)
+		if err != nil {
+			return err
+		}
+		b.Excel.SetCellValue(b.SheetName, left1Cell, value)
+		return nil
+	}
+
+	var drawRight = func(rowIndex int, value string) error {
+		right1Cell := fmt.Sprintf("F%d", rowIndex)
+		err = b.Excel.MergeCell(b.SheetName, right1Cell, fmt.Sprintf("L%d", rowIndex))
+		if err != nil {
+			return err
+		}
+		err = b.Excel.SetCellStyle(b.SheetName, right1Cell, right1Cell, styleRight)
+		if err != nil {
+			return err
+		}
+		b.Excel.SetCellValue(b.SheetName, right1Cell, value)
+		return nil
+	}
+
+	//第一行
+	drawLeft(row, "类别:"+b.Content.Type)
+	drawRight(row, "单号:"+b.Content.SerialNumber)
+	b.Excel.SetRowHeight(b.SheetName, row, 21)
+
+	//第二行
+	drawLeft(row+1, "供应商名称:"+b.Content.Supplier)
+	timeformat := b.Content.CreateTime.Local().Format("2006年01月02号 15:04:05")
+	drawRight(row+1, "下单时间:"+timeformat)
+	b.Excel.SetRowHeight(b.SheetName, row+1, 21)
+
+	//第三行
+	drawLeft(row+2, "产品名称:"+b.Content.ProductName)
+	status := ""
+	if b.Content.Status == "complete" {
+		status = fmt.Sprintf("已完成(%d)", b.Content.ConfirmCount)
+	}
+	if b.Content.Status == "created" {
+		status = "进行中"
+	}
+	drawRight(row+2, "状态:"+status)
+	b.Excel.SetRowHeight(b.SheetName, row+2, 21)
+
+	return nil
+}
+
+func (b *ReportProduceExcel) drawTableTitle() error {
+	row := b.Offset + 5
+
+	//A加工项目 B规格(克) 尺寸C-D 数量E 单价F-G 交货时间H 备注I
+	var drawCol = func(prefix string, value string) error {
+		left1Cell := fmt.Sprintf("%s%d", prefix, row)
+		left2Cell := fmt.Sprintf("%s%d", prefix, row+1)
+
+		err := b.Excel.MergeCell(b.SheetName, left1Cell, left2Cell)
+		if err != nil {
+			return err
+		}
+		err = b.Excel.SetCellStyle(b.SheetName, left1Cell, left2Cell, b.AlignCenterStyle)
+		if err != nil {
+			return err
+		}
+
+		return b.Excel.SetCellValue(b.SheetName, left1Cell, value)
+	}
+
+	var drawCol2 = func(prefix string, value1 string, value2 string) error {
+
+		left1Cell := fmt.Sprintf("%s%d", prefix, row)
+		left2Cell := fmt.Sprintf("%s%d", prefix, row+1)
+		err := b.Excel.SetCellStyle(b.SheetName, left1Cell, left2Cell, b.AlignCenterStyle)
+		if err != nil {
+			return err
+		}
+		b.Excel.SetCellValue(b.SheetName, left1Cell, value1)
+		b.Excel.SetCellValue(b.SheetName, left2Cell, value2)
+		return nil
+	}
+
+	drawCol("A", "加工项目")
+	drawCol("B", "规格")
+	drawCol("C", "纸张")
+	drawCol("D", "来纸尺寸")
+	drawCol("E", "印刷尺寸")
+	drawCol("F", "数量")
+	drawCol("G", "完成数量")
+	drawCol2("H", "单价", "元/张")
+	drawCol("I", "预算金额")
+	drawCol("J", "实际金额")
+	drawCol("K", "交货时间")
+	drawCol("L", "备注")
+
+	return nil
+}
+
+func (b *ReportProduceExcel) drawTableContent() error {
+	row := b.Offset + 7
+	b.Row = row
+	var DrawRow = func(rowIndex int, values ...string) {
+		charas := []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"}
+		for i, c := range charas {
+			v := ""
+			if i < len(values) {
+				v = values[i]
+			}
+			b.Excel.SetCellValue(b.SheetName, fmt.Sprintf("%s%d", c, rowIndex), v)
+			val2Cel := fmt.Sprintf("%s%d", c, rowIndex)
+			b.Excel.SetCellStyle(b.SheetName, val2Cel, val2Cel, b.AlignCenterStyle)
+
+			b.Excel.SetRowHeight(b.SheetName, rowIndex, 21)
+		}
+	}
+
+	produces := b.Content.Produces
+	if len(produces) > 0 {
+		for _, produce := range produces {
+
+			confirmCount := "-"
+			realAmount := "-"
+			price, err := strconv.ParseFloat(produce.Price, 64)
+			if err != nil {
+				price = 0.00
+			}
+
+			// 预算金额
+			budgetAmount := fmt.Sprintf("%.2f", float64(produce.Count)*price)
+			b.FormatToEmpty(&budgetAmount)
+
+			b.BudgetCount += float64(produce.Count) * price
+
+			// 实际完成数
+			confirmCount = fmt.Sprintf("%d", b.Content.ConfirmCount)
+			b.FormatToEmpty(&confirmCount)
+
+			// 实际金额
+			realAmount = fmt.Sprintf("%.2f", float64(b.Content.ConfirmCount)*price)
+			b.FormatToEmpty(&realAmount)
+
+			b.RealCount += float64(b.Content.ConfirmCount) * price
+
+			deliveryTime := produce.DeliveryTime.Local().Format("2006-01-02")
+			DrawRow(row, produce.Name, produce.Norm, produce.Paper, produce.PaperSize, produce.PrintSize, fmt.Sprintf("%d", produce.Count), confirmCount, produce.Price, budgetAmount, realAmount, deliveryTime, produce.Remark)
+			row++
+			b.Row++
+		}
+	}
+
+	return nil
+}
+
+func (b *ReportProduceExcel) Draws() {
+	b.drawTitle()
+	b.drawSubTitles()
+	b.drawTableTitle()
+	b.drawTableContent()
+}
+
+func (b *ReportProduceExcel) Count() {
+	row := b.Row + 1
+
+	startCell := fmt.Sprintf("%s%d", "A", row)
+	endCell := fmt.Sprintf("%s%d", "H", row)
+	b.Excel.MergeCell(b.SheetName, startCell, endCell)
+	b.Excel.SetCellStyle(b.SheetName, startCell, endCell, b.AlignCenterStyle)
+	b.Excel.SetCellValue(b.SheetName, startCell, "汇总金额")
+
+	// 预算金额汇总
+	budgetCountCell := fmt.Sprintf("%s%d", "I", row)
+	b.Excel.SetCellValue(b.SheetName, budgetCountCell, b.BudgetCount)
+	b.Excel.SetCellStyle(b.SheetName, budgetCountCell, budgetCountCell, b.AlignCenterStyle)
+
+	// 实际金额汇总
+	RealCountCell := fmt.Sprintf("%s%d", "J", row)
+	b.Excel.SetCellValue(b.SheetName, RealCountCell, b.RealCount)
+	b.Excel.SetCellStyle(b.SheetName, RealCountCell, RealCountCell, b.AlignCenterStyle)
+
+	b.Excel.SetRowHeight(b.SheetName, row, 21)
+
+}
+
+func NewReportProduceExcel(f *excelize.File) *ReportProduceExcel {
+
+	border := []excelize.Border{
+		{Type: "top", Style: 1, Color: "000000"},
+		{Type: "left", Style: 1, Color: "000000"},
+		{Type: "right", Style: 1, Color: "000000"},
+		{Type: "bottom", Style: 1, Color: "000000"},
+	}
+
+	styleLeft, _ := f.NewStyle(&excelize.Style{
+		Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
+		Border:    border,
+	})
+
+	b := &ReportProduceExcel{
+		Title:            "中鱼互动加工单",
+		SheetName:        "Sheet1",
+		Excel:            f,
+		Offset:           0,
+		AlignCenterStyle: styleLeft,
+	}
+	f.SetColWidth(b.SheetName, "A", "A", 12)
+	f.SetColWidth(b.SheetName, "B", "K", 9.5)
+	f.SetColWidth(b.SheetName, "L", "L", 10)
+	f.SetPageMargins(b.SheetName, excelize.PageMarginTop(0), excelize.PageMarginLeft(0), excelize.PageMarginRight(0))
+
+	return b
+}
+
+func (b *ReportProduceExcel) FormatToEmpty(str *string) {
+	if *str == "0" || *str == "0.00" {
+		*str = ""
+	}
+}

+ 306 - 0
boxcost/api/report-purchase-excel.go

@@ -0,0 +1,306 @@
+package api
+
+import (
+	"box-cost/db/model"
+	"fmt"
+	"strconv"
+
+	_ "image/gif"
+	_ "image/jpeg"
+	_ "image/png"
+
+	"github.com/xuri/excelize/v2"
+)
+
+type ReportPurchaseExcel struct {
+	Offset int
+	Row    int
+
+	Title string //标题
+
+	Excel *excelize.File
+
+	SheetName string
+
+	AlignCenterStyle int
+
+	Content *model.PurchaseBill
+
+	BudgetCount float64
+	RealCount   float64
+}
+
+func (b *ReportPurchaseExcel) drawTitle() error {
+	marginLeft := excelize.PageMarginLeft(0.15)
+	b.Excel.SetPageMargins(b.SheetName, marginLeft)
+	tileIndex := b.Offset + 1
+	startCell := fmt.Sprintf("A%d", tileIndex)
+	err := b.Excel.MergeCell(b.SheetName, startCell, fmt.Sprintf("L%d", tileIndex))
+	if err != nil {
+		return err
+	}
+
+	style, err := b.Excel.NewStyle(&excelize.Style{
+		Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
+		Font:      &excelize.Font{Bold: true, Size: 18}})
+	if err != nil {
+		return err
+	}
+	err = b.Excel.SetCellStyle(b.SheetName, startCell, startCell, style)
+	if err != nil {
+		return err
+	}
+	b.Excel.SetRowHeight(b.SheetName, tileIndex, 23)
+	b.Excel.SetCellValue(b.SheetName, startCell, b.Title)
+	return nil
+}
+
+func (b *ReportPurchaseExcel) drawSubTitles() error {
+
+	row := b.Offset + 2
+
+	styleLeft, err := b.Excel.NewStyle(&excelize.Style{
+		Alignment: &excelize.Alignment{Horizontal: "left", Vertical: "center"},
+		Font:      &excelize.Font{Size: 11}})
+	if err != nil {
+		return err
+	}
+	styleRight, err := b.Excel.NewStyle(&excelize.Style{
+		Alignment: &excelize.Alignment{Horizontal: "right", Vertical: "center"},
+		Font:      &excelize.Font{Size: 11}})
+	if err != nil {
+		return err
+	}
+
+	var drawLeft = func(rowIndex int, value string) error {
+		//左边1
+		left1Cell := fmt.Sprintf("A%d", rowIndex)
+		err = b.Excel.MergeCell(b.SheetName, left1Cell, fmt.Sprintf("E%d", rowIndex))
+		if err != nil {
+			return err
+		}
+		err = b.Excel.SetCellStyle(b.SheetName, left1Cell, left1Cell, styleLeft)
+		if err != nil {
+			return err
+		}
+		b.Excel.SetCellValue(b.SheetName, left1Cell, value)
+		return nil
+	}
+
+	var drawRight = func(rowIndex int, value string) error {
+		right1Cell := fmt.Sprintf("F%d", rowIndex)
+		err = b.Excel.MergeCell(b.SheetName, right1Cell, fmt.Sprintf("L%d", rowIndex))
+		if err != nil {
+			return err
+		}
+		err = b.Excel.SetCellStyle(b.SheetName, right1Cell, right1Cell, styleRight)
+		if err != nil {
+			return err
+		}
+		b.Excel.SetCellValue(b.SheetName, right1Cell, value)
+		return nil
+	}
+	//第一行
+	drawLeft(row, "类别:"+b.Content.Type)
+	drawRight(row, "单号:"+b.Content.SerialNumber)
+	b.Excel.SetRowHeight(b.SheetName, row, 21)
+
+	//第二行
+	drawLeft(row+1, "供应商名称:"+b.Content.Supplier)
+	timeformat := b.Content.CreateTime.Local().Format("2006年01月02号 15:04:05")
+	drawRight(row+1, "下单时间:"+timeformat)
+	b.Excel.SetRowHeight(b.SheetName, row+1, 21)
+
+	//第三行
+	drawLeft(row+2, "产品名称:"+b.Content.ProductName)
+	status := ""
+	if b.Content.Status == "complete" {
+		status = fmt.Sprintf("已完成(%d)", b.Content.ConfirmCount)
+	}
+	if b.Content.Status == "created" {
+		status = "进行中"
+	}
+	drawRight(row+2, "状态:"+status)
+	b.Excel.SetRowHeight(b.SheetName, row+2, 21)
+
+	return nil
+}
+
+func (b *ReportPurchaseExcel) drawTableTitle() error {
+	row := b.Offset + 5
+	//A采购项目 B规格(克) 尺寸C-D 数量E 单价F-G 交货时间H 备注I
+	var drawCol = func(prefix string, value string) error {
+		left1Cell := fmt.Sprintf("%s%d", prefix, row)
+		left2Cell := fmt.Sprintf("%s%d", prefix, row+1)
+
+		err := b.Excel.MergeCell(b.SheetName, left1Cell, left2Cell)
+		if err != nil {
+			return err
+		}
+		err = b.Excel.SetCellStyle(b.SheetName, left1Cell, left2Cell, b.AlignCenterStyle)
+		if err != nil {
+			return err
+		}
+
+		return b.Excel.SetCellValue(b.SheetName, left1Cell, value)
+	}
+
+	var drawCol2 = func(prefix1 string, prefix2 string, value1 string, value2 string, value3 string) error {
+		left1Cell := fmt.Sprintf("%s%d", prefix1, row)
+		left2Cell := fmt.Sprintf("%s%d", prefix2, row)
+		err := b.Excel.MergeCell(b.SheetName, left1Cell, left2Cell)
+		if err != nil {
+			return err
+		}
+		if err != nil {
+			fmt.Println(err)
+			return err
+		}
+		err = b.Excel.SetCellStyle(b.SheetName, left1Cell, left2Cell, b.AlignCenterStyle)
+		if err != nil {
+			return err
+		}
+		b.Excel.SetCellValue(b.SheetName, left1Cell, value1)
+
+		val2Cel := fmt.Sprintf("%s%d", prefix1, row+1)
+		b.Excel.SetCellStyle(b.SheetName, val2Cel, val2Cel, b.AlignCenterStyle)
+		b.Excel.SetCellValue(b.SheetName, val2Cel, value2)
+
+		val3Cel := fmt.Sprintf("%s%d", prefix2, row+1)
+		b.Excel.SetCellStyle(b.SheetName, val3Cel, val3Cel, b.AlignCenterStyle)
+		b.Excel.SetCellValue(b.SheetName, val3Cel, value3)
+		return nil
+	}
+
+	drawCol("A", "采购项目")
+	drawCol("B", "规格(克)")
+
+	drawCol("E", "数量")
+	drawCol("F", "完成数量")
+
+	drawCol2("C", "D", "尺寸(mm)", "长", "宽")
+	drawCol2("C", "D", "尺寸(mm)", "长", "宽")
+	unit1 := "-"
+	unit2 := "-"
+	// ??? for ragne
+	if len(b.Content.Paper) > 0 {
+		if b.Content.Paper[0].PriceUnit != "" {
+			unit1 = b.Content.Paper[0].PriceUnit
+		} else if b.Content.Paper[0].Price2Unit != "" {
+			unit2 = b.Content.Paper[0].Price2Unit
+		} else {
+			unit1 = "元/张"
+			unit2 = "元/吨"
+		}
+		if b.Content.Paper[0].PriceUnit != "" && b.Content.Paper[0].Price2Unit != "" {
+			unit1 = b.Content.Paper[0].PriceUnit
+			unit2 = b.Content.Paper[0].Price2Unit
+		}
+	}
+
+	drawCol2("G", "H", "单价", unit1, unit2)
+	drawCol("I", "预算金额")
+	drawCol("J", "实际金额")
+	drawCol("K", "交货时间")
+	drawCol("L", "备注")
+
+	return nil
+}
+
+func (b *ReportPurchaseExcel) drawTableContent() error {
+	row := b.Offset + 7
+	b.Row = row
+
+	var DrawRow = func(rowIndex int, values ...string) {
+		charas := []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"}
+		for i, c := range charas {
+			v := ""
+			if i < len(values) {
+				v = values[i]
+			}
+			b.Excel.SetCellValue(b.SheetName, fmt.Sprintf("%s%d", c, rowIndex), v)
+			val2Cel := fmt.Sprintf("%s%d", c, rowIndex)
+			b.Excel.SetCellStyle(b.SheetName, val2Cel, val2Cel, b.AlignCenterStyle)
+
+			b.Excel.SetRowHeight(b.SheetName, rowIndex, 21)
+		}
+	}
+	papers := b.Content.Paper
+	if len(papers) > 0 {
+		for _, paper := range papers {
+			deliveryTime := paper.DeliveryTime.Local().Format("2006-01-02")
+
+			confirmCount := "-"
+			realAmount := "-"
+			price, err := strconv.ParseFloat(paper.Price, 64)
+			if err != nil {
+				price = 0.00
+			}
+
+			// 预算金额
+			budgetAmount := fmt.Sprintf("%.2f", float64(paper.Count)*price)
+			b.FormatToEmpty(&budgetAmount)
+			b.BudgetCount += float64(paper.Count) * price
+
+			// 实际完成数
+			confirmCount = fmt.Sprintf("%d", b.Content.ConfirmCount)
+			b.FormatToEmpty(&confirmCount)
+
+			// 实际金额
+			realAmount = fmt.Sprintf("%.2f", float64(b.Content.ConfirmCount)*price)
+			b.FormatToEmpty(&realAmount)
+			b.RealCount += float64(b.Content.ConfirmCount) * price
+
+			DrawRow(row, paper.Name, paper.Norm, paper.Height, paper.Width, fmt.Sprintf("%d", paper.Count), confirmCount, paper.Price, paper.Price2, budgetAmount, realAmount, deliveryTime, paper.Remark)
+			row++
+			b.Row++
+		}
+	}
+
+	return nil
+}
+
+func (b *ReportPurchaseExcel) Draws() {
+	b.drawTitle()
+	b.drawSubTitles()
+	b.drawTableTitle()
+	b.drawTableContent()
+
+}
+
+func NewReportPurchaseExcel(f *excelize.File) *ReportPurchaseExcel {
+
+	border := []excelize.Border{
+		{Type: "top", Style: 1, Color: "000000"},
+		{Type: "left", Style: 1, Color: "000000"},
+		{Type: "right", Style: 1, Color: "000000"},
+		{Type: "bottom", Style: 1, Color: "000000"},
+	}
+
+	styleLeft, _ := f.NewStyle(&excelize.Style{
+		Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
+		Border:    border,
+		Font:      &excelize.Font{Size: 10},
+	})
+
+	b := &ReportPurchaseExcel{
+		Title:            "原材料采购单",
+		SheetName:        "Sheet1",
+		Excel:            f,
+		Offset:           0,
+		AlignCenterStyle: styleLeft,
+	}
+
+	f.SetColWidth(b.SheetName, "A", "A", 12)
+	f.SetColWidth(b.SheetName, "B", "K", 9.5)
+	f.SetColWidth(b.SheetName, "L", "L", 10)
+	f.SetPageMargins(b.SheetName, excelize.PageMarginTop(0), excelize.PageMarginLeft(0), excelize.PageMarginRight(0))
+	return b
+}
+
+func (b *ReportPurchaseExcel) FormatToEmpty(str *string) {
+	if *str == "0" || *str == "0.00" {
+		*str = ""
+	}
+
+}

+ 452 - 170
boxcost/api/report.go

@@ -3,12 +3,10 @@ package api
 import (
 	"box-cost/db/model"
 	"box-cost/db/repo"
-	"box-cost/log"
 	"errors"
 	"fmt"
 
 	"github.com/gin-gonic/gin"
-	"github.com/go-redis/redis/v8"
 	"github.com/xuri/excelize/v2"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/bson/primitive"
@@ -16,20 +14,25 @@ import (
 
 // 统计报表
 func Report(r *GinRouter) {
-	r.POST("/report/list", ReportList)
-	r.POST("/report/download", ReportDownload)
+	// 加工列表
+	r.POST("/report/produce/list", ReportProduceList)
+	// 采购列表
+	r.POST("/report/purchase/list", ReportPurchaseList)
+	r.POST("/report/produce/download", ReportProduceDownload)
+	r.POST("/report/purchase/download", ReportPurchaseDownload)
 }
 
 type ReportListReq struct {
-	Supplier  string
-	TimeRange []string
-	PackIds   []primitive.ObjectID
-	PlanIds   []primitive.ObjectID
-	Page      int64
-	Size      int64
+	SupplierId primitive.ObjectID
+	TimeRange  []string
+	PackIds    []primitive.ObjectID
+	PlanIds    []primitive.ObjectID
+	Page       int64
+	Size       int64
 }
 
-func ReportList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
+// 加工单
+func ReportProduceList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	// 财务管理】 添加统计报表功能。按 时间范围, 供应商(单选)   包装(多选) 计划(多选) 四个维度进行过滤,形成报表。可以下载
 	var form ReportListReq
 	err := c.ShouldBindJSON(&form)
@@ -41,27 +44,22 @@ func ReportList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	var size int64 = 10
 	if form.Page > 0 {
 		page = form.Page
-	} else {
-		page = 1
 	}
 	if form.Size > 0 {
 		size = form.Size
-	} else {
-		size = 10
 	}
-	start := (page - 1) * size
-	end := page*size - 1
 
 	// 条件处理
 	query := make(map[string]interface{}, 0)
-	if form.Supplier != "" {
-		query["supplier"] = form.Supplier
+	query["status"] = "complete"
+	if !form.SupplierId.IsZero() {
+		query["supplierId"] = form.SupplierId
 	}
 
 	// 时间范围
 	if len(form.TimeRange) == 2 {
 		start, end := getTimeRange(form.TimeRange[0], form.TimeRange[1])
-		query["createTime"] = bson.M{"$gte": start, "$lte": end}
+		query["updateTime"] = bson.M{"$gte": start, "$lte": end}
 	}
 
 	// 包装
@@ -83,185 +81,469 @@ func ReportList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	}
 
 	// 获取采购单符合条件的信息
-	purchases := []model.PurchaseBill{}
-	repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
+	return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
 		CollectName: repo.CollectionBillPurchase,
 		Query:       query,
-	}, &purchases)
+		Page:        page,
+		Size:        size,
+	})
 
-	// 获取加工单符合条件的信息
-	produces := []model.ProduceBill{}
-	repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
-		CollectName: repo.CollectionBillProduce,
-		Query:       query,
-	}, &produces)
-	// 组装数据
-	cacheKey := "report:list"
-	apictx.Svc.Redis.Del(apictx.CreateRepoCtx().Ctx, cacheKey)
-	// key存在时
-	// if apictx.Svc.Redis.Exists(apictx.CreateRepoCtx().Ctx, cacheKey).Val() == 1 {
-	// 	ret := apictx.Svc.Redis.ZRange(apictx.CreateRepoCtx().Ctx, cacheKey, start, end)
-	// 	retList = ret.Val()
-	// } else {
-
-	// }
-
-	mlen := len(purchases) + len(produces)
-	type MapList map[string]interface{}
-	lists := make([]MapList, mlen)
-	if len(purchases) > 0 {
-		for _, purchase := range purchases {
-			apictx.Svc.Redis.ZAdd(apictx.CreateRepoCtx().Ctx, cacheKey, &redis.Z{
-				Score:  float64(purchase.CreateTime.Unix()),
-				Member: purchase.Id.Hex(),
-			})
-			list := MapList{purchase.Id.Hex(): purchase, "type": "purchase"}
-			lists = append(lists, list)
-		}
+}
+
+// 采购单
+func ReportPurchaseList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
+	// 财务管理】 添加统计报表功能。按 时间范围, 供应商(单选)   包装(多选) 计划(多选) 四个维度进行过滤,形成报表。可以下载
+	var form ReportListReq
+	err := c.ShouldBindJSON(&form)
+	if err != nil {
+		return nil, errors.New("参数错误")
+	}
+
+	var page int64 = 1
+	var size int64 = 10
+	if form.Page > 0 {
+		page = form.Page
 	}
-	if len(produces) > 0 {
-		for _, produce := range produces {
-			apictx.Svc.Redis.ZAdd(apictx.CreateRepoCtx().Ctx, cacheKey, &redis.Z{
-				Score:  float64(produce.CreateTime.Unix()),
-				Member: produce.Id.Hex(),
-			})
-			list := MapList{produce.Id.Hex(): produce, "type": "produce"}
-			lists = append(lists, list)
+	if form.Size > 0 {
+		size = form.Size
+	}
+
+	// 条件处理
+	query := make(map[string]interface{}, 0)
+	query["status"] = "complete"
+	if !form.SupplierId.IsZero() {
+		query["supplierId"] = form.SupplierId
+	}
+
+	// 时间范围
+	if len(form.TimeRange) == 2 {
+		start, end := getTimeRange(form.TimeRange[0], form.TimeRange[1])
+		query["updateTime"] = bson.M{"$gte": start, "$lte": end}
+	}
+
+	// 包装
+	if len(form.PackIds) > 0 {
+		packQuery := []bson.M{}
+		for _, packId := range form.PackIds {
+			packQuery = append(packQuery, bson.M{"packId": packId})
 		}
+		query["$or"] = packQuery
 	}
-	// 当前key存在时
-	retList := make([]map[string]interface{}, 0)
-	// 所有id
-	ids := make([]map[string]string, 0)
-	if apictx.Svc.Redis.Exists(apictx.CreateRepoCtx().Ctx, cacheKey).Val() == 1 {
-		// ret := apictx.Svc.Redis.ExpireLT(apictx.CreateRepoCtx().Ctx, cacheKey, 20*time.Second)
-		// 按创建时间升序排
-		result := apictx.Svc.Redis.ZRange(apictx.CreateRepoCtx().Ctx, cacheKey, start, end)
-		if result.Err() != nil {
-			log.Error(err)
-			return nil, errors.New("缓存数据内部错误")
+
+	// 计划
+	if len(form.PlanIds) > 0 {
+		planQuery := bson.A{}
+		for _, planId := range form.PlanIds {
+			planQuery = append(planQuery, bson.M{"planId": planId})
 		}
-		retids := apictx.Svc.Redis.ZRange(apictx.CreateRepoCtx().Ctx, cacheKey, 0, -1)
-
-		// 所有id
-		if len(retids.Val()) > 0 {
-			for _, id := range retids.Val() {
-				for _, item := range lists {
-					if _, ok := item[id]; ok {
-						ids = append(ids, map[string]string{"id": id, "type": item["type"].(string)})
-					}
-				}
-			}
+		query["$or"] = planQuery
+	}
+
+	// 获取采购单符合条件的信息
+	return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
+		CollectName: repo.CollectionBillPurchase,
+		Query:       query,
+		Page:        page,
+		Size:        size,
+	})
+
+}
+
+// func ReportProduceList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
+// 	// 财务管理】 添加统计报表功能。按 时间范围, 供应商(单选)   包装(多选) 计划(多选) 四个维度进行过滤,形成报表。可以下载
+// 	var form ReportListReq
+// 	err := c.ShouldBindJSON(&form)
+// 	if err != nil {
+// 		return nil, errors.New("参数错误")
+// 	}
+
+// 	var page int64 = 1
+// 	var size int64 = 10
+// 	if form.Page > 0 {
+// 		page = form.Page
+// 	} else {
+// 		page = 1
+// 	}
+// 	if form.Size > 0 {
+// 		size = form.Size
+// 	} else {
+// 		size = 10
+// 	}
+// 	start := (page - 1) * size
+// 	end := page*size - 1
+
+// 	// 条件处理
+// 	query := make(map[string]interface{}, 0)
+// 	query["status"] = "complete"
+// 	if !form.SupplierId.IsZero() {
+// 		query["supplierId"] = form.SupplierId
+// 	}
+
+// 	// 时间范围
+// 	if len(form.TimeRange) == 2 {
+// 		start, end := getTimeRange(form.TimeRange[0], form.TimeRange[1])
+// 		query["createTime"] = bson.M{"$gte": start, "$lte": end}
+// 	}
+
+// 	// 包装
+// 	if len(form.PackIds) > 0 {
+// 		packQuery := []bson.M{}
+// 		for _, packId := range form.PackIds {
+// 			packQuery = append(packQuery, bson.M{"packId": packId})
+// 		}
+// 		query["$or"] = packQuery
+// 	}
+
+// 	// 计划
+// 	if len(form.PlanIds) > 0 {
+// 		planQuery := bson.A{}
+// 		for _, planId := range form.PlanIds {
+// 			planQuery = append(planQuery, bson.M{"planId": planId})
+// 		}
+// 		query["$or"] = planQuery
+// 	}
+
+// 	// 获取采购单符合条件的信息
+// 	purchases := []model.PurchaseBill{}
+// 	repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
+// 		CollectName: repo.CollectionBillPurchase,
+// 		Query:       query,
+// 	}, &purchases)
+
+// 	// 获取加工单符合条件的信息
+// 	produces := []model.ProduceBill{}
+// 	repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
+// 		CollectName: repo.CollectionBillProduce,
+// 		Query:       query,
+// 	}, &produces)
+// 	// 组装数据
+// 	cacheKey := "report:list"
+// 	apictx.Svc.Redis.Del(apictx.CreateRepoCtx().Ctx, cacheKey)
+// 	// key存在时
+// 	// if apictx.Svc.Redis.Exists(apictx.CreateRepoCtx().Ctx, cacheKey).Val() == 1 {
+// 	// 	ret := apictx.Svc.Redis.ZRange(apictx.CreateRepoCtx().Ctx, cacheKey, start, end)
+// 	// 	retList = ret.Val()
+// 	// } else {
+
+// 	// }
+
+// 	mlen := len(purchases) + len(produces)
+// 	type MapList map[string]interface{}
+// 	lists := make([]MapList, mlen)
+// 	if len(purchases) > 0 {
+// 		for _, purchase := range purchases {
+// 			apictx.Svc.Redis.ZAdd(apictx.CreateRepoCtx().Ctx, cacheKey, &redis.Z{
+// 				Score:  float64(purchase.CreateTime.Unix()),
+// 				Member: purchase.Id.Hex(),
+// 			})
+// 			list := MapList{purchase.Id.Hex(): purchase, "type": "purchase"}
+// 			lists = append(lists, list)
+// 		}
+// 	}
+// 	if len(produces) > 0 {
+// 		for _, produce := range produces {
+// 			apictx.Svc.Redis.ZAdd(apictx.CreateRepoCtx().Ctx, cacheKey, &redis.Z{
+// 				Score:  float64(produce.CreateTime.Unix()),
+// 				Member: produce.Id.Hex(),
+// 			})
+// 			list := MapList{produce.Id.Hex(): produce, "type": "produce"}
+// 			lists = append(lists, list)
+// 		}
+// 	}
+// 	// 当前key存在时
+// 	retList := make([]map[string]interface{}, 0)
+// 	// 所有id
+// 	ids := make([]map[string]string, 0)
+// 	if apictx.Svc.Redis.Exists(apictx.CreateRepoCtx().Ctx, cacheKey).Val() == 1 {
+// 		// ret := apictx.Svc.Redis.ExpireLT(apictx.CreateRepoCtx().Ctx, cacheKey, 20*time.Second)
+// 		// 按创建时间升序排
+// 		result := apictx.Svc.Redis.ZRange(apictx.CreateRepoCtx().Ctx, cacheKey, start, end)
+// 		if result.Err() != nil {
+// 			log.Error(err)
+// 			return nil, errors.New("缓存数据内部错误")
+// 		}
+// 		retids := apictx.Svc.Redis.ZRange(apictx.CreateRepoCtx().Ctx, cacheKey, 0, -1)
+
+// 		// 所有id
+// 		if len(retids.Val()) > 0 {
+// 			for _, id := range retids.Val() {
+// 				for _, item := range lists {
+// 					if _, ok := item[id]; ok {
+// 						ids = append(ids, map[string]string{"id": id, "type": item["type"].(string)})
+// 					}
+// 				}
+// 			}
+
+// 		}
+
+// 		// 返回的列表
+// 		if len(result.Val()) > 0 {
+// 			for _, id := range result.Val() {
+// 				for _, item := range lists {
+// 					if _, ok := item[id]; ok {
+// 						retList = append(retList, item)
+// 					}
+// 				}
+// 			}
+// 		}
+
+// 	}
+// 	type PageResult struct {
+// 		List  []map[string]interface{} `json:"list"`
+// 		Total int64                    `json:"total"`
+// 		Page  int64                    `json:"page"`
+// 		Size  int64                    `json:"size"`
+// 		Ids   []map[string]string      `json:"ids"`
+// 	}
+
+// 	out := &PageResult{
+// 		List:  retList,
+// 		Total: int64(mlen),
+// 		Page:  page,
+// 		Size:  size,
+// 		Ids:   ids,
+// 	}
+
+// 	return out, nil
+
+// }
+
+func ReportProduceDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
+	var form ReportListReq
+	err := c.ShouldBindJSON(&form)
+	if err != nil {
+		return nil, errors.New("参数错误")
+	}
+	// 条件处理
+	query := make(map[string]interface{}, 0)
+	query["status"] = "complete"
+	if !form.SupplierId.IsZero() {
+		query["supplierId"] = form.SupplierId
+	}
+
+	// 时间范围
+	if len(form.TimeRange) == 2 {
+		start, end := getTimeRange(form.TimeRange[0], form.TimeRange[1])
+		query["updateTime"] = bson.M{"$gte": start, "$lte": end}
+	}
 
+	// 包装
+	if len(form.PackIds) > 0 {
+		packQuery := []bson.M{}
+		for _, packId := range form.PackIds {
+			packQuery = append(packQuery, bson.M{"packId": packId})
 		}
+		query["$or"] = packQuery
+	}
 
-		// 返回的列表
-		if len(result.Val()) > 0 {
-			for _, id := range result.Val() {
-				for _, item := range lists {
-					if _, ok := item[id]; ok {
-						retList = append(retList, item)
-					}
-				}
-			}
+	// 计划
+	if len(form.PlanIds) > 0 {
+		planQuery := bson.A{}
+		for _, planId := range form.PlanIds {
+			planQuery = append(planQuery, bson.M{"planId": planId})
 		}
+		query["$or"] = planQuery
+	}
 
+	// 获取采符合条件的信息
+	produces := []model.ProduceBill{}
+	err = repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
+		CollectName: repo.CollectionBillProduce,
+		Query:       query,
+	}, &produces)
+	if err != nil || len(produces) < 1 {
+		return nil, errors.New("数据不存在")
 	}
-	type PageResult struct {
-		List  []map[string]interface{} `json:"list"`
-		Total int64                    `json:"total"`
-		Page  int64                    `json:"page"`
-		Size  int64                    `json:"size"`
-		Ids   []map[string]string      `json:"ids"`
+	f := excelize.NewFile()
+	index := f.NewSheet("Sheet1")
+	sheetName := f.GetSheetName(index)
+	f.SetActiveSheet(index)
+	f.SetDefaultFont("宋体")
+
+	border := []excelize.Border{
+		{Type: "top", Style: 1, Color: "000000"},
+		{Type: "left", Style: 1, Color: "000000"},
+		{Type: "right", Style: 1, Color: "000000"},
+		{Type: "bottom", Style: 1, Color: "000000"},
 	}
+	alignCenterStyle, _ := f.NewStyle(&excelize.Style{
+		Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
+		Border:    border,
+	})
+	offset := 0
+	info := model.Setting{}
+	repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
+		CollectName: "infos",
+	}, &info)
+
+	var budgetCount float64 = 0
+	var realCount float64 = 0
 
-	out := &PageResult{
-		List:  retList,
-		Total: int64(mlen),
-		Page:  page,
-		Size:  size,
-		Ids:   ids,
+	for _, produce := range produces {
+		produceExcel := NewReportProduceExcel(f)
+		produceExcel.Content = &produce
+		budgetCount += produceExcel.BudgetCount
+		realCount += produceExcel.RealCount
+		produceExcel.Title = fmt.Sprintf("%ss加工单", info.CompanyName)
+		//设置对应的数据
+		produceExcel.Offset = offset
+		produceExcel.Draws()
+		offset += 15
 	}
+	row := offset + 1
+	startCell := fmt.Sprintf("%s%d", "A", row)
+	endCell := fmt.Sprintf("%s%d", "H", row)
+	f.MergeCell(sheetName, startCell, endCell)
+	f.SetCellStyle(sheetName, startCell, endCell, alignCenterStyle)
+	f.SetCellValue(sheetName, startCell, "汇总金额")
 
-	return out, nil
+	// 预算金额汇总
+	budgetCountCell := fmt.Sprintf("%s%d", "I", row)
+	budgetCountStr := ""
+	if realCount > 0 {
+		budgetCountStr = fmt.Sprintf("%.2f", budgetCount)
+	}
+	f.SetCellValue(sheetName, budgetCountCell, budgetCountStr)
+	f.SetCellStyle(sheetName, budgetCountCell, budgetCountCell, alignCenterStyle)
 
-}
+	// 实际金额汇总
+	RealCountCell := fmt.Sprintf("%s%d", "J", row)
 
-type ReportDownloadReq struct {
-	Id   string
-	Type string
+	realCountStr := ""
+	if realCount > 0 {
+		realCountStr = fmt.Sprintf("%.2f", realCount)
+	}
+	f.SetCellValue(sheetName, RealCountCell, realCountStr)
+	f.SetCellStyle(sheetName, RealCountCell, RealCountCell, alignCenterStyle)
+
+	f.SetRowHeight(sheetName, row, 21)
+
+	c.Header("Content-Type", "application/octet-stream")
+	c.Header("Content-Disposition", "attachment; filename="+"reportProduce.xlsx")
+	c.Header("Content-Transfer-Encoding", "binary")
+	err = f.Write(c.Writer)
+	if err != nil {
+		return nil, err
+	}
+	return nil, nil
 }
 
-func ReportDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
-	var form []ReportDownloadReq
+func ReportPurchaseDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
+	var form ReportListReq
 	err := c.ShouldBindJSON(&form)
 	if err != nil {
 		return nil, errors.New("参数错误")
 	}
+	// 条件处理
+	query := make(map[string]interface{}, 0)
+	query["status"] = "complete"
+	if !form.SupplierId.IsZero() {
+		query["supplierId"] = form.SupplierId
+	}
 
-	if len(form) > 0 {
-		info := model.Setting{}
-		repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
-			CollectName: "infos",
-		}, &info)
-		f := excelize.NewFile()
-		// Create a new sheet.
-		index := f.NewSheet("Sheet1")
-		f.SetActiveSheet(index)
-		f.SetDefaultFont("宋体")
-		offset := 0
-		for _, req := range form {
-			// 是采购单
-			if req.Type == "purchase" {
-				purchaseId, err := primitive.ObjectIDFromHex(req.Id)
-				if err == nil {
-					purchase := model.PurchaseBill{}
-					found, _ := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
-						CollectName: repo.CollectionBillPurchase,
-						Query:       repo.Map{"_id": purchaseId},
-					}, &purchase)
-					if found {
-						purchaseExcel := NewPurchaseBill(f)
-						purchaseExcel.Content = &purchase
-						purchaseExcel.Title = fmt.Sprintf("%s原材料采购单", info.CompanyName)
-						//设置对应的数据
-						purchaseExcel.Offset = offset
-						purchaseExcel.Draws()
-						offset += 15
-					}
-				}
-			}
-			// 是加工单
-			if req.Type == "produce" {
-				produceId, err := primitive.ObjectIDFromHex(req.Id)
-				if err == nil {
-					produce := model.ProduceBill{}
-					found, _ := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
-						CollectName: repo.CollectionBillProduce,
-						Query:       repo.Map{"_id": produceId},
-					}, &produce)
-					if found {
-						produceExcel := NewProduceBill(f)
-						produceExcel.Content = &produce
-						produceExcel.Title = fmt.Sprintf("%s加工单", info.CompanyName)
-						//设置对应的数据
-						produceExcel.Offset = offset
-						produceExcel.Draws()
-						offset += 15
-					}
-
-				}
-
-			}
+	// 时间范围
+	if len(form.TimeRange) == 2 {
+		start, end := getTimeRange(form.TimeRange[0], form.TimeRange[1])
+		query["updateTime"] = bson.M{"$gte": start, "$lte": end}
+	}
+
+	// 包装
+	if len(form.PackIds) > 0 {
+		packQuery := []bson.M{}
+		for _, packId := range form.PackIds {
+			packQuery = append(packQuery, bson.M{"packId": packId})
 		}
-		c.Header("Content-Type", "application/octet-stream")
-		c.Header("Content-Disposition", "attachment; filename="+"report.xlsx")
-		c.Header("Content-Transfer-Encoding", "binary")
-		err = f.Write(c.Writer)
-		if err != nil {
-			return nil, err
+		query["$or"] = packQuery
+	}
+
+	// 计划
+	if len(form.PlanIds) > 0 {
+		planQuery := bson.A{}
+		for _, planId := range form.PlanIds {
+			planQuery = append(planQuery, bson.M{"planId": planId})
 		}
+		query["$or"] = planQuery
+	}
+
+	// 获取符合条件的信息
+	purchases := []model.PurchaseBill{}
+	err = repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
+		CollectName: repo.CollectionBillPurchase,
+		Query:       query,
+	}, &purchases)
+	if err != nil || len(purchases) < 1 {
+		return nil, errors.New("数据不存在")
+	}
+	f := excelize.NewFile()
+	index := f.NewSheet("Sheet1")
+	sheetName := f.GetSheetName(index)
+	f.SetActiveSheet(index)
+	f.SetDefaultFont("宋体")
+
+	border := []excelize.Border{
+		{Type: "top", Style: 1, Color: "000000"},
+		{Type: "left", Style: 1, Color: "000000"},
+		{Type: "right", Style: 1, Color: "000000"},
+		{Type: "bottom", Style: 1, Color: "000000"},
+	}
+	alignCenterStyle, _ := f.NewStyle(&excelize.Style{
+		Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center"},
+		Border:    border,
+	})
+	offset := 0
+	info := model.Setting{}
+	repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
+		CollectName: "infos",
+	}, &info)
+
+	var budgetCount float64 = 0
+	var realCount float64 = 0
 
+	for _, purchase := range purchases {
+		purchaseExcel := NewReportPurchaseExcel(f)
+		purchaseExcel.Content = &purchase
+		budgetCount += purchaseExcel.BudgetCount
+		realCount += purchaseExcel.RealCount
+		purchaseExcel.Title = fmt.Sprintf("%s原材料采购单", info.CompanyName)
+		//设置对应的数据
+		purchaseExcel.Offset = offset
+		purchaseExcel.Draws()
+		offset += 15
+	}
+	row := offset + 1
+	startCell := fmt.Sprintf("%s%d", "A", row)
+	endCell := fmt.Sprintf("%s%d", "H", row)
+	f.MergeCell(sheetName, startCell, endCell)
+	f.SetCellStyle(sheetName, startCell, endCell, alignCenterStyle)
+	f.SetCellValue(sheetName, startCell, "汇总金额")
+
+	// 预算金额汇总
+	budgetCountCell := fmt.Sprintf("%s%d", "I", row)
+	budgetCountStr := ""
+	if realCount > 0 {
+		budgetCountStr = fmt.Sprintf("%.2f", budgetCount)
+	}
+	f.SetCellValue(sheetName, budgetCountCell, budgetCountStr)
+	f.SetCellStyle(sheetName, budgetCountCell, budgetCountCell, alignCenterStyle)
+
+	// 实际金额汇总
+	RealCountCell := fmt.Sprintf("%s%d", "J", row)
+
+	realCountStr := ""
+	if realCount > 0 {
+		realCountStr = fmt.Sprintf("%.2f", realCount)
+	}
+	f.SetCellValue(sheetName, RealCountCell, realCountStr)
+	f.SetCellStyle(sheetName, RealCountCell, RealCountCell, alignCenterStyle)
+
+	f.SetRowHeight(sheetName, row, 21)
+
+	c.Header("Content-Type", "application/octet-stream")
+	c.Header("Content-Disposition", "attachment; filename="+"reportPurchase.xlsx")
+	c.Header("Content-Transfer-Encoding", "binary")
+	err = f.Write(c.Writer)
+	if err != nil {
+		return nil, err
 	}
 	return nil, nil
 }

+ 8 - 6
boxcost/db/model/bill.go

@@ -35,9 +35,10 @@ type PaperBill struct {
 }
 
 type PurchaseBill struct {
-	Id     primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
-	PackId primitive.ObjectID `bson:"packId,omitempty" json:"packId"`
-	PlanId primitive.ObjectID `bson:"planId,omitempty" json:"planId"`
+	Id         primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
+	PackId     primitive.ObjectID `bson:"packId,omitempty" json:"packId"`
+	PlanId     primitive.ObjectID `bson:"planId,omitempty" json:"planId"`
+	SupplierId primitive.ObjectID `bson:"supplierId,omitempty" json:"supplierId"`
 
 	//类别
 	Type string `bson:"type,omitempty" json:"type"`
@@ -101,9 +102,10 @@ type ProduceBillData struct {
 }
 
 type ProduceBill struct {
-	Id     primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
-	PackId primitive.ObjectID `bson:"packId,omitempty" json:"packId"`
-	PlanId primitive.ObjectID `bson:"planId,omitempty" json:"planId"`
+	Id         primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
+	PackId     primitive.ObjectID `bson:"packId,omitempty" json:"packId"`
+	PlanId     primitive.ObjectID `bson:"planId,omitempty" json:"planId"`
+	SupplierId primitive.ObjectID `bson:"supplierId,omitempty" json:"supplierId"`
 
 	//类别
 	Type string `bson:"type,omitempty" json:"type"`