123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- package order
- import (
- logger "eta/eta_mini_ht_api/common/component/log"
- "eta/eta_mini_ht_api/common/exception"
- "eta/eta_mini_ht_api/common/utils/page"
- "eta/eta_mini_ht_api/controllers"
- "eta/eta_mini_ht_api/service/facade"
- "eta/eta_mini_ht_api/service/order"
- "eta/eta_mini_ht_api/service/product"
- "eta/eta_mini_ht_api/service/user"
- "golang.org/x/time/rate"
- "net/http"
- "sync"
- "time"
- )
- type SubscribeController struct {
- controllers.ListController
- }
- var (
- // 初始化限流器
- orderRateLimiter = NewUserRateLimiter(rate.Every(5*time.Second), 1)
- orderNoRateLimiter = NewUserRateLimiter(rate.Every(time.Second), 1)
- )
- type UserRateLimiter struct {
- limiters sync.Map // 存储每个用户的限流器
- defaultLimiter *rate.Limiter // 默认限流器
- }
- func NewUserRateLimiter(limit rate.Limit, burst int) *UserRateLimiter {
- return &UserRateLimiter{
- defaultLimiter: rate.NewLimiter(limit, burst),
- }
- }
- func (url *UserRateLimiter) Allow(userID int) bool {
- if limiter, ok := url.limiters.Load(userID); ok {
- return limiter.(*rate.Limiter).Allow()
- }
- // 创建新的限流器并存储
- newLimiter := rate.NewLimiter(url.defaultLimiter.Limit(), url.defaultLimiter.Burst())
- url.limiters.Store(userID, newLimiter)
- return newLimiter.Allow()
- }
- func orderRateLimitFilter(userId int) (code int) {
- if userId <= 0 {
- code = http.StatusBadRequest
- return
- }
- if !orderRateLimiter.Allow(userId) {
- code = http.StatusTooManyRequests
- return
- }
- code = http.StatusOK
- return
- }
- func orderNoRateLimitFilter(userId int) (code int) {
- if userId <= 0 {
- code = http.StatusBadRequest
- return
- }
- if !orderNoRateLimiter.Allow(userId) {
- code = http.StatusTooManyRequests
- return
- }
- code = http.StatusOK
- return
- }
- const (
- AccountNotOpen = 430
- IDExpired = 431
- RiskUnTest = 432
- RiskNotMatch = 433
- RiskExpired = 434
- AccountOpening = 435
- orderPending = "pending"
- orderPaid = "paid"
- orderRefund = "refund"
- orderClosed = "closed"
- )
- // GetOrderNo 获取订单号
- // @Summary 获取订单号
- // @Description 获取订单号
- // @Success 200 {object} controllers.BaseResponse
- // @router /orderNo [get]
- func (sc *SubscribeController) GetOrderNo() {
- controllers.Wrap(&sc.BaseController, func() (result *controllers.WrapData, err error) {
- result = sc.InitWrapData("获取订单号失败")
- userInfo := sc.Data["user"].(user.User)
- if code := orderNoRateLimitFilter(userInfo.Id); code != 200 {
- err = exception.New(exception.SubscribeFailed)
- sc.FailedResult("操作太频繁了,请稍后再试", result)
- return
- }
- orderNo := order.GenerateProductOrderNo()
- sc.SuccessResult("获取订单号成功", orderNo, result)
- return
- })
- }
- // SubscribeProduct 订阅产品
- // @Summary 订阅产品
- // @Description 订阅产品
- // @Success 200 {object} controllers.BaseResponse
- // @router /subscribe [post]
- func (sc *SubscribeController) SubscribeProduct() {
- controllers.Wrap(&sc.BaseController, func() (result *controllers.WrapData, err error) {
- result = sc.InitWrapData("订阅产品失败")
- subscribeReq := new(SubscribeRequest)
- sc.GetPostParams(subscribeReq)
- var userInfo user.User
- userInfo = sc.Data["user"].(user.User)
- if subscribeReq.ProductId <= 0 {
- err = exception.New(exception.IllegalProductId)
- sc.FailedResult("订阅产品失败,产品编号非法", result)
- return
- }
- if subscribeReq.OrderNo == "" {
- err = exception.New(exception.IllegalOrderNo)
- sc.FailedResult("订阅产品失败,订单编号非法", result)
- return
- }
- if code := orderRateLimitFilter(userInfo.Id); code != 200 {
- err = exception.New(exception.SubscribeFailed)
- sc.FailedResult("操作太频繁了,请稍后再试", result)
- return
- }
- //校验是否已经购买并且在有效期内
- //是否开户
- //未开户
- officialUser, err := user.GetUserByTemplateUserId(userInfo.Id)
- if err != nil {
- if err.Error() == exception.GetMsg(exception.OfficialUserNotFound) {
- err = exception.New(exception.OfficialUserNotFound)
- result.Ret = AccountNotOpen
- sc.FailedResult("用户未开通账户", result)
- } else {
- sc.FailedResult("获取用户账户信息失败", result)
- }
- return
- }
- switch officialUser.AccountStatus {
- case "unopen":
- result.Ret = AccountNotOpen
- err = exception.New(exception.AccountNotOpen)
- sc.FailedResult("用户未开通账户", result)
- return
- case "opening":
- result.Ret = AccountOpening
- err = exception.New(exception.AccountNotOpen)
- sc.FailedResult("用户开户中", result)
- return
- case "opened":
- default:
- err = exception.New(exception.IllegalAccountStatus)
- sc.FailedResult(result.Msg, result)
- return
- }
- //证件信息是否过期
- if !officialUser.IDValid {
- err = exception.New(exception.IDExpired)
- result.Ret = IDExpired
- sc.FailedResult("用户证件有效期过期", result)
- return
- }
- //主动发起查询最新风险测评(获取失败用系统中原有的测评信息)
- code, err := facade.CheckUserRiskLevel(userInfo.Id, subscribeReq.ProductId, officialUser)
- if err != nil {
- result.Ret = code
- sc.FailedResult("校验用户风险等级失败", result)
- return
- }
- //创单
- //返回订单信息、商品信息
- orderInfo, err := order.CreateProductOrder(userInfo, subscribeReq.ProductId, subscribeReq.OrderNo)
- if err != nil {
- if err.Error() == exception.GetMsg(exception.DuplicateSubscribe) {
- sc.FailedResult("请勿重复订阅", result)
- return
- }
- sc.FailedResult("创建订单失败", result)
- return
- }
- sc.SuccessResult("订阅产品成功", orderInfo, result)
- return
- })
- }
- // SubscribeList 用户订阅列表
- // @Summary 用户订阅列表
- // @Description 用户订阅列表
- // @Success 200 {object} controllers.BaseResponse
- // @router /subscribeList [get]
- func (sc *SubscribeController) SubscribeList(productType string) {
- controllers.Wrap(&sc.BaseController, func() (result *controllers.WrapData, err error) {
- result = sc.InitWrapData("分页查询订阅列表失败")
- userInfo := sc.Data["user"].(user.User)
- if productType == "" || !sc.CheckProductType(productType) {
- err = exception.New(exception.ProductTypeError)
- sc.FailedResult("分页查询订阅列表失败", result)
- return
- }
- pageRes := page.Page{
- Current: sc.PageInfo.Current,
- PageSize: sc.PageInfo.PageSize,
- }
- pageRes.Total, pageRes.LatestId = product.GetTotalUserPageCountByProductType(productType, userInfo.Id)
- if err != nil {
- logger.Error("分页查询订阅列表失败:%v", err)
- sc.FailedResult("分页查询订阅列表失败", result)
- return
- }
- if sc.PageInfo.LatestId == 0 {
- sc.PageInfo.LatestId = pageRes.LatestId
- sc.PageInfo.Total = pageRes.Total
- } else {
- pageRes.LatestId = sc.PageInfo.LatestId
- pageRes.Total = sc.PageInfo.Total
- }
- pageRes.TotalPage = page.TotalPages(pageRes.Total, pageRes.PageSize)
- list, err := product.SubscribeList(userInfo.Id, productType, sc.PageInfo)
- if err != nil {
- sc.FailedResult("分页查询订阅列表失败", result)
- return
- }
- mediaList := new(page.PageResult)
- mediaList.Data = list
- mediaList.Page = pageRes
- sc.SuccessResult("分页查询订阅列表成功", mediaList, result)
- return
- })
- }
- type SubscribeRequest struct {
- ProductId int `json:"productId"`
- OrderNo string `json:"orderNo"`
- }
|