package api import ( "archive/zip" "box-cost/db/model" "box-cost/db/repo" "errors" "fmt" "io" "os" "path/filepath" "regexp" "strings" "sync" "time" "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" ) // 统计报表 按时间范围,供应商 包装-计划(多选) 维度进行过滤,形成报表。可以下载 func Report(r *GinRouter) { // 加工列表 r.GETJWT("/report/produce/list", ReportProduceList) // 采购列表 r.GETJWT("/report/purchase/list", ReportPurchaseList) r.GETJWT("/report/product/list", ReportProductList) r.GETJWT("/report/list", ReportList) r.GETJWT("/report/download", ReportListDownload) // r.GETJWT("/report/bills/download", ReportBillsDownload1) } // 下载单据 func ReportBillsDownload1(c *gin.Context, apictx *ApiSession) (interface{}, error) { _, _, query := UtilQueryPageSize(c) filtter := handleReportQuery(query) purchases := []*model.PurchaseBill{} produces := []*model.ProduceBill{} products := []*model.ProductBill{} repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionBillPurchase, Query: filtter, }, &purchases) repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionBillProduce, Query: filtter, }, &produces) repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionBillProduct, Query: filtter, }, &products) // 加入redis有序集合中进行排序 // 把对应type_id:对象存入map中避免再次查询表 typeBills := map[string]interface{}{} redisCli := apictx.Svc.Redis reportBillKey := "report-bill-list:" + apictx.User.Parent redisCli.Del(apictx.CreateRepoCtx().Ctx, reportBillKey) // isExist := redisCli.Exists(apictx.CreateRepoCtx().Ctx, reportBillKey).Val() // 不存在这个key时 // if isExist < 1 { if len(purchases) > 0 { for _, purchase := range purchases { member := "purchase_" + purchase.Id.Hex() score := purchase.CompleteTime.Unix() redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member}) typeBills[member] = purchase } } if len(produces) > 0 { for _, produce := range produces { member := "produce_" + produce.Id.Hex() score := produce.CompleteTime.Unix() redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member}) typeBills[member] = produce } } if len(products) > 0 { for _, product := range products { member := "product_" + product.Id.Hex() score := product.CompleteTime.Unix() redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member}) typeBills[member] = product } } // 设置过期时间 // redisCli.Expire(apictx.CreateRepoCtx().Ctx, reportBillKey, 1*time.Second) // } total, err := redisCli.ZCard(apictx.CreateRepoCtx().Ctx, reportBillKey).Uint64() fmt.Println("单据总数量: ", total) if err != nil { fmt.Println(err) return nil, err } reports, err := redisCli.ZRevRange(apictx.CreateRepoCtx().Ctx, reportBillKey, 0, -1).Result() if err != nil { return nil, err } if len(reports) < 1 { return nil, errors.New("没有单据信息") } // 获取供应商名称 // supplier := &model.Supplier{} // repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ // CollectName: repo.CollectionSupplier, // Query: repo.Map{"_id": supplierId}, // Project: []string{"name"}, // }, supplier) ct := time.Now().Format("20060102150405") // 下载文件的名字 // eName := fmt.Sprintf("统计单据_%s", ct) companyName := getCompanyName(apictx) zipName := fmt.Sprintf("统计单据_%s", ct) // 获取订单信息下载 saveTmpDir := fmt.Sprintf("tmp1/report/%s", zipName) if isExistDir(saveTmpDir) { os.RemoveAll(saveTmpDir) } f := excelize.NewFile() f.SetDefaultFont("宋体") flagIndex := -1 // 采购 加工 加工-印刷 加工-覆膜 加工-对裱 成品采购 typeRows := []int{0, 0, 0, 0, 0, 0} for _, tId := range reports { var billExcel IExcel // 采购 if strings.Contains(tId, "purchase") { purchase := typeBills[tId].(*model.PurchaseBill) sheetName := "采购单" index := f.NewSheet(sheetName) if flagIndex < 0 { flagIndex = index } billExcel = NewPurchaseBill(f) billExcel.SetSheetName(sheetName) // 获取签名信息 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) } } // 获取计划名 // plan := &model.ProductPlan{} // repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ // CollectName: repo.CollectionProductPlan, // Query: repo.Map{"_id": purchase.PlanId}, // Project: []string{"name"}, // }, plan) // productName = purchase.ProductName // supplierName = purchase.Supplier // serialNumber = purchase.SerialNumber billExcel.SetContent(purchase) billExcel.SetTitle(fmt.Sprintf("%s原材料采购单", companyName)) billExcel.SetRow(typeRows[0]) billExcel.Draws() typeRows[0] = billExcel.GetRow() + 5 } // 加工单 if strings.Contains(tId, "produce") { produce := typeBills[tId].(*model.ProduceBill) sheetName := "加工单" if produce.IsPrint { sheetName = "加工单-印刷" } else if produce.IsLam { sheetName = "加工单-覆膜" } else if produce.IsPaper { sheetName = "加工单-对裱" } index := f.NewSheet(sheetName) if flagIndex < 0 { flagIndex = index } billExcel = NewProduceBill(f) billExcel.SetSheetName(sheetName) // 获取签名信息 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) } } // 获取计划名 // plan := &model.ProductPlan{} // repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ // CollectName: repo.CollectionProductPlan, // Query: repo.Map{"_id": produce.PlanId}, // Project: []string{"name"}, // }, plan) billExcel.SetContent(produce) billExcel.SetTitle(fmt.Sprintf("%s加工单", companyName)) if produce.IsPrint { billExcel.SetRow(typeRows[2]) billExcel.Draws() typeRows[2] = billExcel.GetRow() + 5 } else if produce.IsLam { billExcel.SetRow(typeRows[3]) billExcel.Draws() typeRows[3] = billExcel.GetRow() + 5 } else if produce.IsPaper { billExcel.SetRow(typeRows[4]) billExcel.Draws() typeRows[4] = billExcel.GetRow() + 5 } else { billExcel.SetRow(typeRows[1]) billExcel.Draws() typeRows[1] = billExcel.GetRow() + 5 } } // 成品 if strings.Contains(tId, "product") { product := typeBills[tId].(*model.ProductBill) sheetName := "成品采购单" index := f.NewSheet(sheetName) if flagIndex < 0 { flagIndex = index } billExcel = NewProductBill(f) billExcel.SetSheetName(sheetName) // 获取签名信息 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) } } // 获取计划名 // plan := &model.ProductPlan{} // repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ // CollectName: repo.CollectionProductPlan, // Query: repo.Map{"_id": product.PlanId}, // Project: []string{"name"}, // }, plan) billExcel.SetContent(product) billExcel.SetTitle(companyName) billExcel.SetRow(typeRows[5]) billExcel.Draws() typeRows[5] = billExcel.GetRow() + 5 } } // 设置活跃sheet f.SetActiveSheet(flagIndex) // 删除默认Sheet1 f.DeleteSheet("Sheet1") buf, _ := f.WriteToBuffer() targeName := fmt.Sprintf("%s.xlsx", zipName) err = saveExcelToTmp1(saveTmpDir, targeName, buf.Bytes()) if err != nil { return nil, err } c.Header("Content-Type", "application/octet-stream") c.Header("Content-Disposition", "attachment; filename="+fmt.Sprintf("%s.zip", zipName)) 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 } // 下载单据 // // !更改为ReportBillsDownload1 确定不需要后删除 func ReportBillsDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) { _, _, query := UtilQueryPageSize(c) // supplierId := primitive.NilObjectID // if _supplierId, ok := query["supplierId"]; ok { // supplierId, _ = primitive.ObjectIDFromHex(_supplierId.(string)) // } _isPdf := "false" if isPdf, ok := query["isPdf"]; ok { delete(query, "isPdf") if isPdf.(string) == "true" { _isPdf = "true" } } // timeRange := []interface{}{} // if _timeRange, ok := query["timeRange"]; ok { // timeRange, _ = _timeRange.([]interface{}) // } filtter := handleReportQuery(query) purchases := []*model.PurchaseBill{} produces := []*model.ProduceBill{} products := []*model.ProductBill{} repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionBillPurchase, Query: filtter, }, &purchases) repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionBillProduce, Query: filtter, }, &produces) repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionBillProduct, Query: filtter, }, &products) // 加入redis有序集合中进行排序 // 把对应type_id:对象存入map中避免再次查询表 typeBills := map[string]interface{}{} redisCli := apictx.Svc.Redis reportBillKey := "report-bill-list:" + apictx.User.Parent redisCli.Del(apictx.CreateRepoCtx().Ctx, reportBillKey) // isExist := redisCli.Exists(apictx.CreateRepoCtx().Ctx, reportBillKey).Val() // 不存在这个key时 // if isExist < 1 { if len(purchases) > 0 { for _, purchase := range purchases { member := "purchase_" + purchase.Id.Hex() score := purchase.CompleteTime.Unix() redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member}) typeBills[member] = purchase } } if len(produces) > 0 { for _, produce := range produces { member := "produce_" + produce.Id.Hex() score := produce.CompleteTime.Unix() redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member}) typeBills[member] = produce } } if len(products) > 0 { for _, product := range products { member := "product_" + product.Id.Hex() score := product.CompleteTime.Unix() redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member}) typeBills[member] = product } } // 设置过期时间 // redisCli.Expire(apictx.CreateRepoCtx().Ctx, reportBillKey, 1*time.Second) // } total, err := redisCli.ZCard(apictx.CreateRepoCtx().Ctx, reportBillKey).Uint64() fmt.Println("单据总数量: ", total) if err != nil { fmt.Println(err) return nil, err } reports, err := redisCli.ZRevRange(apictx.CreateRepoCtx().Ctx, reportBillKey, 0, -1).Result() if err != nil { return nil, err } if len(reports) < 1 { return nil, errors.New("没有单据信息") } // 获取供应商名称 // supplier := &model.Supplier{} // repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ // CollectName: repo.CollectionSupplier, // Query: repo.Map{"_id": supplierId}, // Project: []string{"name"}, // }, supplier) r := regexp.MustCompile(`/`) ct := time.Now().Format("20060102150405") zipName := fmt.Sprintf("统计单据_%s", ct) // 获取订单信息下载 saveTmpDir := fmt.Sprintf("tmp1/report/%s", zipName) if isExistDir(saveTmpDir) { os.RemoveAll(saveTmpDir) } // 记录文件数量 var wg sync.WaitGroup c1 := make(chan int, 10) for _, tId := range reports { productName := "" supplierName := "" serialNumber := "" f := excelize.NewFile() index := f.NewSheet("Sheet1") f.SetActiveSheet(index) f.SetDefaultFont("宋体") tidArr := strings.Split(tId, "_") var billExcel IExcel // 采购 if tidArr[0] == "purchase" { purchase := typeBills[tId].(*model.PurchaseBill) 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) } } // 获取计划名 plan := &model.ProductPlan{} repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: repo.CollectionProductPlan, Query: repo.Map{"_id": purchase.PlanId}, Project: []string{"name"}, }, plan) productName = purchase.ProductName supplierName = purchase.Supplier serialNumber = purchase.SerialNumber billExcel.SetContent(purchase) billExcel.SetTitle(fmt.Sprintf("%s原材料采购单", plan.Name)) } // 工艺 if tidArr[0] == "produce" { produce := typeBills[tId].(*model.ProduceBill) 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) } } // 获取计划名 plan := &model.ProductPlan{} repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: repo.CollectionProductPlan, Query: repo.Map{"_id": produce.PlanId}, Project: []string{"name"}, }, plan) productName = produce.ProductName supplierName = produce.Supplier serialNumber = produce.SerialNumber billExcel.SetContent(produce) billExcel.SetTitle(fmt.Sprintf("%s加工单", plan.Name)) } // 成品采购 if tidArr[0] == "product" { product := typeBills[tId].(*model.ProductBill) 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) } } // 获取计划名 plan := &model.ProductPlan{} repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: repo.CollectionProductPlan, Query: repo.Map{"_id": product.PlanId}, Project: []string{"name"}, }, plan) productName = product.ProductName supplierName = product.Supplier serialNumber = product.SerialNumber billExcel.SetContent(product) billExcel.SetTitle(plan.Name) } billExcel.SetIsPdf(_isPdf) billExcel.Draws() buf, _ := f.WriteToBuffer() ft := "xlsx" if _isPdf == "true" { ft = "pdf" } _productName := r.ReplaceAllString(productName, `&`) _supplierName := r.ReplaceAllString(supplierName, `&`) targePdfName := fmt.Sprintf("%s-%s-%s.%s", _supplierName, _productName, serialNumber, ft) wg.Add(1) if _isPdf == "true" { go toPdfAndSaveTask(buf, apictx.Svc.Conf.PdfApiAddr, saveTmpDir, targePdfName, c1, &wg) } else { go saveExcelToTmp(saveTmpDir, targePdfName, buf.Bytes(), c1, &wg) } } go func() { // 等待所有goroutine wg.Wait() // 关闭channel close(c1) }() // channel关闭后结束后停止遍历接收channel中的值 for n := range c1 { if n == -1 { return nil, errors.New("下载失败,请重试") } } c.Header("Content-Type", "application/octet-stream") c.Header("Content-Disposition", "attachment; filename="+zipName+".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 ReportListDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) { _, _, query := UtilQueryPageSize(c) // start, stop := CreatePageRange(page, size) supplierId := primitive.NilObjectID if _supplierId, ok := query["supplierId"]; ok { supplierId, _ = primitive.ObjectIDFromHex(_supplierId.(string)) } timeRange := []interface{}{} if _timeRange, ok := query["timeRange"]; ok { timeRange, _ = _timeRange.([]interface{}) } filtter := handleReportQuery(query) purchases := []*model.PurchaseBill{} produces := []*model.ProduceBill{} products := []*model.ProductBill{} repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionBillPurchase, Query: filtter, Project: []string{"_id", "completeTime"}, }, &purchases) repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionBillProduce, Query: filtter, Project: []string{"_id", "completeTime"}, }, &produces) repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionBillProduct, Query: filtter, Project: []string{"_id", "completeTime"}, }, &products) // 加入redis有序集合中 redisCli := apictx.Svc.Redis reportBillKey := "report-bill-list:" + apictx.User.Parent redisCli.Del(apictx.CreateRepoCtx().Ctx, reportBillKey) // isExist := redisCli.Exists(apictx.CreateRepoCtx().Ctx, reportBillKey).Val() // 不存在这个key时 // if isExist < 1 { if len(purchases) > 0 { for _, purchase := range purchases { member := "purchase_" + purchase.Id.Hex() score := purchase.CompleteTime.Unix() redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member}) } } if len(produces) > 0 { for _, produce := range produces { member := "produce_" + produce.Id.Hex() score := produce.CompleteTime.Unix() redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member}) } } if len(products) > 0 { for _, product := range products { member := "product_" + product.Id.Hex() score := product.CompleteTime.Unix() redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member}) } } // 设置过期时间 // redisCli.Expire(apictx.CreateRepoCtx().Ctx, reportBillKey, 1*time.Second) // } total, err := redisCli.ZCard(apictx.CreateRepoCtx().Ctx, reportBillKey).Uint64() fmt.Println(total) if err != nil { fmt.Println(err) return nil, err } reports, err := redisCli.ZRevRange(apictx.CreateRepoCtx().Ctx, reportBillKey, 0, -1).Result() if err != nil { return nil, err } if len(reports) < 1 { return nil, errors.New("没有单据信息") } lists := []map[string]interface{}{} for _, report := range reports { billArray := strings.Split(report, "_") billType := billArray[0] _billId := billArray[1] billId, _ := primitive.ObjectIDFromHex(_billId) billData := map[string]interface{}{} found := false if billType == "purchase" { found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: repo.CollectionBillPurchase, Query: repo.Map{"_id": billId}, }) } if billType == "produce" { found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: repo.CollectionBillProduce, Query: repo.Map{"_id": billId}, }) } if billType == "product" { found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: repo.CollectionBillProduct, Query: repo.Map{"_id": billId}, }) } if found { billData["billType"] = billType lists = append(lists, billData) } } f := excelize.NewFile() defer f.Close() index := f.NewSheet("Sheet1") f.SetActiveSheet(index) f.SetDefaultFont("宋体") report := NewReportExcel(f) supplier := model.Supplier{} supplierName := "【所有供应商】" if !supplierId.IsZero() { repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: repo.CollectionSupplier, Query: repo.Map{"_id": supplierId}, Project: []string{"name"}, }, &supplier) supplierName = supplier.Name } report.SupplierName = supplierName if len(timeRange) == 2 { report.TimeRange = append(report.TimeRange, timeRange[0].(string), timeRange[1].(string)) } report.Content = lists report.Draws() 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 } return nil, nil } // 加工单 func ReportList(c *gin.Context, apictx *ApiSession) (interface{}, error) { page, size, query := UtilQueryPageSize(c) start, stop := CreatePageRange(page, size) filtter := handleReportQuery(query) purchases := []*model.PurchaseBill{} produces := []*model.ProduceBill{} products := []*model.ProductBill{} repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionBillPurchase, Query: filtter, Project: []string{"_id", "completeTime"}, }, &purchases) repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionBillProduce, Query: filtter, Project: []string{"_id", "completeTime"}, }, &produces) repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionBillProduct, Query: filtter, Project: []string{"_id", "completeTime"}, }, &products) // 加入redis有序集合中 redisCli := apictx.Svc.Redis reportBillKey := "report-bill-list:" + apictx.User.Parent redisCli.Del(apictx.CreateRepoCtx().Ctx, reportBillKey) // isExist := redisCli.Exists(apictx.CreateRepoCtx().Ctx, reportBillKey).Val() // 不存在这个key时 // if isExist < 1 { if len(purchases) > 0 { for _, purchase := range purchases { member := "purchase_" + purchase.Id.Hex() score := purchase.CompleteTime.Unix() redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member}) } } if len(produces) > 0 { for _, produce := range produces { member := "produce_" + produce.Id.Hex() score := produce.CompleteTime.Unix() redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member}) } } if len(products) > 0 { for _, product := range products { member := "product_" + product.Id.Hex() score := product.CompleteTime.Unix() redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member}) } } // 设置过期时间 // redisCli.Expire(apictx.CreateRepoCtx().Ctx, reportBillKey, 1*time.Second) // } total, err := redisCli.ZCard(apictx.CreateRepoCtx().Ctx, reportBillKey).Uint64() if err != nil { fmt.Println(err) return nil, err } reports, err := redisCli.ZRevRange(apictx.CreateRepoCtx().Ctx, reportBillKey, start, stop).Result() if err != nil { return nil, err } if len(reports) < 1 { return repo.PageResult{ List: []map[string]interface{}{}, Page: page, Size: size, Total: 0, }, nil } lists := []map[string]interface{}{} for _, report := range reports { billArray := strings.Split(report, "_") billType := billArray[0] _billId := billArray[1] billId, _ := primitive.ObjectIDFromHex(_billId) billData := map[string]interface{}{} found := false if billType == "purchase" { found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: repo.CollectionBillPurchase, Query: repo.Map{"_id": billId}, }) } if billType == "produce" { found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: repo.CollectionBillProduce, Query: repo.Map{"_id": billId}, }) } if billType == "product" { found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{ CollectName: repo.CollectionBillProduct, Query: repo.Map{"_id": billId}, }) } if found { billData["billType"] = billType lists = append(lists, billData) } } return repo.PageResult{ List: lists, Total: int64(total), Page: page, Size: size, }, nil } func CreatePageRange(page, size int64) (int64, int64) { if page < 1 { page = 1 } if size < 1 { size = 10 } start := (page - 1) * size stop := page*size - 1 return start, stop } func ReportProduceList(c *gin.Context, apictx *ApiSession) (interface{}, error) { page, size, query := UtilQueryPageSize(c) // 条件处理 // 获取采购单符合条件的信息 return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionBillProduce, Query: handleReportQuery(query), Page: page, Size: size, }) } // 采购单 func ReportPurchaseList(c *gin.Context, apictx *ApiSession) (interface{}, error) { page, size, query := UtilQueryPageSize(c) return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionBillPurchase, Query: handleReportQuery(query), Page: page, Size: size, }) } func ReportProductList(c *gin.Context, apictx *ApiSession) (interface{}, error) { page, size, query := UtilQueryPageSize(c) return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{ CollectName: repo.CollectionBillProduct, Query: handleReportQuery(query), Page: page, Size: size, }) }