package api import ( "box-cost/db/model" "box-cost/db/repo" "box-cost/log" "errors" "strings" "time" "github.com/gin-gonic/gin" "github.com/xuri/excelize/v2" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" ) // 汇总 func Summary(r *GinRouter) { // 下载详细汇总 r.GETJWT("/summary/download", SummaryDownload) // 下载简单汇总 r.GETJWT("/summary/sample/download", SummarySampleDownload) // !10.27 时间和供应商查询 // summary/supplier/plan query={"supplierId":"xxx","timeRange":["xxx","xxx"]} // 返回planIds数组 []string r.GETJWT("/summary/supplier/plan", SummarySupplierPlan) } type SupplierPlanSummary struct { Plans []*PlanSummary SupplierId primitive.ObjectID ApiSession *ApiSession } 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 SerialNumber map[string]string SendTo map[string]string } type PlanSimple struct { Id primitive.ObjectID `bson:"_id,omitempty" json:"_id"` Name string `bson:"name,omitempty" json:"name"` CreateUser string `bson:"createUser,omitempty" json:"createUser"` //生产数量 Total int `bson:"total,omitempty" json:"total"` //状态 Status string `bson:"status,omitempty" json:"status"` //总价 TotalPrice float64 `bson:"totalPrice,omitempty" json:"totalPrice"` CreateTime time.Time `bson:"createTime,omitempty" json:"createTime"` } func SummarySupplierPlan(c *gin.Context, apictx *ApiSession) (interface{}, error) { _, _, query := UtilQueryPageSize(c) supplierId := primitive.NilObjectID if _supplierId, ok := query["supplierId"]; ok { supplierId, _ = primitive.ObjectIDFromHex(_supplierId.(string)) delete(query, "supplierId") } if _timeRange, ok := query["timeRange"]; ok { timeRange, _ := _timeRange.([]interface{}) if len(timeRange) == 2 { start, end := getTimeRange(timeRange[0].(string), timeRange[1].(string)) query["createTime"] = bson.M{"$gte": start, "$lte": end} } delete(query, "timeRange") } // 遍历判断包含供应商的数据,返回planIds plans := []*model.ProductPlan{} err := repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionProductPlan, Query: query, Sort: bson.M{"createTime": -1}, }, &plans) if err != nil { log.Error(err) return nil, errors.New("查询数据错误!") } planSimples := []*PlanSimple{} if len(plans) < 1 { return planSimples, nil } // 遍历 for _, plan := range plans { flag := false // !20240425兼容totalPrice为空的情况 var totalPrice float64 = 0 if plan.TotalPrice != nil { totalPrice = *plan.TotalPrice } ps := &PlanSimple{ Id: plan.Id, Name: plan.Name, CreateUser: plan.CreateUser, Total: plan.Total, Status: plan.Status, TotalPrice: totalPrice, CreateTime: plan.CreateTime, } // 选供应商 if !supplierId.IsZero() { for _, comp := range plan.Pack.Components { if comp.Id == "" || len(comp.Stages) == 0 { continue } for _, stage := range comp.Stages { // 只要任意一个stage中存在选中的供应商,那么这个计划包含这个供应商,这时应该跳出来 if stage.SupplierInfo == nil { continue } if stage.SupplierInfo.Id == supplierId { planSimples = append(planSimples, ps) flag = true break } } if flag { break } } } else { planSimples = append(planSimples, ps) } } return planSimples, nil } // /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, ",") supplierId, _ := primitive.ObjectIDFromHex(_supplierId) // 获取详情 if len(planIds) < 1 { return nil, errors.New("数据不存在") } summaryPlans := []*PlanSummary{} for _, _planId := range planIds { id, _ := primitive.ObjectIDFromHex(_planId) if id.IsZero() { 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, ApiSession: apictx, } // 绘制表格 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, ",") supplierId, _ := primitive.ObjectIDFromHex(_supplierId) // 获取详情 if len(planIds) < 1 { return nil, errors.New("数据不存在") } summaryPlans := []*PlanSummary{} for _, _planId := range planIds { id, _ := primitive.ObjectIDFromHex(_planId) if id.IsZero() { 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 GetPlanStatus(plan *model.ProductPlan, apictx *ApiSession) *PlanSummary { billStates := map[string]string{} billSerialNumber := map[string]string{} billSendTo := 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", "sendTo", "remark", "createTime"}}) if ok { billStates[stage.BillId] = state["status"].(string) billSerialNumber[stage.BillId] = state["serialNumber"].(string) if v, ok := state["sendTo"]; ok { billSendTo[stage.BillId] = v.(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, SerialNumber: billSerialNumber, SendTo: billSendTo, } }