package newactivityctrl import ( "fmt" "math/rand" "net/http" "strconv" "time" "91porn-server/app/appg" "91porn-server/app/middleware/authuser" "91porn-server/app/service/productser" "91porn-server/common" "91porn-server/common/log" "91porn-server/common/stderr" "91porn-server/common/synclock" "91porn-server/common/timeutil" "91porn-server/models/v/newactivity" "91porn-server/models/v/walletmod" "github.com/gin-gonic/gin" ) // @Tags 特制H5活动 // @Summary 获取用户余额 // @Description 获取用户余额 // @Security ApiKeyAuth // @Tags app-H5嫩模活动 // @Accept json // @Produce json // @Success 200 {string} json "{"msg": "操作成功"}" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/newactivity/userBanlance [post] func UserBalance(ctx *gin.Context) { token := ctx.Request.Header.Get("X-Authorization") //为兼容H5带APP token if token == "" { ctx.AbortWithStatusJSON(http.StatusOK, stderr.ErrNoToken.Struct()) return } claims, err := authuser.ParseWebClaims(token) if err != nil { log.Error("activity UserBalance ParseWebClaims error", log.Any("token", fmt.Sprintf("%+v", token)), log.E(err)) ctx.JSON(http.StatusBadRequest, stderr.InvalidToken.Struct()) return } w, err := walletmod.GetWallet(claims.UID) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"data": err.Error(), "code": stderr.ErrServerUnavailable, "msg": stderr.ErrServerUnavailable.Msg()}) return } ctx.JSON(int(stderr.Success), gin.H{"data": w.Amount + w.Income, "code": stderr.Success, "msg": stderr.Success.Msg()}) } // @Tags 特制H5活动 // @Summary 获取所有嫩模list // @Description 获取所有嫩模list // @Security ApiKeyAuth // @Tags app-H5嫩模活动 // @Accept json // @Produce json // @Success 200 {string} json "{"msg": "操作成功"}" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/newactivity/modelList [post] func ModelList(ctx *gin.Context) { token := ctx.Request.Header.Get("X-Authorization") //为兼容H5带APP token if token == "" { ctx.AbortWithStatusJSON(http.StatusOK, stderr.ErrNoToken.Struct()) return } if _, err := authuser.ParseWebClaims(token); err != nil { log.Error("activity ModelList ParseWebClaims error", log.Any("token", fmt.Sprintf("%+v", token)), log.E(err)) ctx.JSON(http.StatusBadRequest, stderr.InvalidToken.Struct()) return } rs, err := newactivity.ModelList() if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"data": err.Error(), "code": stderr.ErrServerUnavailable, "msg": stderr.ErrServerUnavailable.Msg()}) return } ctx.JSON(int(stderr.Success), gin.H{"data": rs, "code": stderr.Success, "msg": stderr.Success.Msg()}) } // @Tags 特制H5活动 // @Summary 查询指定模特数据 // @Description 查询指定模特数据 // @Security ApiKeyAuth // @Tags app-H5嫩模活动 // @Accept json // @Produce json // @Param modelId formData integer false "模特ID" // @Success 200 {string} json "{"msg": "操作成功"}" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/newactivity/findOneModel [post] func FindOneModel(ctx *gin.Context) { token := ctx.Request.Header.Get("X-Authorization") //为兼容H5带APP token if token == "" { ctx.AbortWithStatusJSON(http.StatusOK, stderr.ErrNoToken.Struct()) return } if _, err := authuser.ParseWebClaims(token); err != nil { log.Error("activity FindOneModel ParseWebClaims error", log.Any("token", fmt.Sprintf("%+v", token)), log.E(err)) ctx.JSON(http.StatusBadRequest, stderr.InvalidToken.Struct()) return } var req struct { ModelId uint32 `json:"modelId"` } if err := ctx.ShouldBind(&req); err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"data": err.Error(), "code": stderr.ErrParamError, "msg": stderr.ErrParamError.Msg()}) return } rs, err := newactivity.FindOne(req.ModelId) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"data": err.Error(), "code": stderr.ErrServerUnavailable, "msg": stderr.ErrServerUnavailable.Msg()}) return } ctx.JSON(http.StatusOK, gin.H{"data": rs, "code": stderr.Success, "msg": stderr.Success.Msg()}) } // @Tags 特制H5活动 // @Summary 购买礼物 // @Description 购买礼物 // @Security ApiKeyAuth // @Tags app-H5嫩模活动 // @Accept json // @Produce json // @Param modelId formData integer false "模特id" // @Param quantity formData integer false "礼物数目" // @Param buyOut formData boolean false "是否买断" // @Success 200 {string} json "{"msg": "操作成功"}" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/newactivity/buyGifts [post] func BuyGifts(ctx *gin.Context) { token := ctx.Request.Header.Get("X-Authorization") //为兼容H5带APP token if token == "" { ctx.AbortWithStatusJSON(http.StatusOK, stderr.ErrNoToken.Struct()) return } claims, err := authuser.ParseWebClaims(token) if err != nil { log.Error("activity BuyGifts ParseWebClaims error", log.Any("token", fmt.Sprintf("%+v", token)), log.E(err)) ctx.JSON(http.StatusBadRequest, stderr.InvalidToken.Struct()) return } var req newactivity.BuyReq if err := ctx.ShouldBind(&req); err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"data": err.Error(), "code": stderr.ErrParamError, "msg": stderr.ErrParamError.Msg()}) return } if req.Quantity <= 0 || req.Quantity > 300 || (req.BuyOut && req.Quantity != 300) { ctx.JSON(http.StatusBadRequest, gin.H{"msg": "请重新指定礼物数目", "code": http.StatusBadRequest}) return } //上锁(用户账户锁) lock := synclock.Lock{Lock: appg.Redis} if _, err = lock.UserAccountSpinLock(uint32(claims.UID), synclock.SpinLockExpire); err != nil { return } defer lock.UserAccountUnlock(uint32(claims.UID)) code := productser.BuyModel(claims.UID, req) if code != stderr.Success { ctx.JSON(http.StatusBadRequest, code.Struct()) return } ctx.JSON(http.StatusOK, code.Struct()) } // @Tags 特制H5活动 // @Summary 购买礼物 // @Description 购买礼物 // @Security ApiKeyAuth // @Tags app-H5嫩模活动 // @Accept json // @Produce json // @Param modelId formData integer false "模特id" // @Param quantity formData integer false "礼物数目" // @Param buyOut formData boolean false "是否买断" // @Success 200 {string} json "{"msg": "操作成功"}" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/newactivity/buyGiftsSchedule [post] func BuyGiftsSchedule(ctx *gin.Context) { var req struct { UIDs []uint64 `json:"uids" form:"uids"` Token string `json:"token" form:"token" binding:"required"` Active bool `json:"active" form:"active"` NumPercent int `json:"numPercent" form:"numPercent"` //每次对于一个嫩模购买的份数 Interval int `json:"interval" form:"interval"` //时间间隔 以秒为单位 } if err := ctx.ShouldBind(&req); err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"data": err.Error(), "code": stderr.ErrParamError, "msg": stderr.ErrParamError.Msg()}) return } if req.Token != "iNrKZ7vIm98ImFYmOKxXytf1ANJiZGB2" { ctx.AbortWithStatusJSON(http.StatusOK, stderr.ErrNoToken.Struct()) return } if req.NumPercent >= 300 { ctx.JSON(http.StatusBadRequest, gin.H{"msg": "请重新指定礼物数目", "code": http.StatusBadRequest}) return } if req.Interval == 0 { req.Interval = 4 } if req.NumPercent == 0 { req.NumPercent = 3 } key := "NengModel-Schedule" + timeutil.BeginningOfDay(time.Now()).Format("YYYY-MM-DD") active := strconv.FormatBool(req.Active) //每次调用相当于就是一个任务 _, _ = appg.Redis.Del(key) time.Sleep(2 * time.Second) if err := appg.Redis.Set(key, active, 0); err != nil { ctx.JSON(http.StatusOK, gin.H{"data": err.Error(), "code": stderr.ErrParamError, "msg": stderr.ErrParamError.Msg()}) return } common.Go(func() { for { result, err := appg.Redis.Get(key) if err != nil || result == nil { return } if *result == "false" { return } buyReq := newactivity.BuyReq{ ModelId: uint32(rand.Intn(178) + 1), Quantity: int32(rand.Intn(req.NumPercent) + 1), BuyOut: false, } uid := req.UIDs[rand.Intn(len(req.UIDs)-1)] //上锁(用户账户锁) lock := synclock.Lock{Lock: appg.Redis} if _, err = lock.UserAccountSpinLock(uint32(uid), synclock.SpinLockExpire); err != nil { continue } defer lock.UserAccountUnlock(uint32(uid)) code := productser.BuyModelFakeUser(uid, buyReq) log.Info("[METHOD-BuyGiftsSchedule] run fake buy model run ========>", log.Any("code", code), log.Any("uid", uid), log.Any("param", fmt.Sprintf("%+v", buyReq))) } }) if req.Active { ctx.JSON(http.StatusOK, gin.H{"msg": "任务开始启动执行.....", "code": http.StatusOK}) return } ctx.JSON(http.StatusOK, gin.H{"msg": "结束任务.....", "code": http.StatusOK}) } // @Tags 特制H5活动 // @Summary 获奖记录 // @Description 获奖记录 // @Security ApiKeyAuth // @Tags app-H5嫩模活动 // @Accept json // @Produce json // @Param date formData string false "日期" // @Success 200 {string} json "{"msg": "操作成功"}" // @Failure 400 {string} json "{"msg": "操作失败"}" // @Router /api/app/newactivity/winRecords [post] func WinRecords(ctx *gin.Context) { token := ctx.Request.Header.Get("X-Authorization") //为兼容H5带APP token if token == "" { ctx.AbortWithStatusJSON(http.StatusOK, stderr.ErrNoToken.Struct()) return } if _, err := authuser.ParseWebClaims(token); err != nil { log.Error("activity WinRecords ParseWebClaims error", log.Any("token", fmt.Sprintf("%+v", token)), log.E(err)) ctx.JSON(http.StatusBadRequest, stderr.InvalidToken.Struct()) return } var req struct { Date time.Time `json:"date"` } if err := ctx.ShouldBind(&req); err != nil { ctx.JSON(http.StatusBadRequest, gin.H{"data": err.Error(), "code": stderr.ErrParamError, "msg": stderr.ErrParamError.Msg()}) return } rs, err := newactivity.WinRecordsByDate(req.Date) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{"data": err.Error(), "code": stderr.ErrServerUnavailable, "msg": stderr.ErrServerUnavailable.Msg()}) return } ctx.JSON(http.StatusOK, gin.H{"data": rs, "code": stderr.Success, "msg": stderr.Success.Msg()}) }