report.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901
  1. package api
  2. import (
  3. "archive/zip"
  4. "box-cost/db/model"
  5. "box-cost/db/repo"
  6. "errors"
  7. "fmt"
  8. "io"
  9. "os"
  10. "path/filepath"
  11. "regexp"
  12. "strings"
  13. "sync"
  14. "time"
  15. "github.com/gin-gonic/gin"
  16. "github.com/go-redis/redis/v8"
  17. "github.com/xuri/excelize/v2"
  18. "go.mongodb.org/mongo-driver/bson"
  19. "go.mongodb.org/mongo-driver/bson/primitive"
  20. )
  21. // 统计报表 按时间范围,供应商 包装-计划(多选) 维度进行过滤,形成报表。可以下载
  22. func Report(r *GinRouter) {
  23. // 加工列表
  24. r.GETJWT("/report/produce/list", ReportProduceList)
  25. // 采购列表
  26. r.GETJWT("/report/purchase/list", ReportPurchaseList)
  27. r.GETJWT("/report/product/list", ReportProductList)
  28. r.GETJWT("/report/list", ReportList)
  29. r.GETJWT("/report/download", ReportListDownload)
  30. //
  31. r.GETJWT("/report/bills/download", ReportBillsDownload1)
  32. }
  33. // 下载单据
  34. func ReportBillsDownload1(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  35. _, _, query := UtilQueryPageSize(c)
  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. }, &purchases)
  44. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  45. CollectName: repo.CollectionBillProduce,
  46. Query: filtter,
  47. }, &produces)
  48. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  49. CollectName: repo.CollectionBillProduct,
  50. Query: filtter,
  51. }, &products)
  52. // 加入redis有序集合中进行排序
  53. // 把对应type_id:对象存入map中避免再次查询表
  54. typeBills := map[string]interface{}{}
  55. redisCli := apictx.Svc.Redis
  56. reportBillKey := "report-bill-list:" + apictx.User.Parent
  57. isExist := redisCli.Exists(apictx.CreateRepoCtx().Ctx, reportBillKey).Val()
  58. // 不存在这个key时
  59. if isExist < 1 {
  60. if len(purchases) > 0 {
  61. for _, purchase := range purchases {
  62. member := "purchase_" + purchase.Id.Hex()
  63. score := purchase.CompleteTime.Unix()
  64. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  65. typeBills[member] = purchase
  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. typeBills[member] = produce
  74. }
  75. }
  76. if len(products) > 0 {
  77. for _, product := range products {
  78. member := "product_" + product.Id.Hex()
  79. score := product.CompleteTime.Unix()
  80. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  81. typeBills[member] = product
  82. }
  83. }
  84. // 设置过期时间
  85. redisCli.Expire(apictx.CreateRepoCtx().Ctx, reportBillKey, 1*time.Second)
  86. }
  87. total, err := redisCli.ZCard(apictx.CreateRepoCtx().Ctx, reportBillKey).Uint64()
  88. fmt.Println("单据总数量: ", total)
  89. if err != nil {
  90. fmt.Println(err)
  91. return nil, err
  92. }
  93. reports, err := redisCli.ZRevRange(apictx.CreateRepoCtx().Ctx, reportBillKey, 0, -1).Result()
  94. if err != nil {
  95. return nil, err
  96. }
  97. if len(reports) < 1 {
  98. return nil, errors.New("没有单据信息")
  99. }
  100. // 获取供应商名称
  101. // supplier := &model.Supplier{}
  102. // repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  103. // CollectName: repo.CollectionSupplier,
  104. // Query: repo.Map{"_id": supplierId},
  105. // Project: []string{"name"},
  106. // }, supplier)
  107. ct := time.Now().Format("20060102150405")
  108. // 下载文件的名字
  109. eName := fmt.Sprintf("统计单据_%s", ct)
  110. companyName := getCompanyName(apictx)
  111. f := excelize.NewFile()
  112. f.SetDefaultFont("宋体")
  113. flagIndex := -1
  114. // 采购 加工 加工-印刷 加工-覆膜 成品采购
  115. typeRows := []int{0, 0, 0, 0, 0}
  116. for _, tId := range reports {
  117. tidArr := strings.Split(tId, "_")
  118. var billExcel IExcel
  119. // 采购
  120. if tidArr[0] == "purchase" {
  121. purchase := typeBills[tidArr[1]].(*model.PurchaseBill)
  122. sheetName := "采购单"
  123. index := f.NewSheet(sheetName)
  124. if flagIndex < 0 {
  125. flagIndex = index
  126. }
  127. billExcel = NewPurchaseBill(f)
  128. billExcel.SetSheetName(sheetName)
  129. // 获取签名信息
  130. if purchase.Reviewed == 1 {
  131. if len(purchase.SignUsers) > 0 {
  132. signs := []*model.Signature{}
  133. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  134. CollectName: repo.CollectionSignature,
  135. Query: repo.Map{"_id": bson.M{"$in": purchase.SignUsers}},
  136. Sort: bson.M{"sort": 1},
  137. }, &signs)
  138. billExcel.SetSignatures(signs)
  139. }
  140. }
  141. // 获取计划名
  142. // plan := &model.ProductPlan{}
  143. // repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  144. // CollectName: repo.CollectionProductPlan,
  145. // Query: repo.Map{"_id": purchase.PlanId},
  146. // Project: []string{"name"},
  147. // }, plan)
  148. // productName = purchase.ProductName
  149. // supplierName = purchase.Supplier
  150. // serialNumber = purchase.SerialNumber
  151. billExcel.SetContent(purchase)
  152. billExcel.SetTitle(fmt.Sprintf("%s原材料采购单", companyName))
  153. billExcel.SetRow(typeRows[0])
  154. billExcel.Draws()
  155. typeRows[0] = billExcel.GetRow() + 5
  156. }
  157. // 加工单
  158. if tidArr[0] == "produce" {
  159. produce := typeBills[tidArr[1]].(*model.ProduceBill)
  160. sheetName := "加工单"
  161. if produce.IsPrint {
  162. sheetName = "加工单-印刷"
  163. } else if produce.IsLam {
  164. sheetName = "加工单-覆膜"
  165. }
  166. index := f.NewSheet(sheetName)
  167. if flagIndex < 0 {
  168. flagIndex = index
  169. }
  170. billExcel = NewPurchaseBill(f)
  171. billExcel.SetSheetName(sheetName)
  172. // 获取签名信息
  173. if produce.Reviewed == 1 {
  174. if len(produce.SignUsers) > 0 {
  175. signs := []*model.Signature{}
  176. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  177. CollectName: repo.CollectionSignature,
  178. Query: repo.Map{"_id": bson.M{"$in": produce.SignUsers}},
  179. Sort: bson.M{"sort": 1},
  180. }, &signs)
  181. billExcel.SetSignatures(signs)
  182. }
  183. }
  184. // 获取计划名
  185. // plan := &model.ProductPlan{}
  186. // repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  187. // CollectName: repo.CollectionProductPlan,
  188. // Query: repo.Map{"_id": produce.PlanId},
  189. // Project: []string{"name"},
  190. // }, plan)
  191. billExcel.SetContent(produce)
  192. billExcel.SetTitle(fmt.Sprintf("%s加工单", companyName))
  193. if produce.IsPrint {
  194. billExcel.SetRow(typeRows[2])
  195. billExcel.Draws()
  196. typeRows[2] = billExcel.GetRow() + 5
  197. } else if produce.IsLam {
  198. billExcel.SetRow(typeRows[3])
  199. billExcel.Draws()
  200. typeRows[3] = billExcel.GetRow() + 5
  201. } else {
  202. billExcel.SetRow(typeRows[1])
  203. billExcel.Draws()
  204. typeRows[1] = billExcel.GetRow() + 5
  205. }
  206. }
  207. // 成品
  208. if tidArr[0] == "product" {
  209. product := typeBills[tidArr[1]].(*model.ProductBill)
  210. sheetName := "成品采购单"
  211. index := f.NewSheet(sheetName)
  212. if flagIndex < 0 {
  213. flagIndex = index
  214. }
  215. billExcel = NewPurchaseBill(f)
  216. billExcel.SetSheetName(sheetName)
  217. // 获取签名信息
  218. if product.Reviewed == 1 {
  219. if len(product.SignUsers) > 0 {
  220. signs := []*model.Signature{}
  221. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  222. CollectName: repo.CollectionSignature,
  223. Query: repo.Map{"_id": bson.M{"$in": product.SignUsers}},
  224. Sort: bson.M{"sort": 1},
  225. }, &signs)
  226. billExcel.SetSignatures(signs)
  227. }
  228. }
  229. // 获取计划名
  230. // plan := &model.ProductPlan{}
  231. // repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  232. // CollectName: repo.CollectionProductPlan,
  233. // Query: repo.Map{"_id": product.PlanId},
  234. // Project: []string{"name"},
  235. // }, plan)
  236. billExcel.SetContent(product)
  237. billExcel.SetTitle(companyName)
  238. billExcel.SetRow(typeRows[4])
  239. billExcel.Draws()
  240. typeRows[4] = billExcel.GetRow() + 5
  241. }
  242. }
  243. // 设置活跃sheet
  244. f.SetActiveSheet(flagIndex)
  245. // 删除默认Sheet1
  246. f.DeleteSheet("Sheet1")
  247. c.Header("Content-Type", "application/octet-stream")
  248. c.Header("Content-Disposition", "attachment; filename="+fmt.Sprintf("%s.xlsx", eName))
  249. c.Header("Content-Transfer-Encoding", "binary")
  250. f.Write(c.Writer)
  251. return nil, nil
  252. }
  253. // 下载单据
  254. //
  255. // !更改为ReportBillsDownload1 确定不需要后删除
  256. func ReportBillsDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  257. _, _, query := UtilQueryPageSize(c)
  258. // supplierId := primitive.NilObjectID
  259. // if _supplierId, ok := query["supplierId"]; ok {
  260. // supplierId, _ = primitive.ObjectIDFromHex(_supplierId.(string))
  261. // }
  262. _isPdf := "false"
  263. if isPdf, ok := query["isPdf"]; ok {
  264. delete(query, "isPdf")
  265. if isPdf.(string) == "true" {
  266. _isPdf = "true"
  267. }
  268. }
  269. // timeRange := []interface{}{}
  270. // if _timeRange, ok := query["timeRange"]; ok {
  271. // timeRange, _ = _timeRange.([]interface{})
  272. // }
  273. filtter := handleReportQuery(query)
  274. purchases := []*model.PurchaseBill{}
  275. produces := []*model.ProduceBill{}
  276. products := []*model.ProductBill{}
  277. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  278. CollectName: repo.CollectionBillPurchase,
  279. Query: filtter,
  280. }, &purchases)
  281. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  282. CollectName: repo.CollectionBillProduce,
  283. Query: filtter,
  284. }, &produces)
  285. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  286. CollectName: repo.CollectionBillProduct,
  287. Query: filtter,
  288. }, &products)
  289. // 加入redis有序集合中进行排序
  290. // 把对应type_id:对象存入map中避免再次查询表
  291. typeBills := map[string]interface{}{}
  292. redisCli := apictx.Svc.Redis
  293. reportBillKey := "report-bill-list:" + apictx.User.Parent
  294. isExist := redisCli.Exists(apictx.CreateRepoCtx().Ctx, reportBillKey).Val()
  295. // 不存在这个key时
  296. if isExist < 1 {
  297. if len(purchases) > 0 {
  298. for _, purchase := range purchases {
  299. member := "purchase_" + purchase.Id.Hex()
  300. score := purchase.CompleteTime.Unix()
  301. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  302. typeBills[member] = purchase
  303. }
  304. }
  305. if len(produces) > 0 {
  306. for _, produce := range produces {
  307. member := "produce_" + produce.Id.Hex()
  308. score := produce.CompleteTime.Unix()
  309. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  310. typeBills[member] = produce
  311. }
  312. }
  313. if len(products) > 0 {
  314. for _, product := range products {
  315. member := "product_" + product.Id.Hex()
  316. score := product.CompleteTime.Unix()
  317. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  318. typeBills[member] = product
  319. }
  320. }
  321. // 设置过期时间
  322. redisCli.Expire(apictx.CreateRepoCtx().Ctx, reportBillKey, 1*time.Second)
  323. }
  324. total, err := redisCli.ZCard(apictx.CreateRepoCtx().Ctx, reportBillKey).Uint64()
  325. fmt.Println("单据总数量: ", total)
  326. if err != nil {
  327. fmt.Println(err)
  328. return nil, err
  329. }
  330. reports, err := redisCli.ZRevRange(apictx.CreateRepoCtx().Ctx, reportBillKey, 0, -1).Result()
  331. if err != nil {
  332. return nil, err
  333. }
  334. if len(reports) < 1 {
  335. return nil, errors.New("没有单据信息")
  336. }
  337. // 获取供应商名称
  338. // supplier := &model.Supplier{}
  339. // repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  340. // CollectName: repo.CollectionSupplier,
  341. // Query: repo.Map{"_id": supplierId},
  342. // Project: []string{"name"},
  343. // }, supplier)
  344. r := regexp.MustCompile(`/`)
  345. ct := time.Now().Format("20060102150405")
  346. zipName := fmt.Sprintf("统计单据_%s", ct)
  347. // 获取订单信息下载
  348. saveTmpDir := fmt.Sprintf("tmp1/report/%s", zipName)
  349. if isExistDir(saveTmpDir) {
  350. os.RemoveAll(saveTmpDir)
  351. }
  352. // 记录文件数量
  353. var wg sync.WaitGroup
  354. c1 := make(chan int, 10)
  355. for _, tId := range reports {
  356. productName := ""
  357. supplierName := ""
  358. serialNumber := ""
  359. f := excelize.NewFile()
  360. index := f.NewSheet("Sheet1")
  361. f.SetActiveSheet(index)
  362. f.SetDefaultFont("宋体")
  363. tidArr := strings.Split(tId, "_")
  364. var billExcel IExcel
  365. // 采购
  366. if tidArr[0] == "purchase" {
  367. purchase := typeBills[tId].(*model.PurchaseBill)
  368. billExcel = NewPurchaseBill(f)
  369. // 获取签名信息
  370. if purchase.Reviewed == 1 {
  371. if len(purchase.SignUsers) > 0 {
  372. signs := []*model.Signature{}
  373. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  374. CollectName: repo.CollectionSignature,
  375. Query: repo.Map{"_id": bson.M{"$in": purchase.SignUsers}},
  376. Sort: bson.M{"sort": 1},
  377. }, &signs)
  378. billExcel.SetSignatures(signs)
  379. }
  380. }
  381. // 获取计划名
  382. plan := &model.ProductPlan{}
  383. repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  384. CollectName: repo.CollectionProductPlan,
  385. Query: repo.Map{"_id": purchase.PlanId},
  386. Project: []string{"name"},
  387. }, plan)
  388. productName = purchase.ProductName
  389. supplierName = purchase.Supplier
  390. serialNumber = purchase.SerialNumber
  391. billExcel.SetContent(purchase)
  392. billExcel.SetTitle(fmt.Sprintf("%s原材料采购单", plan.Name))
  393. }
  394. // 工艺
  395. if tidArr[0] == "produce" {
  396. produce := typeBills[tId].(*model.ProduceBill)
  397. billExcel = NewProduceBill(f)
  398. if produce.Reviewed == 1 {
  399. if len(produce.SignUsers) > 0 {
  400. signs := []*model.Signature{}
  401. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  402. CollectName: repo.CollectionSignature,
  403. Query: repo.Map{"_id": bson.M{"$in": produce.SignUsers}},
  404. Sort: bson.M{"sort": 1},
  405. }, &signs)
  406. billExcel.SetSignatures(signs)
  407. }
  408. }
  409. // 获取计划名
  410. plan := &model.ProductPlan{}
  411. repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  412. CollectName: repo.CollectionProductPlan,
  413. Query: repo.Map{"_id": produce.PlanId},
  414. Project: []string{"name"},
  415. }, plan)
  416. productName = produce.ProductName
  417. supplierName = produce.Supplier
  418. serialNumber = produce.SerialNumber
  419. billExcel.SetContent(produce)
  420. billExcel.SetTitle(fmt.Sprintf("%s加工单", plan.Name))
  421. }
  422. // 成品采购
  423. if tidArr[0] == "product" {
  424. product := typeBills[tId].(*model.ProductBill)
  425. billExcel = NewProductBill(f)
  426. if product.Reviewed == 1 {
  427. if len(product.SignUsers) > 0 {
  428. signs := []*model.Signature{}
  429. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  430. CollectName: repo.CollectionSignature,
  431. Query: repo.Map{"_id": bson.M{"$in": product.SignUsers}},
  432. Sort: bson.M{"sort": 1},
  433. }, &signs)
  434. billExcel.SetSignatures(signs)
  435. }
  436. }
  437. // 获取计划名
  438. plan := &model.ProductPlan{}
  439. repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  440. CollectName: repo.CollectionProductPlan,
  441. Query: repo.Map{"_id": product.PlanId},
  442. Project: []string{"name"},
  443. }, plan)
  444. productName = product.ProductName
  445. supplierName = product.Supplier
  446. serialNumber = product.SerialNumber
  447. billExcel.SetContent(product)
  448. billExcel.SetTitle(plan.Name)
  449. }
  450. billExcel.SetIsPdf(_isPdf)
  451. billExcel.Draws()
  452. buf, _ := f.WriteToBuffer()
  453. ft := "xlsx"
  454. if _isPdf == "true" {
  455. ft = "pdf"
  456. }
  457. _productName := r.ReplaceAllString(productName, `&`)
  458. _supplierName := r.ReplaceAllString(supplierName, `&`)
  459. targePdfName := fmt.Sprintf("%s-%s-%s.%s", _supplierName, _productName, serialNumber, ft)
  460. wg.Add(1)
  461. if _isPdf == "true" {
  462. go toPdfAndSaveTask(buf, apictx.Svc.Conf.PdfApiAddr, saveTmpDir, targePdfName, c1, &wg)
  463. } else {
  464. go saveExcelToTmp(saveTmpDir, targePdfName, buf.Bytes(), c1, &wg)
  465. }
  466. }
  467. go func() {
  468. // 等待所有goroutine
  469. wg.Wait()
  470. // 关闭channel
  471. close(c1)
  472. }()
  473. // channel关闭后结束后停止遍历接收channel中的值
  474. for n := range c1 {
  475. if n == -1 {
  476. return nil, errors.New("下载失败,请重试")
  477. }
  478. }
  479. c.Header("Content-Type", "application/octet-stream")
  480. c.Header("Content-Disposition", "attachment; filename="+zipName+".zip")
  481. c.Header("Content-Transfer-Encoding", "binary")
  482. archive := zip.NewWriter(c.Writer)
  483. defer archive.Close()
  484. // 遍历路径信息
  485. filepath.Walk(saveTmpDir, func(path string, info os.FileInfo, _ error) error {
  486. // 如果是源路径,提前进行下一个遍历
  487. if path == saveTmpDir {
  488. return nil
  489. }
  490. // 获取:文件头信息
  491. header, _ := zip.FileInfoHeader(info)
  492. header.Name = strings.TrimPrefix(path, saveTmpDir+`/`)
  493. // 判断:文件是不是文件夹
  494. if info.IsDir() {
  495. header.Name += `/`
  496. } else {
  497. // 设置:zip的文件压缩算法
  498. header.Method = zip.Deflate
  499. }
  500. // 创建:压缩包头部信息
  501. writer, _ := archive.CreateHeader(header)
  502. if !info.IsDir() {
  503. file, _ := os.Open(path)
  504. defer file.Close()
  505. io.Copy(writer, file)
  506. }
  507. return nil
  508. })
  509. // 删除缓存目录
  510. os.RemoveAll(saveTmpDir)
  511. return nil, nil
  512. }
  513. // 加工单
  514. func ReportListDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  515. _, _, query := UtilQueryPageSize(c)
  516. // start, stop := CreatePageRange(page, size)
  517. supplierId := primitive.NilObjectID
  518. if _supplierId, ok := query["supplierId"]; ok {
  519. supplierId, _ = primitive.ObjectIDFromHex(_supplierId.(string))
  520. }
  521. timeRange := []interface{}{}
  522. if _timeRange, ok := query["timeRange"]; ok {
  523. timeRange, _ = _timeRange.([]interface{})
  524. }
  525. filtter := handleReportQuery(query)
  526. purchases := []*model.PurchaseBill{}
  527. produces := []*model.ProduceBill{}
  528. products := []*model.ProductBill{}
  529. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  530. CollectName: repo.CollectionBillPurchase,
  531. Query: filtter,
  532. Project: []string{"_id", "completeTime"},
  533. }, &purchases)
  534. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  535. CollectName: repo.CollectionBillProduce,
  536. Query: filtter,
  537. Project: []string{"_id", "completeTime"},
  538. }, &produces)
  539. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  540. CollectName: repo.CollectionBillProduct,
  541. Query: filtter,
  542. Project: []string{"_id", "completeTime"},
  543. }, &products)
  544. // 加入redis有序集合中
  545. redisCli := apictx.Svc.Redis
  546. reportBillKey := "report-bill-list:" + apictx.User.Parent
  547. isExist := redisCli.Exists(apictx.CreateRepoCtx().Ctx, reportBillKey).Val()
  548. // 不存在这个key时
  549. if isExist < 1 {
  550. if len(purchases) > 0 {
  551. for _, purchase := range purchases {
  552. member := "purchase_" + purchase.Id.Hex()
  553. score := purchase.CompleteTime.Unix()
  554. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  555. }
  556. }
  557. if len(produces) > 0 {
  558. for _, produce := range produces {
  559. member := "produce_" + produce.Id.Hex()
  560. score := produce.CompleteTime.Unix()
  561. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  562. }
  563. }
  564. if len(products) > 0 {
  565. for _, product := range products {
  566. member := "product_" + product.Id.Hex()
  567. score := product.CompleteTime.Unix()
  568. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  569. }
  570. }
  571. // 设置过期时间
  572. redisCli.Expire(apictx.CreateRepoCtx().Ctx, reportBillKey, 1*time.Second)
  573. }
  574. total, err := redisCli.ZCard(apictx.CreateRepoCtx().Ctx, reportBillKey).Uint64()
  575. fmt.Println(total)
  576. if err != nil {
  577. fmt.Println(err)
  578. return nil, err
  579. }
  580. reports, err := redisCli.ZRevRange(apictx.CreateRepoCtx().Ctx, reportBillKey, 0, -1).Result()
  581. if err != nil {
  582. return nil, err
  583. }
  584. if len(reports) < 1 {
  585. return nil, errors.New("没有单据信息")
  586. }
  587. lists := []map[string]interface{}{}
  588. for _, report := range reports {
  589. billArray := strings.Split(report, "_")
  590. billType := billArray[0]
  591. _billId := billArray[1]
  592. billId, _ := primitive.ObjectIDFromHex(_billId)
  593. billData := map[string]interface{}{}
  594. found := false
  595. if billType == "purchase" {
  596. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  597. CollectName: repo.CollectionBillPurchase,
  598. Query: repo.Map{"_id": billId},
  599. })
  600. }
  601. if billType == "produce" {
  602. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  603. CollectName: repo.CollectionBillProduce,
  604. Query: repo.Map{"_id": billId},
  605. })
  606. }
  607. if billType == "product" {
  608. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  609. CollectName: repo.CollectionBillProduct,
  610. Query: repo.Map{"_id": billId},
  611. })
  612. }
  613. if found {
  614. billData["billType"] = billType
  615. lists = append(lists, billData)
  616. }
  617. }
  618. f := excelize.NewFile()
  619. defer f.Close()
  620. index := f.NewSheet("Sheet1")
  621. f.SetActiveSheet(index)
  622. f.SetDefaultFont("宋体")
  623. report := NewReportExcel(f)
  624. supplier := model.Supplier{}
  625. supplierName := "【所有供应商】"
  626. if !supplierId.IsZero() {
  627. repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  628. CollectName: repo.CollectionSupplier,
  629. Query: repo.Map{"_id": supplierId},
  630. Project: []string{"name"},
  631. }, &supplier)
  632. supplierName = supplier.Name
  633. }
  634. report.SupplierName = supplierName
  635. if len(timeRange) == 2 {
  636. report.TimeRange = append(report.TimeRange, timeRange[0].(string), timeRange[1].(string))
  637. }
  638. report.Content = lists
  639. report.Draws()
  640. c.Header("Content-Type", "application/octet-stream")
  641. c.Header("Content-Disposition", "attachment; filename="+"report.xlsx")
  642. c.Header("Content-Transfer-Encoding", "binary")
  643. err = f.Write(c.Writer)
  644. if err != nil {
  645. return nil, err
  646. }
  647. return nil, nil
  648. }
  649. // 加工单
  650. func ReportList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  651. page, size, query := UtilQueryPageSize(c)
  652. start, stop := CreatePageRange(page, size)
  653. filtter := handleReportQuery(query)
  654. purchases := []*model.PurchaseBill{}
  655. produces := []*model.ProduceBill{}
  656. products := []*model.ProductBill{}
  657. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  658. CollectName: repo.CollectionBillPurchase,
  659. Query: filtter,
  660. Project: []string{"_id", "completeTime"},
  661. }, &purchases)
  662. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  663. CollectName: repo.CollectionBillProduce,
  664. Query: filtter,
  665. Project: []string{"_id", "completeTime"},
  666. }, &produces)
  667. repo.RepoDocsSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  668. CollectName: repo.CollectionBillProduct,
  669. Query: filtter,
  670. Project: []string{"_id", "completeTime"},
  671. }, &products)
  672. // 加入redis有序集合中
  673. redisCli := apictx.Svc.Redis
  674. reportBillKey := "report-bill-list:" + apictx.User.Parent
  675. isExist := redisCli.Exists(apictx.CreateRepoCtx().Ctx, reportBillKey).Val()
  676. // 不存在这个key时
  677. if isExist < 1 {
  678. if len(purchases) > 0 {
  679. for _, purchase := range purchases {
  680. member := "purchase_" + purchase.Id.Hex()
  681. score := purchase.CompleteTime.Unix()
  682. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  683. }
  684. }
  685. if len(produces) > 0 {
  686. for _, produce := range produces {
  687. member := "produce_" + produce.Id.Hex()
  688. score := produce.CompleteTime.Unix()
  689. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  690. }
  691. }
  692. if len(products) > 0 {
  693. for _, product := range products {
  694. member := "product_" + product.Id.Hex()
  695. score := product.CompleteTime.Unix()
  696. redisCli.ZAdd(apictx.CreateRepoCtx().Ctx, reportBillKey, &redis.Z{Score: float64(score), Member: member})
  697. }
  698. }
  699. // 设置过期时间
  700. redisCli.Expire(apictx.CreateRepoCtx().Ctx, reportBillKey, 1*time.Second)
  701. }
  702. total, err := redisCli.ZCard(apictx.CreateRepoCtx().Ctx, reportBillKey).Uint64()
  703. if err != nil {
  704. fmt.Println(err)
  705. return nil, err
  706. }
  707. reports, err := redisCli.ZRevRange(apictx.CreateRepoCtx().Ctx, reportBillKey, start, stop).Result()
  708. if err != nil {
  709. return nil, err
  710. }
  711. if len(reports) < 1 {
  712. return repo.PageResult{
  713. List: []map[string]interface{}{},
  714. Page: page,
  715. Size: size,
  716. Total: 0,
  717. }, nil
  718. }
  719. lists := []map[string]interface{}{}
  720. for _, report := range reports {
  721. billArray := strings.Split(report, "_")
  722. billType := billArray[0]
  723. _billId := billArray[1]
  724. billId, _ := primitive.ObjectIDFromHex(_billId)
  725. billData := map[string]interface{}{}
  726. found := false
  727. if billType == "purchase" {
  728. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  729. CollectName: repo.CollectionBillPurchase,
  730. Query: repo.Map{"_id": billId},
  731. })
  732. }
  733. if billType == "produce" {
  734. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  735. CollectName: repo.CollectionBillProduce,
  736. Query: repo.Map{"_id": billId},
  737. })
  738. }
  739. if billType == "product" {
  740. found, billData = repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  741. CollectName: repo.CollectionBillProduct,
  742. Query: repo.Map{"_id": billId},
  743. })
  744. }
  745. if found {
  746. billData["billType"] = billType
  747. lists = append(lists, billData)
  748. }
  749. }
  750. return repo.PageResult{
  751. List: lists,
  752. Total: int64(total),
  753. Page: page,
  754. Size: size,
  755. }, nil
  756. }
  757. func CreatePageRange(page, size int64) (int64, int64) {
  758. if page < 1 {
  759. page = 1
  760. }
  761. if size < 1 {
  762. size = 10
  763. }
  764. start := (page - 1) * size
  765. stop := page*size - 1
  766. return start, stop
  767. }
  768. func ReportProduceList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  769. page, size, query := UtilQueryPageSize(c)
  770. // 条件处理
  771. // 获取采购单符合条件的信息
  772. return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  773. CollectName: repo.CollectionBillProduce,
  774. Query: handleReportQuery(query),
  775. Page: page,
  776. Size: size,
  777. })
  778. }
  779. // 采购单
  780. func ReportPurchaseList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  781. page, size, query := UtilQueryPageSize(c)
  782. return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  783. CollectName: repo.CollectionBillPurchase,
  784. Query: handleReportQuery(query),
  785. Page: page,
  786. Size: size,
  787. })
  788. }
  789. func ReportProductList(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  790. page, size, query := UtilQueryPageSize(c)
  791. return repo.RepoPageSearch(apictx.CreateRepoCtx(), &repo.PageSearchOptions{
  792. CollectName: repo.CollectionBillProduct,
  793. Query: handleReportQuery(query),
  794. Page: page,
  795. Size: size,
  796. })
  797. }