智盟项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

327 lines
8.6 KiB

  1. package hdl
  2. import (
  3. "applet/app/db"
  4. "applet/app/db/model"
  5. "applet/app/e"
  6. "applet/app/enum"
  7. "applet/app/lib/validate"
  8. "applet/app/md"
  9. "applet/app/svc"
  10. "applet/app/utils"
  11. "github.com/360EntSecGroup-Skylar/excelize"
  12. "github.com/gin-gonic/gin"
  13. "github.com/shopspring/decimal"
  14. "strconv"
  15. "time"
  16. )
  17. func QrcodeBatchList(c *gin.Context) {
  18. var req md.QrcodeBatchListReq
  19. err := c.ShouldBindJSON(&req)
  20. if err != nil {
  21. err = validate.HandleValidateErr(err)
  22. err1 := err.(e.E)
  23. e.OutErr(c, err1.Code, err1.Error())
  24. return
  25. }
  26. qrcodeBatchDb := db.QrcodeBatchDb{}
  27. qrcodeBatchDb.Set()
  28. list, total, err := qrcodeBatchDb.List(req.Page, req.Limit)
  29. if err != nil {
  30. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  31. return
  32. }
  33. qrcodeTotalNums, waitUseQrcodeNums, alreadyUseQrcodeNums, allowCreateQrcodeNums, err := svc.StatisticsQrcodeData()
  34. if err != nil {
  35. e.OutErr(c, e.ERR, err.Error())
  36. return
  37. }
  38. e.OutSuc(c, map[string]interface{}{
  39. "list": list,
  40. "total": total,
  41. "batch_state_list": []map[string]interface{}{
  42. {
  43. "name": enum.QrcodeBatchState(enum.QrcodeBatchStateForUseIng).String(),
  44. "value": enum.QrcodeBatchStateForUseIng,
  45. },
  46. {
  47. "name": enum.QrcodeBatchState(enum.QrcodeBatchStateForUseAlready).String(),
  48. "value": enum.QrcodeBatchStateForUseAlready,
  49. },
  50. {
  51. "name": enum.QrcodeBatchState(enum.QrcodeBatchStateForExpire).String(),
  52. "value": enum.QrcodeBatchStateForExpire,
  53. },
  54. {
  55. "name": enum.QrcodeBatchState(enum.QrcodeBatchStateForCancel).String(),
  56. "value": enum.QrcodeBatchStateForCancel,
  57. },
  58. },
  59. "statistics_qrcode_data": map[string]interface{}{
  60. "qrcode_total_nums": qrcodeTotalNums,
  61. "wait_use_qrcode_nums": waitUseQrcodeNums,
  62. "already_use_qrcode_nums": alreadyUseQrcodeNums,
  63. "allow_create_qrcode_nums": allowCreateQrcodeNums,
  64. },
  65. }, nil)
  66. return
  67. }
  68. func QrcodeBatchAdd(c *gin.Context) {
  69. var req md.QrcodeBatchAddReq
  70. err := c.ShouldBindJSON(&req)
  71. if err != nil {
  72. err = validate.HandleValidateErr(err)
  73. err1 := err.(e.E)
  74. e.OutErr(c, err1.Code, err1.Error())
  75. return
  76. }
  77. var totalNum int
  78. var totalAmount decimal.Decimal
  79. for _, v := range req.List {
  80. totalNum += v.Num
  81. amount, _ := decimal.NewFromString(v.Amount)
  82. num := decimal.NewFromInt(int64(v.Num))
  83. totalAmount = totalAmount.Add(amount.Mul(num))
  84. }
  85. session := db.Db.NewSession()
  86. defer session.Close()
  87. session.Begin()
  88. now := time.Now()
  89. //1、新增批次数据 `qrcode_batch`
  90. var qrcodeBatch = model.QrcodeBatch{
  91. Name: req.Name,
  92. TotalNum: totalNum,
  93. TotalAmount: totalAmount.String(),
  94. State: enum.QrcodeBatchStateForUseIng,
  95. ExpireDate: req.ExpireDate,
  96. Memo: req.Memo,
  97. CreateAt: now.Format("2006-01-02 15:04:05"),
  98. UpdateAt: now.Format("2006-01-02 15:04:05"),
  99. }
  100. qrcodeBatchDb := db.QrcodeBatchDb{}
  101. err = qrcodeBatchDb.AddBySession(session, &qrcodeBatch)
  102. if err != nil {
  103. _ = session.Rollback()
  104. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  105. return
  106. }
  107. //2、获取 qrcode 表中是否有可用二维码
  108. qrcodeDb := db.QrcodeDb{}
  109. qrcodeDb.Set()
  110. _, allowUseQrcodeTotal, err := qrcodeDb.FindQrcodeForAllowUse()
  111. if err != nil {
  112. _ = session.Rollback()
  113. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  114. return
  115. }
  116. diffQrcodeNum := totalNum - int(allowUseQrcodeTotal)
  117. if diffQrcodeNum > 0 {
  118. //TODO::为避免频繁请求微信二维码接口
  119. if diffQrcodeNum > 1000 {
  120. e.OutErr(c, e.ERR, "为保证二维码数据准确性,每批次新增二维码不宜操过1000张")
  121. return
  122. }
  123. //3、不够用,新增二维码
  124. err := svc.CreateQrcode(diffQrcodeNum)
  125. if err != nil {
  126. _ = session.Rollback()
  127. e.OutErr(c, e.ERR, err.Error())
  128. return
  129. }
  130. }
  131. //4、生成 "二维码-批次" 记录
  132. err = svc.OperateQrcode(qrcodeBatch.Id, totalNum, req, session)
  133. if err != nil {
  134. _ = session.Rollback()
  135. e.OutErr(c, e.ERR, err.Error())
  136. return
  137. }
  138. err = session.Commit()
  139. if err != nil {
  140. _ = session.Rollback()
  141. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  142. return
  143. }
  144. e.OutSuc(c, "success", nil)
  145. return
  146. }
  147. func GetBatchAddName(c *gin.Context) {
  148. var name = "第【1】批"
  149. qrcodeBatchDb := db.QrcodeBatchDb{}
  150. qrcodeBatchDb.Set()
  151. qrcodeBatch, err := qrcodeBatchDb.GeLastId()
  152. if err != nil {
  153. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  154. return
  155. }
  156. if qrcodeBatch != nil {
  157. name = "第【" + utils.IntToStr(qrcodeBatch.Id+1) + "】批"
  158. }
  159. e.OutSuc(c, map[string]string{
  160. "name": name,
  161. }, nil)
  162. return
  163. }
  164. func QrcodeBatchDetail(c *gin.Context) {
  165. batchId := c.DefaultQuery("id", "")
  166. qrcodeBatchDb := db.QrcodeBatchDb{}
  167. qrcodeBatchDb.Set()
  168. qrcodeBatch, err := qrcodeBatchDb.GetQrcodeBatchById(utils.StrToInt(batchId))
  169. if err != nil {
  170. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  171. return
  172. }
  173. if qrcodeBatch == nil {
  174. e.OutErr(c, e.ERR_NO_DATA, "未查询到对应的批次记录")
  175. return
  176. }
  177. qrcodeWithBatchRecordsDb := db.QrcodeWithBatchRecordsDb{}
  178. qrcodeWithBatchRecordsDb.Set()
  179. data, _, err := qrcodeWithBatchRecordsDb.FindQrcodeWithBatchRecordsById(utils.StrToInt(batchId))
  180. if err != nil {
  181. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  182. return
  183. }
  184. var list = map[string]*md.QrcodeBatchAddReqListDetail{}
  185. for _, v := range data {
  186. if list[v.Amount] == nil {
  187. list[v.Amount] = &md.QrcodeBatchAddReqListDetail{}
  188. }
  189. list[v.Amount].Num++
  190. list[v.Amount].Amount = v.Amount
  191. switch v.State {
  192. case enum.QrcodeWithBatchRecordsStateForWait:
  193. list[v.Amount].WaitUseNum++
  194. break
  195. case enum.QrcodeWithBatchRecordsStateForAlready:
  196. list[v.Amount].UsedNum++
  197. break
  198. case enum.QrcodeWithBatchRecordsStateForExpire:
  199. list[v.Amount].ExpiredNum++
  200. break
  201. case enum.QrcodeWithBatchRecordsStateForCancel:
  202. list[v.Amount].CancelNum++
  203. break
  204. }
  205. }
  206. var resultList []*md.QrcodeBatchAddReqListDetail
  207. for _, v := range list {
  208. resultList = append(resultList, v)
  209. }
  210. e.OutSuc(c, map[string]interface{}{
  211. "info": qrcodeBatch,
  212. "list": resultList,
  213. }, nil)
  214. return
  215. }
  216. func QrcodeBatchDelete(c *gin.Context) {
  217. batchId := c.Param("id")
  218. session := db.Db.NewSession()
  219. defer session.Close()
  220. session.Begin()
  221. //1、删除 `qrcode_batch` 记录
  222. qrcodeBatchDb := db.QrcodeBatchDb{}
  223. qrcodeBatchDb.Set()
  224. _, err := qrcodeBatchDb.DeleteQrcodeBatchBySession(session, utils.StrToInt(batchId))
  225. if err != nil {
  226. _ = session.Rollback()
  227. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  228. return
  229. }
  230. //2、将所关联的 `qrcode` 状态改为 "可用"
  231. qrcodeWithBatchRecordsDb := db.QrcodeWithBatchRecordsDb{}
  232. qrcodeWithBatchRecordsDb.Set()
  233. data, _, err := qrcodeWithBatchRecordsDb.FindQrcodeWithBatchRecordsById(utils.StrToInt(batchId))
  234. if err != nil {
  235. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  236. return
  237. }
  238. var updateQrcodeIds []int
  239. for _, v := range data {
  240. updateQrcodeIds = append(updateQrcodeIds, v.QrcodeId)
  241. }
  242. qrcodeDb := db.QrcodeDb{}
  243. qrcodeDb.Set()
  244. _, err = qrcodeDb.BatchUpdateQrcodeBySession(session, updateQrcodeIds, enum.QrcodeSateAllowUse)
  245. if err != nil {
  246. _ = session.Rollback()
  247. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  248. return
  249. }
  250. //3、删除 `qrcode_with_batch_records` 记录
  251. _, err = qrcodeWithBatchRecordsDb.DeleteQrcodeWithBatchRecordsBySession(session, utils.StrToInt(batchId))
  252. if err != nil {
  253. _ = session.Rollback()
  254. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  255. return
  256. }
  257. err = session.Commit()
  258. if err != nil {
  259. _ = session.Rollback()
  260. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  261. return
  262. }
  263. e.OutSuc(c, "success", nil)
  264. return
  265. }
  266. func QrcodeBatchDownload(c *gin.Context) {
  267. batchId := c.DefaultQuery("id", "")
  268. qrcodeBatchDb := db.QrcodeBatchDb{}
  269. qrcodeBatchDb.Set()
  270. qrcodeBatch, err := qrcodeBatchDb.GetQrcodeBatchById(utils.StrToInt(batchId))
  271. if err != nil {
  272. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  273. return
  274. }
  275. if qrcodeBatch == nil {
  276. e.OutErr(c, e.ERR_NO_DATA, "未查询到对应的批次记录")
  277. return
  278. }
  279. qrcodeWithBatchRecordsDb := db.QrcodeWithBatchRecordsDb{}
  280. qrcodeWithBatchRecordsDb.Set()
  281. data, _, err := qrcodeWithBatchRecordsDb.FindQrcodeWithBatchRecordsLeftJoinQrcode(utils.StrToInt(batchId))
  282. if err != nil {
  283. e.OutErr(c, e.ERR_DB_ORM, err.Error())
  284. return
  285. }
  286. titleList := []string{"批次", "有效期", "金额", "二维码地址"}
  287. xlsx := excelize.NewFile()
  288. xlsx.SetSheetRow("Sheet1", "A1", &titleList)
  289. //表头被第一行用了,只能从第二行开始
  290. j := 2
  291. for _, vv := range data {
  292. xlsx.SetSheetRow("Sheet1", "A"+strconv.Itoa(j), &[]interface{}{qrcodeBatch.Name, qrcodeBatch.ExpireDate, vv.Amount, vv.Url})
  293. j++
  294. }
  295. //if err := xlsx.SaveAs(qrcodeBatch.Name + ".xlsx"); err != nil {
  296. // e.OutErr(c, e.ERR, err.Error())
  297. // return
  298. //}
  299. c.Header("Content-Type", "application/octet-stream")
  300. c.Header("Content-Disposition", "attachment; filename="+qrcodeBatch.Name+".xlsx")
  301. c.Header("Content-Transfer-Encoding", "binary")
  302. //回写到web 流媒体 形成下载
  303. _ = xlsx.Write(c.Writer)
  304. return
  305. }