summary.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. package api
  2. import (
  3. "box-cost/db/model"
  4. "box-cost/db/repo"
  5. "errors"
  6. "strings"
  7. "time"
  8. "github.com/gin-gonic/gin"
  9. "github.com/xuri/excelize/v2"
  10. "go.mongodb.org/mongo-driver/bson/primitive"
  11. )
  12. // 汇总
  13. func Summary(r *GinRouter) {
  14. // 下载详细汇总
  15. r.GET("/summary/download", SummaryDownload)
  16. // 下载简单汇总
  17. r.GET("/summary/sample/download", SummarySampleDownload)
  18. }
  19. type SupplierPlanSummary struct {
  20. Plans []*PlanSummary
  21. SupplierId primitive.ObjectID
  22. ApiSession *ApiSession
  23. }
  24. type PlanSummary struct {
  25. Plan *model.ProductPlan
  26. IsSend map[string]bool
  27. IsAck map[string]bool
  28. Reviewed map[string]int32
  29. State map[string]string
  30. CreateTimes map[string]time.Time
  31. SerialNumber map[string]string
  32. SendTo map[string]string
  33. }
  34. // /summary/download?planIds=id1,id2&supplierId=xxx
  35. func SummaryDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  36. // 获取planIds supplierId
  37. _planIds := c.Query("planIds") // id1,id2...
  38. _supplierId := c.Query("supplierId") // 供应商id
  39. planIds := strings.Split(_planIds, ",")
  40. supplierId, _ := primitive.ObjectIDFromHex(_supplierId)
  41. // 获取详情
  42. if len(planIds) < 1 {
  43. return nil, errors.New("数据不存在")
  44. }
  45. summaryPlans := []*PlanSummary{}
  46. for _, _planId := range planIds {
  47. id, _ := primitive.ObjectIDFromHex(_planId)
  48. if id.IsZero() {
  49. return nil, errors.New("非法id")
  50. }
  51. plan := &model.ProductPlan{}
  52. found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  53. CollectName: repo.CollectionProductPlan,
  54. Query: repo.Map{"_id": id},
  55. }, plan)
  56. if !found || err != nil {
  57. continue
  58. }
  59. summaryPlan := GetPlanStatus(plan, apictx)
  60. summaryPlans = append(summaryPlans, summaryPlan)
  61. }
  62. if len(summaryPlans) < 1 {
  63. return nil, errors.New("数据不存在")
  64. }
  65. // 实例化表格,传入数据
  66. f := excelize.NewFile()
  67. index := f.NewSheet("Sheet1")
  68. f.SetActiveSheet(index)
  69. f.SetDefaultFont("宋体")
  70. planSummaryExcel := NewPlanSummaryExcel(f)
  71. planSummaryExcel.Content = &SupplierPlanSummary{
  72. Plans: summaryPlans,
  73. SupplierId: supplierId,
  74. ApiSession: apictx,
  75. }
  76. // 绘制表格
  77. planSummaryExcel.Draws()
  78. c.Header("Content-Type", "application/octet-stream")
  79. c.Header("Content-Disposition", "attachment; filename="+"planSummary.xlsx")
  80. c.Header("Content-Transfer-Encoding", "binary")
  81. err := f.Write(c.Writer)
  82. if err != nil {
  83. return nil, err
  84. }
  85. return nil, nil
  86. }
  87. // /summary/sample/download?planIds=id1,id2&supplierId=xxx
  88. func SummarySampleDownload(c *gin.Context, apictx *ApiSession) (interface{}, error) {
  89. // 获取planIds supplierId
  90. _planIds := c.Query("planIds") // id1,id2...
  91. _supplierId := c.Query("supplierId") // 供应商id
  92. planIds := strings.Split(_planIds, ",")
  93. supplierId, _ := primitive.ObjectIDFromHex(_supplierId)
  94. // 获取详情
  95. if len(planIds) < 1 {
  96. return nil, errors.New("数据不存在")
  97. }
  98. summaryPlans := []*PlanSummary{}
  99. for _, _planId := range planIds {
  100. id, _ := primitive.ObjectIDFromHex(_planId)
  101. if id.IsZero() {
  102. return nil, errors.New("非法id")
  103. }
  104. plan := &model.ProductPlan{}
  105. found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  106. CollectName: repo.CollectionProductPlan,
  107. Query: repo.Map{"_id": id},
  108. }, plan)
  109. if !found || err != nil {
  110. continue
  111. }
  112. summaryPlan := GetPlanStatus(plan, apictx)
  113. summaryPlans = append(summaryPlans, summaryPlan)
  114. }
  115. if len(summaryPlans) < 1 {
  116. return nil, errors.New("数据不存在")
  117. }
  118. // 实例化表格,传入数据
  119. f := excelize.NewFile()
  120. index := f.NewSheet("Sheet1")
  121. f.SetActiveSheet(index)
  122. f.SetDefaultFont("宋体")
  123. planSummaryExcel := NewSummarySampleExcel(f)
  124. planSummaryExcel.Content = &SupplierPlanSummary{
  125. Plans: summaryPlans,
  126. SupplierId: supplierId,
  127. }
  128. // 绘制表格
  129. planSummaryExcel.Draws()
  130. c.Header("Content-Type", "application/octet-stream")
  131. c.Header("Content-Disposition", "attachment; filename="+"planSummary.xlsx")
  132. c.Header("Content-Transfer-Encoding", "binary")
  133. err := f.Write(c.Writer)
  134. if err != nil {
  135. return nil, err
  136. }
  137. return nil, nil
  138. }
  139. func GetPlanStatus(plan *model.ProductPlan, apictx *ApiSession) *PlanSummary {
  140. billStates := map[string]string{}
  141. billSerialNumber := map[string]string{}
  142. billSendTo := map[string]string{}
  143. billIsSend := map[string]bool{}
  144. billReviewed := map[string]int32{}
  145. billIsAck := map[string]bool{}
  146. billCreateTimes := map[string]time.Time{}
  147. if plan.Pack != nil && plan.Pack.Components != nil {
  148. for _, comp := range plan.Pack.Components {
  149. if comp.Stages != nil {
  150. for _, stage := range comp.Stages {
  151. if len(stage.BillId) > 0 {
  152. collectName := ""
  153. // 材料
  154. if stage.BillType == 1 {
  155. collectName = repo.CollectionBillPurchase
  156. }
  157. // 工艺
  158. if stage.BillType == 2 {
  159. collectName = repo.CollectionBillProduce
  160. }
  161. // 成品
  162. if stage.BillType == 3 {
  163. collectName = repo.CollectionBillProduct
  164. }
  165. ok, state := repo.RepoSeachDocMap(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
  166. CollectName: collectName,
  167. Query: repo.Map{"_id": stage.BillId},
  168. Project: []string{"status", "isSend", "reviewed", "isAck", "serialNumber", "sendTo", "remark", "createTime"}})
  169. if ok {
  170. billStates[stage.BillId] = state["status"].(string)
  171. billSerialNumber[stage.BillId] = state["serialNumber"].(string)
  172. if v, ok := state["sendTo"]; ok {
  173. billSendTo[stage.BillId] = v.(string)
  174. }
  175. if v, ok := state["isSend"]; ok {
  176. billIsSend[stage.BillId] = v.(bool)
  177. } else {
  178. billIsSend[stage.BillId] = false
  179. }
  180. if v, ok := state["reviewed"]; ok {
  181. billReviewed[stage.BillId] = v.(int32)
  182. } else {
  183. billReviewed[stage.BillId] = -1
  184. }
  185. if v, ok := state["isAck"]; ok {
  186. billIsAck[stage.BillId] = v.(bool)
  187. } else {
  188. billIsAck[stage.BillId] = false
  189. }
  190. if v, ok := state["createTime"]; ok {
  191. billCreateTimes[stage.BillId] = v.(primitive.DateTime).Time()
  192. }
  193. }
  194. }
  195. }
  196. }
  197. }
  198. }
  199. return &PlanSummary{
  200. Plan: plan,
  201. IsSend: billIsSend,
  202. IsAck: billIsAck,
  203. Reviewed: billReviewed,
  204. State: billStates,
  205. CreateTimes: billCreateTimes,
  206. SerialNumber: billSerialNumber,
  207. SendTo: billSendTo,
  208. }
  209. }