report.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. package api
  2. import (
  3. "box-cost/db/model"
  4. "box-cost/db/repo"
  5. "errors"
  6. "fmt"
  7. "strings"
  8. "time"
  9. "github.com/gin-gonic/gin"
  10. "github.com/go-redis/redis/v8"
  11. "github.com/xuri/excelize/v2"
  12. "go.mongodb.org/mongo-driver/bson/primitive"
  13. )
  14. // 统计报表 按时间范围,供应商 包装-计划(多选) 维度进行过滤,形成报表。可以下载
  15. func Report(r *GinRouter) {
  16. // 加工列表
  17. r.GET("/report/produce/list", ReportProduceList)
  18. // 采购列表
  19. r.GET("/report/purchase/list", ReportPurchaseList)
  20. r.GET("/report/product/list", ReportProductList)
  21. r.GETJWT("/report/list", ReportList)
  22. r.GETJWT("/report/download", ReportListDownload)
  23. }
  24. // 加工单
  25. func ReportListDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  26. _, _, query := UtilQueryPageSize(c)
  27. // start, stop := CreatePageRange(page, size)
  28. supplierId := primitive.NilObjectID
  29. if _supplierId, ok := query["supplierId"]; ok {
  30. supplierId, _ = primitive.ObjectIDFromHex(_supplierId.(string))
  31. }
  32. timeRange := []interface{}{}
  33. if _timeRange, ok := query["timeRange"]; ok {
  34. timeRange, _ = _timeRange.([]interface{})
  35. }
  36. filtter := handleReportQuery(query)
  37. purchases := []*model.PurchaseBill{}
  38. produces := []*model.ProduceBill{}
  39. products := []*model.ProductBill{}
  40. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  41. CollectName: repo.CollectionBillPurchase,
  42. Query: filtter,
  43. Project: []string{"_id", "completeTime"},
  44. }, &purchases)
  45. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  46. CollectName: repo.CollectionBillProduce,
  47. Query: filtter,
  48. Project: []string{"_id", "completeTime"},
  49. }, &produces)
  50. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  51. CollectName: repo.CollectionBillProduct,
  52. Query: filtter,
  53. Project: []string{"_id", "completeTime"},
  54. }, &products)
  55. // 加入redis有序集合中
  56. redisCli := apictx.Svc.Redis
  57. reportBillKey := "report-bill-list:" + apictx.User.Parent
  58. isExist := redisCli.Exists(apictx.CreateRepoCtx().Ctx, reportBillKey).Val()
  59. // 不存在这个key时
  60. if isExist < 1 {
  61. if len(purchases) > 0 {
  62. for _, purchase := range purchases {
  63. member := "purchase_" + purchase.Id.Hex()
  64. score := purchase.CompleteTime.Unix()
  65. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  66. }
  67. }
  68. if len(produces) > 0 {
  69. for _, produce := range produces {
  70. member := "produce_" + produce.Id.Hex()
  71. score := produce.CompleteTime.Unix()
  72. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  73. }
  74. }
  75. if len(products) > 0 {
  76. for _, product := range products {
  77. member := "product_" + product.Id.Hex()
  78. score := product.CompleteTime.Unix()
  79. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  80. }
  81. }
  82. // 设置过期时间
  83. redisCli.Expire(apictx.CreateRepoCtx().Ctx, reportBillKey, 1*time.Second)
  84. }
  85. total, err := redisCli.ZCard(apictx.CreateRepoCtx().Ctx, reportBillKey).Uint64()
  86. fmt.Println(total)
  87. if err != nil {
  88. fmt.Println(err)
  89. return nil, err
  90. }
  91. reports, err := redisCli.ZRevRange(apictx.CreateRepoCtx().Ctx, reportBillKey, 0, -1).Result()
  92. if err != nil {
  93. return nil, err
  94. }
  95. if len(reports) < 1 {
  96. return nil, errors.New("没有单据信息")
  97. }
  98. lists := []map[string]interface{}{}
  99. for _, report := range reports {
  100. billArray := strings.Split(report, "_")
  101. billType := billArray[0]
  102. _billId := billArray[1]
  103. billId, _ := primitive.ObjectIDFromHex(_billId)
  104. billData := map[string]interface{}{}
  105. found := false
  106. if billType == "purchase" {
  107. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  108. CollectName: repo.CollectionBillPurchase,
  109. Query: repo.Map{"_id": billId},
  110. })
  111. }
  112. if billType == "produce" {
  113. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  114. CollectName: repo.CollectionBillProduce,
  115. Query: repo.Map{"_id": billId},
  116. })
  117. }
  118. if billType == "product" {
  119. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  120. CollectName: repo.CollectionBillProduct,
  121. Query: repo.Map{"_id": billId},
  122. })
  123. }
  124. if found {
  125. billData["billType"] = billType
  126. lists = append(lists, billData)
  127. }
  128. }
  129. f := excelize.NewFile()
  130. defer f.Close()
  131. index := f.NewSheet("Sheet1")
  132. f.SetActiveSheet(index)
  133. f.SetDefaultFont("宋体")
  134. report := NewReportExcel(f)
  135. supplier := model.Supplier{}
  136. supplierName := "【所有供应商】"
  137. if !supplierId.IsZero() {
  138. repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  139. CollectName: repo.CollectionSupplier,
  140. Query: repo.Map{"_id": supplierId},
  141. Project: []string{"name"},
  142. }, &supplier)
  143. supplierName = supplier.Name
  144. }
  145. report.SupplierName = supplierName
  146. if len(timeRange) == 2 {
  147. report.TimeRange = append(report.TimeRange, timeRange[0].(string), timeRange[1].(string))
  148. }
  149. report.Content = lists
  150. report.Draws()
  151. c.Header("Content-Type", "application/octet-stream")
  152. c.Header("Content-Disposition", "attachment; filename="+"report.xlsx")
  153. c.Header("Content-Transfer-Encoding", "binary")
  154. err = f.Write(c.Writer)
  155. if err != nil {
  156. return nil, err
  157. }
  158. return nil, nil
  159. }
  160. // 加工单
  161. func ReportList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  162. page, size, query := UtilQueryPageSize(c)
  163. start, stop := CreatePageRange(page, size)
  164. filtter := handleReportQuery(query)
  165. purchases := []*model.PurchaseBill{}
  166. produces := []*model.ProduceBill{}
  167. products := []*model.ProductBill{}
  168. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  169. CollectName: repo.CollectionBillPurchase,
  170. Query: filtter,
  171. Project: []string{"_id", "completeTime"},
  172. }, &purchases)
  173. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  174. CollectName: repo.CollectionBillProduce,
  175. Query: filtter,
  176. Project: []string{"_id", "completeTime"},
  177. }, &produces)
  178. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  179. CollectName: repo.CollectionBillProduct,
  180. Query: filtter,
  181. Project: []string{"_id", "completeTime"},
  182. }, &products)
  183. // 加入redis有序集合中
  184. redisCli := apictx.Svc.Redis
  185. reportBillKey := "report-bill-list:" + apictx.User.Parent
  186. isExist := redisCli.Exists(apictx.CreateRepoCtx().Ctx, reportBillKey).Val()
  187. // 不存在这个key时
  188. if isExist < 1 {
  189. if len(purchases) > 0 {
  190. for _, purchase := range purchases {
  191. member := "purchase_" + purchase.Id.Hex()
  192. score := purchase.CompleteTime.Unix()
  193. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  194. }
  195. }
  196. if len(produces) > 0 {
  197. for _, produce := range produces {
  198. member := "produce_" + produce.Id.Hex()
  199. score := produce.CompleteTime.Unix()
  200. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  201. }
  202. }
  203. if len(products) > 0 {
  204. for _, product := range products {
  205. member := "product_" + product.Id.Hex()
  206. score := product.CompleteTime.Unix()
  207. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  208. }
  209. }
  210. // 设置过期时间
  211. redisCli.Expire(apictx.CreateRepoCtx().Ctx, reportBillKey, 1*time.Second)
  212. }
  213. total, err := redisCli.ZCard(apictx.CreateRepoCtx().Ctx, reportBillKey).Uint64()
  214. if err != nil {
  215. fmt.Println(err)
  216. return nil, err
  217. }
  218. reports, err := redisCli.ZRevRange(apictx.CreateRepoCtx().Ctx, reportBillKey, start, stop).Result()
  219. if err != nil {
  220. return nil, err
  221. }
  222. if len(reports) < 1 {
  223. return repo.PageResult{
  224. List: []map[string]interface{}{},
  225. Page: page,
  226. Size: size,
  227. Total: 0,
  228. }, nil
  229. }
  230. lists := []map[string]interface{}{}
  231. for _, report := range reports {
  232. billArray := strings.Split(report, "_")
  233. billType := billArray[0]
  234. _billId := billArray[1]
  235. billId, _ := primitive.ObjectIDFromHex(_billId)
  236. billData := map[string]interface{}{}
  237. found := false
  238. if billType == "purchase" {
  239. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  240. CollectName: repo.CollectionBillPurchase,
  241. Query: repo.Map{"_id": billId},
  242. })
  243. }
  244. if billType == "produce" {
  245. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  246. CollectName: repo.CollectionBillProduce,
  247. Query: repo.Map{"_id": billId},
  248. })
  249. }
  250. if billType == "product" {
  251. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  252. CollectName: repo.CollectionBillProduct,
  253. Query: repo.Map{"_id": billId},
  254. })
  255. }
  256. if found {
  257. billData["billType"] = billType
  258. lists = append(lists, billData)
  259. }
  260. }
  261. return repo.PageResult{
  262. List: lists,
  263. Total: int64(total),
  264. Page: page,
  265. Size: size,
  266. }, nil
  267. }
  268. func CreatePageRange(page, size int64) (int64, int64) {
  269. if page < 1 {
  270. page = 1
  271. }
  272. if size < 1 {
  273. size = 10
  274. }
  275. start := (page - 1) * size
  276. stop := page*size - 1
  277. return start, stop
  278. }
  279. func ReportProduceList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  280. page, size, query := UtilQueryPageSize(c)
  281. // 条件处理
  282. // 获取采购单符合条件的信息
  283. return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  284. CollectName: repo.CollectionBillProduce,
  285. Query: handleReportQuery(query),
  286. Page: page,
  287. Size: size,
  288. })
  289. }
  290. // 采购单
  291. func ReportPurchaseList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  292. page, size, query := UtilQueryPageSize(c)
  293. return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  294. CollectName: repo.CollectionBillPurchase,
  295. Query: handleReportQuery(query),
  296. Page: page,
  297. Size: size,
  298. })
  299. }
  300. func ReportProductList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  301. page, size, query := UtilQueryPageSize(c)
  302. return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  303. CollectName: repo.CollectionBillProduct,
  304. Query: handleReportQuery(query),
  305. Page: page,
  306. Size: size,
  307. })
  308. }