limitSearchText.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package public
  2. import (
  3. "fmt"
  4. "net/http"
  5. "time"
  6. util "app.yhyue.com/moapp/jybase/common"
  7. "app.yhyue.com/moapp/jybase/redis"
  8. "app.yhyue.com/moapp/jybase/go-xweb/httpsession"
  9. )
  10. var Lst *LimitSearchText
  11. type LimitSearchText struct {
  12. TimeOut int
  13. Count int
  14. UserIds []string
  15. Flag bool
  16. TotalPage int
  17. Msg string
  18. Percentage int
  19. LimitKey string
  20. LimitKeyUser string
  21. NoLogin int
  22. }
  23. func IsSearchLimit(searchItems []string) bool {
  24. for _, searchItem := range searchItems {
  25. if searchItem == "detail" || searchItem == "filetext" {
  26. return true
  27. }
  28. }
  29. return false
  30. }
  31. //
  32. func InitLimitSearchText(flag bool, Sysconfig map[string]interface{}) {
  33. limitSearchConfig, _ := Sysconfig["limitSearchText"].(map[string]interface{})
  34. Lst = &LimitSearchText{
  35. TimeOut: util.IntAllDef(limitSearchConfig["timeout"], 60),
  36. UserIds: util.ObjArrToStringArr(limitSearchConfig["userIds"].([]interface{})),
  37. Count: util.IntAllDef(limitSearchConfig["count"], 3),
  38. TotalPage: util.IntAllDef(limitSearchConfig["totalPage"], 3),
  39. Flag: limitSearchConfig["flag"].(bool),
  40. Msg: limitSearchConfig["msg"].(string),
  41. Percentage: util.IntAllDef(limitSearchConfig["percentage"], 80),
  42. LimitKey: fmt.Sprintf(util.ObjToString(limitSearchConfig["limitKey"]), "jy_limitSearchText"),
  43. LimitKeyUser: fmt.Sprintf(util.ObjToString(limitSearchConfig["limitKey"]), "%s"),
  44. NoLogin: util.IntAllDef(limitSearchConfig["noLogin"], 3),
  45. }
  46. if !Lst.Flag {
  47. return
  48. }
  49. if flag {
  50. Lst.Init()
  51. }
  52. }
  53. func (l *LimitSearchText) Init() {
  54. l.Clear()
  55. for i := 0; i < Lst.Count; i++ {
  56. redis.RPUSH("other", l.LimitKey, 1)
  57. }
  58. }
  59. func (l *LimitSearchText) Clear() {
  60. redis.Del("other", l.LimitKey)
  61. }
  62. //限制正文查询
  63. //return 1 正常
  64. //return -1 抱歉!由于系统繁忙暂时无法进行搜索,请1分钟后再试!
  65. //return -2 抱歉!由于系统繁忙暂时无法进行搜索,请稍后再试!
  66. func (l *LimitSearchText) IsLimited(r *http.Request, w http.ResponseWriter, s *httpsession.Session, isPayedUser bool) int {
  67. if !l.Flag {
  68. return 1
  69. }
  70. var llen = int(redis.LLEN("other", l.LimitKey))
  71. if l.TimeOut > 0 {
  72. limitFlag, isNew := l.getFlag(r, w, s)
  73. if isNew {
  74. if llen <= l.Count/2 {
  75. timeLimit, _ := redis.Exists("other", fmt.Sprintf(l.LimitKeyUser, limitFlag))
  76. if timeLimit {
  77. return -1
  78. }
  79. }
  80. }
  81. redis.Put("other", fmt.Sprintf(l.LimitKeyUser, limitFlag), 1, l.TimeOut)
  82. }
  83. if l.Count == -2 {
  84. return 1
  85. } else if l.Count == -1 {
  86. return -2
  87. }
  88. if s.Get("userId") == nil { //未登录用户,2个并发数限制
  89. if l.Count-l.NoLogin <= 0 || llen <= l.Count-l.NoLogin || llen == 1 {
  90. return -2
  91. }
  92. } else if !isPayedUser { //非VIP&大会员 用户 使用并发的80%(默认)通道|| 保留一条通道给非普通用户使用
  93. if llen <= l.Count*l.Percentage/100 || llen == 1 {
  94. return -2
  95. }
  96. }
  97. //
  98. pollLimit := redis.LPOP("other", l.LimitKey)
  99. if util.IntAll(pollLimit) <= 0 {
  100. return -2
  101. }
  102. return 1
  103. }
  104. func (l *LimitSearchText) Limit() {
  105. if !l.Flag {
  106. return
  107. }
  108. if int(redis.LLEN("other", l.LimitKey)) < l.Count {
  109. redis.RPUSH("other", l.LimitKey, 1)
  110. }
  111. }
  112. func (l *LimitSearchText) getFlag(r *http.Request, w http.ResponseWriter, s *httpsession.Session) (string, bool) {
  113. limitFlag, _ := s.Get("userId").(string)
  114. if limitFlag == "" {
  115. c, _ := r.Cookie("limitSearchTextFlag")
  116. if c != nil {
  117. limitFlag = c.Value
  118. if limitFlag == "" {
  119. limitFlag, _ = s.Get("limitSearchTextFlag").(string)
  120. }
  121. }
  122. }
  123. if limitFlag != "" {
  124. return limitFlag, true
  125. }
  126. limitFlag = util.GetLetterRandom(5) + fmt.Sprint(time.Now().UnixNano())
  127. s.Set("limitSearchTextFlag", limitFlag)
  128. c := &http.Cookie{
  129. Name: "limitSearchTextFlag",
  130. Value: limitFlag,
  131. Path: "/",
  132. HttpOnly: false,
  133. MaxAge: 2592000, //一个月
  134. }
  135. http.SetCookie(w, c)
  136. return limitFlag, false
  137. }
  138. //
  139. func (l *LimitSearchText) IsCanLogin(userId string) bool {
  140. for _, v := range l.UserIds {
  141. if v == userId {
  142. return true
  143. }
  144. }
  145. return false
  146. }