package util import ( MC "app.yhyue.com/moapp/jybase/common" "app.yhyue.com/moapp/jybase/redis" IC "bp.jydev.jianyu360.cn/BaseService/jyMicroservices/jyBXCore/rpc/init" "fmt" "strings" ) // 标讯搜索:全文搜索和附件搜索限制 func IsSearchLimit(searchItems []string) bool { for _, searchItem := range searchItems { if LimitItemsMap[searchItem] { return true } } return false } func LimitSearchInit() { if IC.C.LimitSearchText.Flag { LimitSearchClear() for i := 0; i < IC.C.LimitSearchText.Count; i++ { redis.RPUSH("other", IC.SearchLimitKey, 1) } if limitItems := IC.C.LimitSearchText.LimitItems; len(limitItems) > 0 { LimitItemsMap = map[string]bool{} for _, v := range IC.C.LimitSearchText.LimitItems { LimitItemsMap[v] = true } } } } func LimitSearchClear() { redis.Del("other", IC.SearchLimitKey) } // 限制正文、附件查询 // return 1 正常 // return -1 抱歉!由于系统繁忙暂时无法进行搜索,请1分钟后再试! // return -2 抱歉!由于系统繁忙暂时无法进行搜索,请稍后再试! func IsLimited(limitFlag, userid string, isPayedUser, isNew bool) int64 { if !IC.C.LimitSearchText.Flag { return 1 } var llen = int(redis.LLEN("other", IC.SearchLimitKey)) if IC.C.LimitSearchText.TimeOut > 0 { //limitFlag, isNew := getFlag(r, w, userid) if isNew { if llen <= IC.C.LimitSearchText.Count/2 { timeLimit, _ := redis.Exists("other", fmt.Sprintf(IC.C.LimitSearchText.LimitKey, limitFlag)) if timeLimit { return -1 } } } redis.Put("other", fmt.Sprintf(IC.C.LimitSearchText.LimitKey, limitFlag), 1, IC.C.LimitSearchText.TimeOut) } if IC.C.LimitSearchText.Count == -2 { //不限制 return 1 } else if IC.C.LimitSearchText.Count == -1 { //无条件限制 return -2 } //免费和付费用户 使用并发的80%(默认)通道|| 保留一条通道给付费用户使用 if userid == "" { //未登录用户2个并发数限制, if IC.C.LimitSearchText.Count-IC.C.LimitSearchText.NoLogin <= 0 || llen <= IC.C.LimitSearchText.Count-IC.C.LimitSearchText.NoLogin || llen == 1 { return -2 } } else if !isPayedUser { if llen <= IC.C.LimitSearchText.Count*IC.C.LimitSearchText.Percentage/100 || llen == 1 { return -1 } } // pollLimit := redis.LPOP("other", IC.SearchLimitKey) if MC.IntAll(pollLimit) <= 0 { return -2 } return 1 } func Limit() { if !IC.C.LimitSearchText.Flag { return } if int(redis.LLEN("other", IC.SearchLimitKey)) < IC.C.LimitSearchText.Count { redis.RPUSH("other", IC.SearchLimitKey, 1) } } func IsCanLogin(userId string) bool { for _, v := range IC.C.LimitSearchText.UserIds { if v == userId { return true } } return false } var ( UserIdentMap = map[string]int{ "payer": 1, "free": 2, "noLogin": 3, } LimitItemsMap = map[string]bool{ "detail": true, "filetext": true, } ) /* 限制正文、附件查询 return 1 正常 return -1 抱歉!由于系统繁忙暂时无法进行搜索,请1分钟后再试! return -2 抱歉!由于系统繁忙暂时无法进行搜索,请稍后再试! userIdent 未登录用户是;cookie 中存的标识;登录用户是UserId */ func CheckLimit(userType int, userIdent string, isNew bool) (state int64, msg string) { if !IC.C.LimitSearchText.Flag { state = 1 return } var limitCount = int(redis.LLEN("other", IC.SearchLimitKey)) switch IC.C.LimitSearchText.Count { case -2: //不限制 state = 1 return case -1: //无条件限制 state = -2 msg = fmt.Sprintf("筛选条件:%s,必限制。", strings.Join(IC.C.LimitSearchText.LimitItems, ",")) return default: if limitCount <= 0 { state = -1 msg = fmt.Sprintf("并发通道总数:%d,\n未使用数量:%d", IC.C.LimitSearchText.Count, limitCount) return } } //同一用户 -- 请求频次 在IC.C.LimitSearchText.TimeOut内 不允许多次请求 if IC.C.LimitSearchText.TimeOut > 0 { if isNew && limitCount <= IC.C.LimitSearchText.Count/2 { timeLimit, _ := redis.Exists("other", fmt.Sprintf(IC.C.LimitSearchText.LimitKey, userIdent)) if timeLimit { state = -1 msg = fmt.Sprintf("当前用户:%s \n招投标筛选在%d秒内请求频次过多,\n并发通道-\n总数:%d,\n未使用数量:%d", userIdent, IC.C.LimitSearchText.TimeOut, IC.C.LimitSearchText.Count, limitCount) return } } redis.Put("other", fmt.Sprintf(IC.C.LimitSearchText.LimitKey, userIdent), 1, IC.C.LimitSearchText.TimeOut) } //userType 用户标识:1:付费用户;2:免费用户;3:未登录用户; switch userType { case 1: if limitCount > 0 { state = 1 } default: state = -2 userStr := MC.If(userType == 2, "免费用户", "未登录用户").(string) msg = fmt.Sprintf("%s 招投标重要字段筛选", userStr) if limitCount > IC.C.LimitSearchText.ForPayer { switch userType { case 2: quota := limitCount * IC.C.LimitSearchText.Percentage / 100 if quota > 0 { state = 1 msg = "" } else { state = -1 msg = fmt.Sprintf("%s,\n总并发量的百分之%d", msg, IC.C.LimitSearchText.Percentage) } case 3: quota := limitCount * IC.C.LimitSearchText.NoLogin / 100 if quota > 0 { state = 1 msg = "" } else { state = -1 msg = fmt.Sprintf("%s,\n总并发量的百分之%d", msg, IC.C.LimitSearchText.NoLogin) } } } } //两套负载 同一套并发池 pollLimit := redis.LPOP("other", IC.SearchLimitKey) if MC.IntAll(pollLimit) <= 0 { state = -2 } if msg != "" { msg = fmt.Sprintf("%s,\n并发通道-\n总数:%d,\n未使用数量:%d", msg, IC.C.LimitSearchText.Count, limitCount) } return }