package api import ( "box-cost/db/model" "box-cost/db/repo" "errors" "strings" "time" "github.com/gin-gonic/gin" "github.com/xuri/excelize/v2" "go.mongodb.org/mongo-driver/bson/primitive" ) // 汇总 func Summary(r *GinRouter) { // 下载详细汇总 r.GET("/summary/download", SummaryDownload) // 下载简单汇总 r.GET("/summary/sample/download", SummarySampleDownload) } type SupplierPlanSummary struct { Plans []*PlanSummary SupplierId primitive.ObjectID } type PlanSummary struct { Plan *model.ProductPlan IsSend map[string]bool IsAck map[string]bool Reviewed map[string]int32 State map[string]string CreateTimes map[string]time.Time } // /summary/download?planIds=id1,id2&supplierId=xxx func SummaryDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) { // 获取planIds supplierId _planIds := c.Query("planIds") // id1,id2... _supplierId := c.Query("supplierId") // 供应商id planIds := strings.Split(_planIds, ",") planIds = filter(planIds, func(s string) bool { return s != "" }) supplierId, _ := primitive.ObjectIDFromHex(_supplierId) // 获取详情 if len(planIds) < 1 { return nil, errors.New("数据不存在") } summaryPlans := []*PlanSummary{} for _, _planId := range planIds { id, err := primitive.ObjectIDFromHex(_planId) if err != nil { return nil, errors.New("非法id") } plan := &model.ProductPlan{} found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: repo.CollectionProductPlan, Query: repo.Map{"_id": id}, }, plan) if !found || err != nil { continue } summaryPlan := GetPlanStatus(plan, apictx) summaryPlans = append(summaryPlans, summaryPlan) } if len(summaryPlans) < 1 { return nil, errors.New("数据不存在") } // 实例化表格,传入数据 f := excelize.NewFile() index := f.NewSheet("Sheet1") f.SetActiveSheet(index) f.SetDefaultFont("宋体") planSummaryExcel := NewPlanSummaryExcel(f) planSummaryExcel.Content = &SupplierPlanSummary{ Plans: summaryPlans, SupplierId: supplierId, } // 绘制表格 planSummaryExcel.Draws() c.Header("Content-Type", "application/octet-stream") c.Header("Content-Disposition", "attachment; filename="+"planSummary.xlsx") c.Header("Content-Transfer-Encoding", "binary") err := f.Write(c.Writer) if err != nil { return nil, err } return nil, nil } // /summary/sample/download?planIds=id1,id2&supplierId=xxx func SummarySampleDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) { // 获取planIds supplierId _planIds := c.Query("planIds") // id1,id2... _supplierId := c.Query("supplierId") // 供应商id planIds := strings.Split(_planIds, ",") planIds = filter(planIds, func(s string) bool { return s != "" }) supplierId, _ := primitive.ObjectIDFromHex(_supplierId) // 获取详情 if len(planIds) < 1 { return nil, errors.New("数据不存在") } summaryPlans := []*PlanSummary{} for _, _planId := range planIds { id, err := primitive.ObjectIDFromHex(_planId) if err != nil { return nil, errors.New("非法id") } plan := &model.ProductPlan{} found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: repo.CollectionProductPlan, Query: repo.Map{"_id": id}, }, plan) if !found || err != nil { continue } summaryPlan := GetPlanStatus(plan, apictx) summaryPlans = append(summaryPlans, summaryPlan) } if len(summaryPlans) < 1 { return nil, errors.New("数据不存在") } // 实例化表格,传入数据 f := excelize.NewFile() index := f.NewSheet("Sheet1") f.SetActiveSheet(index) f.SetDefaultFont("宋体") planSummaryExcel := NewSummarySampleExcel(f) planSummaryExcel.Content = &SupplierPlanSummary{ Plans: summaryPlans, SupplierId: supplierId, } // 绘制表格 planSummaryExcel.Draws() c.Header("Content-Type", "application/octet-stream") c.Header("Content-Disposition", "attachment; filename="+"planSummary.xlsx") c.Header("Content-Transfer-Encoding", "binary") err := f.Write(c.Writer) if err != nil { return nil, err } return nil, nil } func filter(arr []string, f func(string) bool) []string { var filtered []string for _, s := range arr { if f(s) { filtered = append(filtered, s) } } return filtered } func GetPlanStatus(plan *model.ProductPlan, apictx *ApiSession) *PlanSummary { billStates := map[string]string{} billIsSend := map[string]bool{} billReviewed := map[string]int32{} billIsAck := map[string]bool{} billCreateTimes := map[string]time.Time{} if plan.Pack != nil && plan.Pack.Components != nil { for _, comp := range plan.Pack.Components { if comp.Stages != nil { for _, stage := range comp.Stages { if len(stage.BillId) > 0 { collectName := "" // 材料 if stage.BillType == 1 { collectName = repo.CollectionBillPurchase } // 工艺 if stage.BillType == 2 { collectName = repo.CollectionBillProduce } // 成品 if stage.BillType == 3 { collectName = repo.CollectionBillProduct } ok, state := repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: collectName, Query: repo.Map{"_id": stage.BillId}, Project: []string{"status", "isSend", "reviewed", "isAck", "serialNumber", "remark", "createTime"}}) if ok { billStates[stage.BillId] = state["status"].(string) if v, ok := state["isSend"]; ok { billIsSend[stage.BillId] = v.(bool) } else { billIsSend[stage.BillId] = false } if v, ok := state["reviewed"]; ok { billReviewed[stage.BillId] = v.(int32) } else { billReviewed[stage.BillId] = -1 } if v, ok := state["isAck"]; ok { billIsAck[stage.BillId] = v.(bool) } else { billIsAck[stage.BillId] = false } if v, ok := state["createTime"]; ok { billCreateTimes[stage.BillId] = v.(primitive.DateTime).Time() } } } } } } } return &PlanSummary{ Plan: plan, IsSend: billIsSend, IsAck: billIsAck, Reviewed: billReviewed, State: billStates, CreateTimes: billCreateTimes, } }