api_util.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package utils
  2. import (
  3. "context"
  4. "log"
  5. "sfbase/global"
  6. "sfis/db"
  7. "sfis/lock"
  8. "sfis/model"
  9. "sfis/model/response"
  10. "strings"
  11. "time"
  12. "github.com/gin-gonic/gin"
  13. "go.uber.org/zap"
  14. )
  15. func Check(appID string, productID int, c *gin.Context, getData func() ([]map[string]interface{}, int, error), param, ip string) {
  16. lock.MainLock.Lock()
  17. userLock := lock.UserLockMap[appID]
  18. lock.MainLock.Unlock()
  19. var err error
  20. datas := []map[string]interface{}{}
  21. orderCode := ""
  22. errStr := ""
  23. /**
  24. 第二步:用户接口产品校验-加锁处理
  25. */
  26. //2.1 取用户接口状态校验-可加锁也可不加锁 这个没有太严谨
  27. //userLock.Lock()
  28. userProduct := &model.UserProduct{}
  29. db.GetSFISDB().First(userProduct, &model.UserProduct{AppID: appID, ProductID: productID})
  30. //userLock.Unlock()
  31. if userProduct.ID == 0 {
  32. response.FailWithDetailed(response.InterfaceDeleted, nil, "该用户接口未购买", c)
  33. return
  34. } else if userProduct.InterfaceStatus != 0 {
  35. response.FailWithDetailed(response.InterfaceDeleted, nil, "该用户接口暂不提供服务", c)
  36. return
  37. }
  38. //2.2 取用户(产品余量|钱包账户余额)校验-必须加锁
  39. costModel := userProduct.CostModel //扣费模式 0扣余量,1-扣余额
  40. product := GetProductByID(productID)
  41. userLock.Lock()
  42. log.Println(param + "锁住......")
  43. //
  44. // ctx, _ := context.WithTimeout(c, 20*time.Second)
  45. // go func() {
  46. // var i = 0
  47. // for {
  48. // select {
  49. // case <-ctx.Done():
  50. // userLock.Unlock()
  51. // return
  52. // case <-time.After(time.Second * time.Duration(2)):
  53. // i++
  54. // if i == 10 {
  55. // userLock.Unlock()
  56. // return
  57. // }
  58. // continue
  59. // }
  60. // }
  61. // }()
  62. // time.Sleep(time.Second * time.Duration(25))
  63. //
  64. db.GetSFISDB().First(userProduct, &model.UserProduct{AppID: appID, ProductID: productID})
  65. // costModel = 0
  66. switch costModel {
  67. case 0:
  68. //按剩余量扣费
  69. datas, orderCode, err, errStr = costByLeftNum(getData, appID, productID, userProduct, product, param, ip)
  70. case 1:
  71. //按账户钱包余额扣费
  72. datas, orderCode, err, errStr = costByAccountBalance(getData, appID, productID, userProduct, product, param, ip)
  73. case 2:
  74. //优先扣剩余量,剩余量为0,扣钱包余额
  75. }
  76. userLock.Unlock()
  77. log.Println(param + "解锁......")
  78. if err == nil {
  79. db.GetQyfw().Save("user_data", map[string]interface{}{
  80. "app_id": appID,
  81. "result_num": len(datas),
  82. "result_content": datas,
  83. "order_code": orderCode,
  84. "status": 200,
  85. "user_product_id": userProduct.ID,
  86. "create_at": time.Now().Unix(),
  87. })
  88. response.FailWithDetailed(response.SUCCESS, datas, "OK", c)
  89. } else {
  90. if strings.Contains(errStr, "不足") {
  91. response.FailWithDetailed(response.LeftNumEmpty, nil, errStr, c)
  92. } else {
  93. global.Logger.Error("数据库操作失败", zap.Any("error:", err))
  94. response.FailWithDetailed(response.QueryError, nil, "内部错误", c)
  95. }
  96. }
  97. }