simCardTaskAcceleronix.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. package simCardQueue
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fwh-toolbox-server/domain"
  6. "fwh-toolbox-server/repositories"
  7. "strconv"
  8. "strings"
  9. "time"
  10. "github.com/google/uuid"
  11. "github.com/hibiken/asynq"
  12. "go.uber.org/zap"
  13. )
  14. const (
  15. TaskTypeSimCardAcceleronixSyncOnePage = "SimCard:Acceleronix:SyncOnePage"
  16. AcceleronixSimCardInfoPageSize = 50 // Acceleronix平台每次查询页数
  17. )
  18. // 数据类型转换 AcceleronixInfo -> SimCardInfo
  19. func (processor *SimCardProcessor) acceleronixInfoToSimCardInfo(infoList []domain.AcceleronixSimCardInfoItem, dataUsage map[string]*domain.AcceleronixSimCardDataUsageInfoResponse) []domain.SimCardInfo {
  20. var simCardInfoList []domain.SimCardInfo
  21. for _, info := range infoList {
  22. var simCardInfo domain.SimCardInfo
  23. simCardInfo.GICCID = info.Iccid[:19] // 只取前19位不取检验码
  24. simCardInfo.IMEI = info.Imei
  25. simCardInfo.IMSI = info.Imsi
  26. simCardInfo.MSISDN = info.Msisdn
  27. switch info.SimState {
  28. case domain.SCS_PreActivation: // 2 预激活
  29. simCardInfo.Status = domain.SimStatusNotActivated
  30. break
  31. case domain.SCS_Test: // 3 测试
  32. simCardInfo.Status = domain.SimStatusNotActivated
  33. break
  34. case domain.SCS_Silence: // 4 沉默
  35. simCardInfo.Status = domain.SimStatusNotActivated
  36. break
  37. case domain.SCS_Standby: // 5 待机
  38. simCardInfo.Status = domain.SimStatusNotActivated
  39. break
  40. case domain.SCS_Activated: // 6 激活
  41. simCardInfo.Status = domain.SimStatusActivated
  42. break
  43. case domain.SCS_Deactivated: // 7 停机
  44. simCardInfo.Status = domain.SimStatusDeactivated
  45. break
  46. case domain.SCS_Pause: // 8 暂停
  47. simCardInfo.Status = domain.SimStatusDeactivated
  48. break
  49. case domain.SCS_PreCancellation: // 9 预注销
  50. simCardInfo.Status = domain.SimStatusDeactivated
  51. break
  52. case domain.SCS_Cancellation: // 10 注销
  53. simCardInfo.Status = domain.SimStatusRetired
  54. break
  55. default:
  56. simCardInfo.Status = domain.SimStatusUnknown
  57. break
  58. }
  59. simCardInfo.ExpirationTime = info.ExpirationTime // 到期时间(后付费卡没有到期时间) 格式:yyyy-MM-dd
  60. simCardInfo.Platform = domain.SimPlatformAcceleronix // 数据来源平台
  61. usageInfo := dataUsage[info.Iccid]
  62. if usageInfo == nil {
  63. zap.L().Warn("AcceleronixSimCardDataUsageInfo not exist.", zap.String("Iccid", info.Iccid), zap.Any("dataUsageMap", dataUsage))
  64. } else {
  65. simCardInfo.Month = usageInfo.Month // 统计月份 格式:yyyy-MM
  66. totalDataUsage, err := strconv.ParseFloat(usageInfo.TotalDataUsage, 64)
  67. if err != nil {
  68. zap.L().Warn("TotalDataUsage ParseFloat failed.", zap.String("err", err.Error()), zap.String("TotalDataUsage", usageInfo.TotalDataUsage))
  69. simCardInfo.AllDataUsage = 0
  70. } else {
  71. simCardInfo.AllDataUsage = totalDataUsage * 1024 // 月数据用量(KB)
  72. }
  73. }
  74. simCardInfo.UpdateTime = time.Now().UTC() // UTC时间
  75. simCardInfoList = append(simCardInfoList, simCardInfo)
  76. }
  77. return simCardInfoList
  78. }
  79. // 处理Acceleronix信息收集任务
  80. func (processor *SimCardProcessor) handleSimCardAcceleronixSyncOnePageTask(ctx context.Context, task *asynq.Task) error {
  81. payloadStr := task.Payload()
  82. var payload SimCardSyncOnePagePayload
  83. err := json.Unmarshal(payloadStr, &payload)
  84. if err != nil {
  85. zap.L().Error("handleSimCardAcceleronixSyncOnePageTask payload error.", zap.String("err", err.Error()), zap.String("payload", string(payloadStr)))
  86. return err
  87. }
  88. if payload.Date == "" {
  89. payload.Date = time.Now().UTC().Format(time.DateOnly)
  90. }
  91. // 请求批量查询Acceleronix批量数据信息
  92. // 查询Sim卡基本信息列表
  93. respInfoList, err := repositories.QueryAcceleronixSimCardList(uint(payload.Page), uint(payload.Size))
  94. if err != nil {
  95. zap.L().Error("handleSimCardAcceleronixSyncOnePageTask QueryAcceleronixSimCardList failed.", zap.String("err", err.Error()), zap.Uint64("page", payload.Page), zap.Uint64("size", payload.Size))
  96. return err
  97. }
  98. idList := []string{}
  99. for _, info := range respInfoList.Data.List {
  100. idList = append(idList, info.Iccid)
  101. }
  102. // 查询
  103. mouth := strings.ReplaceAll(time.Now().UTC().Format(time.DateOnly)[:7], "-", "") // 统计月份 格式:yyyyMM
  104. respUsageList, err := repositories.QueryAcceleronixBatchSimCardDataInfo(idList, mouth)
  105. if err != nil {
  106. zap.L().Error("handleSimCardAcceleronixSyncOnePageTask QueryAcceleronixBatchSimCardDataInfo failed.", zap.String("err", err.Error()), zap.Strings("idList", idList), zap.String("mouth", mouth))
  107. return err
  108. }
  109. // 生成数据用量信息map
  110. dataUsageMap := make(map[string]*domain.AcceleronixSimCardDataUsageInfoResponse)
  111. for _, info := range respUsageList {
  112. dataUsageMap[info.Iccid] = &info
  113. }
  114. // 转换数据结构
  115. infoList := processor.acceleronixInfoToSimCardInfo(respInfoList.Data.List, dataUsageMap)
  116. uuidStr := uuid.NewString()
  117. processor.putBatches(uuidStr, []simCardPageBatch{{
  118. Date: payload.Date, Pages: []domain.SimCardRunPage{{Platform: domain.SimPlatformAcceleronix, Page: payload.Page}}, Info: infoList,
  119. }})
  120. zap.L().Debug("Acceleronix get infoList.", zap.Int("len", len(infoList)))
  121. // 创建聚合组任务
  122. aggTask := asynq.NewTask(
  123. TaskTypeSimCardAggregation,
  124. []byte(uuidStr),
  125. asynq.Queue("default"),
  126. asynq.Unique(5*time.Minute),
  127. asynq.Group(GroupNameSimCardAggregation),
  128. )
  129. _, err = TaskClient.Enqueue(aggTask)
  130. if err != nil {
  131. zap.L().Error("TaskTypeSimCardAggregation Enqueue failed.", zap.String("err", err.Error()), zap.Uint64("size", payload.Size), zap.Uint64("page", payload.Page))
  132. return err
  133. }
  134. // 判断是否查完所有信息
  135. if payload.Page*payload.Size > uint64(respInfoList.Data.Total) {
  136. if err := repositories.MarkSimCardLastPage(payload.Date, domain.SimPlatformAcceleronix, payload.Page); err != nil {
  137. return err
  138. }
  139. return processor.enqueueSimCardReportIfComplete(payload.Date)
  140. }
  141. // 查询太快,间隔1s
  142. time.Sleep(time.Second)
  143. // 创建下一个任务(查询下一页)
  144. payload.Page++
  145. taskPayloadStr, err := json.Marshal(payload)
  146. nextTask := asynq.NewTask(
  147. TaskTypeSimCardAcceleronixSyncOnePage,
  148. taskPayloadStr,
  149. asynq.MaxRetry(5),
  150. asynq.Queue("default"),
  151. asynq.Timeout(time.Minute),
  152. asynq.Unique(5*time.Minute),
  153. asynq.Retention(7*24*time.Hour), // 成功后保留7天
  154. )
  155. _, err = TaskClient.Enqueue(nextTask)
  156. if err != nil {
  157. zap.L().Error("TaskTypeSimCardSyncOnePage Enqueue failed.", zap.String("err", err.Error()), zap.Uint64("size", payload.Size), zap.Uint64("page", payload.Page))
  158. return err
  159. }
  160. return nil
  161. }