simCardManageRepo.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. package mongo
  2. import (
  3. "context"
  4. "fmt"
  5. "fwh-toolbox-server/database"
  6. "fwh-toolbox-server/domain"
  7. "fwh-toolbox-server/dto"
  8. "strings"
  9. "time"
  10. "go.mongodb.org/mongo-driver/bson"
  11. "go.mongodb.org/mongo-driver/mongo"
  12. "go.mongodb.org/mongo-driver/mongo/options"
  13. "go.uber.org/zap"
  14. )
  15. const (
  16. CollectionName_SimCardManage = "SimCardManage"
  17. CollectionName_SimCardMonthlyData = "SimCardMonthlyData"
  18. )
  19. // 查询SIM卡信息(批量)
  20. func GetSimCardBatchInfo(page, size uint, search string, status *string, platform *string) (*dto.ResPage[domain.SimCardInfo], error) {
  21. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  22. defer cancel()
  23. collection := database.GetCollection(CollectionName_SimCardManage)
  24. // 查询条件
  25. filter := bson.M{}
  26. // 搜索 _id (GICCID)
  27. if search != "" {
  28. filter["_id"] = bson.M{
  29. "$regex": search,
  30. "$options": "i", // 不区分大小写,可去掉
  31. }
  32. }
  33. // 过滤状态(支持逗号分隔多值)
  34. if status != nil {
  35. parts := strings.Split(*status, ",")
  36. if len(parts) == 1 {
  37. filter["status"] = bson.M{"$eq": parts[0]}
  38. } else {
  39. filter["status"] = bson.M{"$in": parts}
  40. }
  41. }
  42. // 过滤平台(支持逗号分隔多值)
  43. if platform != nil {
  44. parts := strings.Split(*platform, ",")
  45. if len(parts) == 1 {
  46. filter["platform"] = bson.M{"$eq": parts[0]}
  47. } else {
  48. filter["platform"] = bson.M{"$in": parts}
  49. }
  50. }
  51. findOptions := options.Find().
  52. SetSkip(int64((page - 1) * size)).
  53. SetLimit(int64(size)).
  54. SetSort(bson.D{
  55. {Key: "allDataUsage", Value: -1}, // 降序
  56. })
  57. cursor, err := collection.Find(ctx, filter, findOptions)
  58. if err != nil {
  59. return nil, err
  60. }
  61. defer cursor.Close(ctx)
  62. var infoList []domain.SimCardInfo
  63. for cursor.Next(ctx) {
  64. var info domain.SimCardInfo
  65. if err := cursor.Decode(&info); err != nil {
  66. return nil, err
  67. }
  68. infoList = append(infoList, info)
  69. }
  70. // 查询总数
  71. total, err := collection.CountDocuments(ctx, bson.M{})
  72. if err != nil {
  73. return nil, err
  74. }
  75. res := dto.ResPage[domain.SimCardInfo]{
  76. Data: infoList,
  77. PageSize: size,
  78. PageNum: page,
  79. Total: uint(total),
  80. }
  81. return &res, nil
  82. }
  83. // 查询SIM卡信息(单卡)
  84. func GetSimCardInfo(id string) (*domain.SimCardInfo, error) {
  85. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  86. defer cancel()
  87. collection := database.GetCollection(CollectionName_SimCardManage)
  88. var info domain.SimCardInfo
  89. err := collection.FindOne(ctx, bson.M{"_id": id}).Decode(&info)
  90. if err != nil {
  91. return nil, err
  92. }
  93. return &info, nil
  94. }
  95. // 查询SIM卡月数据(单卡)
  96. func GetSimCardMonthlyData(month string, id string) (*domain.SimCardMonthlyData, error) {
  97. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  98. defer cancel()
  99. collection := database.GetCollection(CollectionName_SimCardMonthlyData)
  100. var info domain.SimCardMonthlyData
  101. err := collection.FindOne(ctx, bson.M{"simId": id, "month": month}).Decode(&info)
  102. if err != nil {
  103. return nil, err
  104. }
  105. return &info, nil
  106. }
  107. // 插入SIM卡基本信息数据
  108. func UpdateSimCardInfo(info domain.SimCardInfo) error {
  109. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  110. defer cancel()
  111. collection := database.GetCollection(CollectionName_SimCardManage)
  112. filter := bson.M{"_id": info.GICCID} // 按ID匹配
  113. _, err := collection.ReplaceOne(ctx, filter, info, options.Replace().SetUpsert(true))
  114. if err != nil {
  115. return err
  116. }
  117. return nil
  118. }
  119. // 批量插入SIM卡基本信息数据
  120. func UpdateSimCardBatchInfo(infoList []domain.SimCardInfo) (int64, error) {
  121. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  122. defer cancel()
  123. collection := database.GetCollection(CollectionName_SimCardManage)
  124. batchSize := 1000
  125. var totalInserted int64
  126. for start := 0; start < len(infoList); start += batchSize {
  127. end := start + batchSize
  128. if end > len(infoList) {
  129. end = len(infoList)
  130. }
  131. models := make([]mongo.WriteModel, 0, end-start)
  132. for _, doc := range infoList[start:end] {
  133. model := mongo.NewReplaceOneModel().
  134. SetFilter(bson.M{
  135. "_id": doc.GICCID,
  136. }).
  137. SetReplacement(doc).
  138. SetUpsert(true)
  139. models = append(models, model)
  140. }
  141. result, err := collection.BulkWrite(
  142. ctx,
  143. models,
  144. options.BulkWrite().
  145. SetOrdered(false),
  146. )
  147. if err != nil {
  148. zap.L().Error("UpdateSimCardBatchInfo bulk insert failed.", zap.String("err", err.Error()), zap.Int("start", start), zap.Int("end", end), zap.Int64("totalInserted", totalInserted))
  149. return totalInserted, fmt.Errorf(
  150. "bulk insert failed (%d~%d): %w",
  151. start,
  152. end,
  153. err,
  154. )
  155. }
  156. totalInserted += result.InsertedCount
  157. }
  158. return totalInserted, nil
  159. }
  160. // 插入SIM卡日流量数据
  161. func UpdateSimCardDayData(data domain.SimCardDayData) error {
  162. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  163. defer cancel()
  164. collection := database.GetCollection(CollectionName_SimCardMonthlyData)
  165. dailyUsageField := fmt.Sprintf(
  166. "dailyUsage.%d",
  167. data.Day,
  168. )
  169. update := bson.M{
  170. "$set": bson.M{
  171. "allDataUsage": data.AllDataUsage,
  172. "updateTime": data.UpdateTime,
  173. dailyUsageField: data.DailyUsage,
  174. },
  175. "$setOnInsert": bson.M{
  176. "simId": data.SimId,
  177. "month": data.Month,
  178. },
  179. }
  180. filter := bson.M{"simId": data.SimId, "month": data.Month} // 按ID和month匹配
  181. _, err := collection.UpdateOne(ctx, filter, update, options.Update().SetUpsert(true))
  182. if err != nil {
  183. return err
  184. }
  185. return nil
  186. }
  187. // 批量插入SIM卡日流量数据
  188. func UpdateSimCardBatchDayData(dataList []domain.SimCardDayData) (int64, error) {
  189. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  190. defer cancel()
  191. collection := database.GetCollection(CollectionName_SimCardMonthlyData)
  192. batchSize := 1000
  193. var totalInserted int64
  194. for start := 0; start < len(dataList); start += batchSize {
  195. end := start + batchSize
  196. if end > len(dataList) {
  197. end = len(dataList)
  198. }
  199. models := make([]mongo.WriteModel, 0, end-start)
  200. for _, doc := range dataList[start:end] {
  201. dailyUsageField := fmt.Sprintf("dailyUsage.%d", doc.Day)
  202. update := bson.M{
  203. "$set": bson.M{
  204. "allDataUsage": doc.AllDataUsage,
  205. "updateTime": doc.UpdateTime,
  206. dailyUsageField: doc.DailyUsage,
  207. },
  208. "$setOnInsert": bson.M{
  209. "simId": doc.SimId,
  210. "month": doc.Month,
  211. },
  212. }
  213. model := mongo.NewUpdateOneModel().
  214. SetFilter(bson.M{
  215. "simId": doc.SimId,
  216. "month": doc.Month,
  217. }).
  218. SetUpdate(update).
  219. SetUpsert(true)
  220. models = append(models, model)
  221. }
  222. result, err := collection.BulkWrite(
  223. ctx,
  224. models,
  225. options.BulkWrite().
  226. SetOrdered(false),
  227. )
  228. if err != nil {
  229. zap.L().Error("UpdateSimCardBatchMonthlyData bulk insert failed.", zap.String("err", err.Error()), zap.Int("start", start), zap.Int("end", end), zap.Int64("totalInserted", totalInserted))
  230. return totalInserted, fmt.Errorf(
  231. "bulk insert failed (%d~%d): %w",
  232. start,
  233. end,
  234. err,
  235. )
  236. }
  237. totalInserted += result.InsertedCount
  238. }
  239. return totalInserted, nil
  240. }