subscribe_controller.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. package order
  2. import (
  3. logger "eta/eta_mini_ht_api/common/component/log"
  4. "eta/eta_mini_ht_api/common/exception"
  5. "eta/eta_mini_ht_api/common/utils/page"
  6. "eta/eta_mini_ht_api/controllers"
  7. "eta/eta_mini_ht_api/service/facade"
  8. "eta/eta_mini_ht_api/service/order"
  9. "eta/eta_mini_ht_api/service/product"
  10. "eta/eta_mini_ht_api/service/user"
  11. "golang.org/x/time/rate"
  12. "net/http"
  13. "sync"
  14. "time"
  15. )
  16. type SubscribeController struct {
  17. controllers.ListController
  18. }
  19. var (
  20. // 初始化限流器
  21. orderRateLimiter = NewUserRateLimiter(rate.Every(5*time.Second), 1)
  22. orderNoRateLimiter = NewUserRateLimiter(rate.Every(time.Second), 1)
  23. )
  24. type UserRateLimiter struct {
  25. limiters sync.Map // 存储每个用户的限流器
  26. defaultLimiter *rate.Limiter // 默认限流器
  27. }
  28. func NewUserRateLimiter(limit rate.Limit, burst int) *UserRateLimiter {
  29. return &UserRateLimiter{
  30. defaultLimiter: rate.NewLimiter(limit, burst),
  31. }
  32. }
  33. func (url *UserRateLimiter) Allow(userID int) bool {
  34. if limiter, ok := url.limiters.Load(userID); ok {
  35. return limiter.(*rate.Limiter).Allow()
  36. }
  37. // 创建新的限流器并存储
  38. newLimiter := rate.NewLimiter(url.defaultLimiter.Limit(), url.defaultLimiter.Burst())
  39. url.limiters.Store(userID, newLimiter)
  40. return newLimiter.Allow()
  41. }
  42. func orderRateLimitFilter(userId int) (code int) {
  43. if userId <= 0 {
  44. code = http.StatusBadRequest
  45. return
  46. }
  47. if !orderRateLimiter.Allow(userId) {
  48. code = http.StatusTooManyRequests
  49. return
  50. }
  51. code = http.StatusOK
  52. return
  53. }
  54. func orderNoRateLimitFilter(userId int) (code int) {
  55. if userId <= 0 {
  56. code = http.StatusBadRequest
  57. return
  58. }
  59. if !orderNoRateLimiter.Allow(userId) {
  60. code = http.StatusTooManyRequests
  61. return
  62. }
  63. code = http.StatusOK
  64. return
  65. }
  66. const (
  67. AccountNotOpen = 430
  68. IDExpired = 431
  69. RiskUnTest = 432
  70. RiskNotMatch = 433
  71. RiskExpired = 434
  72. AccountOpening = 435
  73. orderPending = "pending"
  74. orderPaid = "paid"
  75. orderRefund = "refund"
  76. orderClosed = "closed"
  77. )
  78. // GetOrderNo 获取订单号
  79. // @Summary 获取订单号
  80. // @Description 获取订单号
  81. // @Success 200 {object} controllers.BaseResponse
  82. // @router /orderNo [get]
  83. func (sc *SubscribeController) GetOrderNo() {
  84. controllers.Wrap(&sc.BaseController, func() (result *controllers.WrapData, err error) {
  85. result = sc.InitWrapData("获取订单号失败")
  86. userInfo := sc.Data["user"].(user.User)
  87. if code := orderNoRateLimitFilter(userInfo.Id); code != 200 {
  88. err = exception.New(exception.SubscribeFailed)
  89. sc.FailedResult("操作太频繁了,请稍后再试", result)
  90. return
  91. }
  92. orderNo := order.GenerateProductOrderNo()
  93. sc.SuccessResult("获取订单号成功", orderNo, result)
  94. return
  95. })
  96. }
  97. // SubscribeProduct 订阅产品
  98. // @Summary 订阅产品
  99. // @Description 订阅产品
  100. // @Success 200 {object} controllers.BaseResponse
  101. // @router /subscribe [post]
  102. func (sc *SubscribeController) SubscribeProduct() {
  103. controllers.Wrap(&sc.BaseController, func() (result *controllers.WrapData, err error) {
  104. result = sc.InitWrapData("订阅产品失败")
  105. subscribeReq := new(SubscribeRequest)
  106. sc.GetPostParams(subscribeReq)
  107. var userInfo user.User
  108. userInfo = sc.Data["user"].(user.User)
  109. if subscribeReq.ProductId <= 0 {
  110. err = exception.New(exception.IllegalProductId)
  111. sc.FailedResult("订阅产品失败,产品编号非法", result)
  112. return
  113. }
  114. if subscribeReq.OrderNo == "" {
  115. err = exception.New(exception.IllegalOrderNo)
  116. sc.FailedResult("订阅产品失败,订单编号非法", result)
  117. return
  118. }
  119. if code := orderRateLimitFilter(userInfo.Id); code != 200 {
  120. err = exception.New(exception.SubscribeFailed)
  121. sc.FailedResult("操作太频繁了,请稍后再试", result)
  122. return
  123. }
  124. //校验是否已经购买并且在有效期内
  125. //是否开户
  126. //未开户
  127. officialUser, err := user.GetUserByTemplateUserId(userInfo.Id)
  128. if err != nil {
  129. if err.Error() == exception.GetMsg(exception.OfficialUserNotFound) {
  130. err = exception.New(exception.OfficialUserNotFound)
  131. result.Ret = AccountNotOpen
  132. sc.FailedResult("用户未开通账户", result)
  133. } else {
  134. sc.FailedResult("获取用户账户信息失败", result)
  135. }
  136. return
  137. }
  138. switch officialUser.AccountStatus {
  139. case "unopen":
  140. result.Ret = AccountNotOpen
  141. err = exception.New(exception.AccountNotOpen)
  142. sc.FailedResult("用户未开通账户", result)
  143. return
  144. case "opening":
  145. result.Ret = AccountOpening
  146. err = exception.New(exception.AccountNotOpen)
  147. sc.FailedResult("用户开户中", result)
  148. return
  149. case "opened":
  150. default:
  151. err = exception.New(exception.IllegalAccountStatus)
  152. sc.FailedResult(result.Msg, result)
  153. return
  154. }
  155. //证件信息是否过期
  156. if !officialUser.IDValid {
  157. err = exception.New(exception.IDExpired)
  158. result.Ret = IDExpired
  159. sc.FailedResult("用户证件有效期过期", result)
  160. return
  161. }
  162. //主动发起查询最新风险测评(获取失败用系统中原有的测评信息)
  163. code, err := facade.CheckUserRiskLevel(userInfo.Id, subscribeReq.ProductId, officialUser)
  164. if err != nil {
  165. result.Ret = code
  166. sc.FailedResult("校验用户风险等级失败", result)
  167. return
  168. }
  169. //创单
  170. //返回订单信息、商品信息
  171. orderInfo, err := order.CreateProductOrder(userInfo, subscribeReq.ProductId, subscribeReq.OrderNo)
  172. if err != nil {
  173. if err.Error() == exception.GetMsg(exception.DuplicateSubscribe) {
  174. sc.FailedResult("请勿重复订阅", result)
  175. return
  176. }
  177. sc.FailedResult("创建订单失败", result)
  178. return
  179. }
  180. sc.SuccessResult("订阅产品成功", orderInfo, result)
  181. return
  182. })
  183. }
  184. // SubscribeList 用户订阅列表
  185. // @Summary 用户订阅列表
  186. // @Description 用户订阅列表
  187. // @Success 200 {object} controllers.BaseResponse
  188. // @router /subscribeList [get]
  189. func (sc *SubscribeController) SubscribeList(productType string) {
  190. controllers.Wrap(&sc.BaseController, func() (result *controllers.WrapData, err error) {
  191. result = sc.InitWrapData("分页查询订阅列表失败")
  192. userInfo := sc.Data["user"].(user.User)
  193. if productType == "" || !sc.CheckProductType(productType) {
  194. err = exception.New(exception.ProductTypeError)
  195. sc.FailedResult("分页查询订阅列表失败", result)
  196. return
  197. }
  198. pageRes := page.Page{
  199. Current: sc.PageInfo.Current,
  200. PageSize: sc.PageInfo.PageSize,
  201. }
  202. pageRes.Total, pageRes.LatestId = product.GetTotalUserPageCountByProductType(productType, userInfo.Id)
  203. if err != nil {
  204. logger.Error("分页查询订阅列表失败:%v", err)
  205. sc.FailedResult("分页查询订阅列表失败", result)
  206. return
  207. }
  208. if sc.PageInfo.LatestId == 0 {
  209. sc.PageInfo.LatestId = pageRes.LatestId
  210. sc.PageInfo.Total = pageRes.Total
  211. } else {
  212. pageRes.LatestId = sc.PageInfo.LatestId
  213. pageRes.Total = sc.PageInfo.Total
  214. }
  215. pageRes.TotalPage = page.TotalPages(pageRes.Total, pageRes.PageSize)
  216. list, err := product.SubscribeList(userInfo.Id, productType, sc.PageInfo)
  217. if err != nil {
  218. sc.FailedResult("分页查询订阅列表失败", result)
  219. return
  220. }
  221. mediaList := new(page.PageResult)
  222. mediaList.Data = list
  223. mediaList.Page = pageRes
  224. sc.SuccessResult("分页查询订阅列表成功", mediaList, result)
  225. return
  226. })
  227. }
  228. type SubscribeRequest struct {
  229. ProductId int `json:"productId"`
  230. OrderNo string `json:"orderNo"`
  231. }