Ver Fonte

feat:xiugai

wangchuanjin há 3 meses atrás
pai
commit
4668bf945a

+ 2 - 0
common/gatecode/errcode.go

@@ -28,6 +28,7 @@ const (
 	GLOBAL_ERR_MISSPARAM                          //缺少参数:%s
 	GLOBAL_ERR_INVALIDPARAM                       //无效参数:%s
 	GLOBAL_ERR_SERVICE                            //远端服务异常
+	GLOBAL_ERR_NOPERMISSION                       //没有权限
 )
 
 var globalErrMap = map[ErrCode]string{
@@ -40,6 +41,7 @@ var globalErrMap = map[ErrCode]string{
 	GLOBAL_ERR_MISSPARAM:    "缺少参数:%s",
 	GLOBAL_ERR_INVALIDPARAM: "无效参数:%s",
 	GLOBAL_ERR_SERVICE:      "远端服务异常",
+	GLOBAL_ERR_NOPERMISSION: "没有权限",
 }
 
 func (i ErrCode) String() string {

+ 1 - 1
core/proxy/middleware/filterFuncs.go

@@ -48,7 +48,7 @@ func filterBefore(r *ghttp.Request) error {
 		return NewErrorWithCode(GLOBAL_ERR_MISSPARAM, "sign")
 	}
 	users := db.GateWatMySql.SelectBySql(`SELECT a.secretkey,a.amount,b.count FROM USER a LEFT JOIN (
-		SELECT a.id,b.count FROM USER a INNER JOIN gift b ON (a.appid= AND a.id=b.user_id)
+		SELECT a.id,b.count FROM USER a INNER JOIN gift b ON (a.appid=? AND a.id=b.user_id)
 		INNER JOIN front_proxy c ON (c.url=? AND b.front_proxy_id=c.id)
 		) b ON (a.id=b.id) WHERE a.appid=?`, appid, url_, appid)
 	if users == nil || len(*users) == 0 {

+ 2 - 2
core/proxy/proxyServer.go

@@ -91,7 +91,7 @@ var proxyHandler = func(r *ghttp.Request) {
 	change := func(resp *http.Response) error {
 		if resp.StatusCode != 200 {
 			return errors.New(fmt.Sprintf("RespError_%d", GLOBAL_ERR_SERVICE))
-		} else if gCtx.RouterRule.Price <= 0 { //免费接口不处理
+		} else if gCtx.RouterRule.IsFree { //免费接口不处理
 			return nil
 		}
 		status := 0
@@ -136,7 +136,7 @@ var proxyHandler = func(r *ghttp.Request) {
 					return false
 				} else if giftUpdate == 0 {
 					updateRes := db.GateWatMySql.UpdateOrDeleteBySqlByTx(tx, `update user set amount=amount-? where appid=?`, gCtx.RouterRule.Price, appid)
-					if updateRes <= 0 {
+					if updateRes < 0 {
 						log.WithContext(r.Context()).Error(appid, "更新金额扣除计费失败")
 						return false
 					}

+ 42 - 7
core/router/manager.go

@@ -1,6 +1,7 @@
 package router
 
 import (
+	"app.yhyue.com/moapp/jybase/redis"
 	"errors"
 	"fmt"
 	"log"
@@ -22,8 +23,9 @@ type Manager struct {
 // InitRouterManager 初始化系统代理路由
 // 支持完全匹配和正则匹配
 func InitRouterManager() (*Manager, error) {
+	redis.DelByCodePattern("other", "reqLimit_tripartite_*")
 	//加载规则
-	res := db.GateWatMySql.Query(`SELECT * FROM front_proxy`)
+	res := db.GateWatMySql.SelectBySql(`SELECT * FROM front_proxy`)
 	if res == nil {
 		return nil, errors.New("未发现可用路由")
 	}
@@ -36,18 +38,20 @@ func InitRouterManager() (*Manager, error) {
 		// 获取路由信息
 		router := gconv.String(row["url"])
 		routerRule := &Router{
+			Id:      gconv.Int(row["id"]),
 			Status:  gconv.Int(row["status"]),
 			ReqUrl:  router,
 			TimeOut: gconv.Int64(row["timeout"]),
 			Remark:  gconv.String(row["remark"]),
 			Server:  gconv.String(row["server"]),
 			Price:   gconv.Int64(row["price"]),
-			ReqLimit: &util.ReqLimit{
-				Size: gconv.Int(row["pool_size"]),
-				Key:  fmt.Sprintf("reqLimit_tripartite_%d", gconv.Int(row["id"])),
-			},
+		}
+		routerRule.ReqLimit = &util.ReqLimit{
+			Size: gconv.Int(row["pool_size"]),
+			Key:  fmt.Sprintf("reqLimit_tripartite_%d", routerRule.Id),
 		}
 		routerRule.ReqLimit.Init()
+		routerRule.IsFree = routerRule.Price <= 0
 		// 判断路由匹配方式是完全匹配还是正则匹配 (此处逻辑参考x-web框架)
 		if regexp.QuoteMeta(router) == router {
 			routerManager.eqRouters[router] = routerRule
@@ -93,8 +97,39 @@ func (m *Manager) InfusionContext(r *ghttp.Request) (err error) {
 	}
 	router, err = m.GetRouterRule(r.URL.Path)
 	if err != nil {
-		r.SetCtxVar(GContextKey, GCtx)
-		return
+		return err
+	}
+	appid := r.GetQuery("appid").String()
+	res := db.GateWatMySql.SelectBySql(`SELECT b.* FROM USER a INNER JOIN user_api b ON (a.appid=? AND b.front_proxy_id=? AND a.id=b.user_id)`, appid, router.Id)
+	if res == nil || len(*res) == 0 {
+		return NewErrorWithCode(GLOBAL_ERR_NOPERMISSION)
+	}
+	router = &Router{
+		Id:       router.Id,
+		Status:   router.Status,
+		ReqUrl:   router.ReqUrl,
+		TimeOut:  router.TimeOut,
+		Remark:   router.Remark,
+		Server:   router.Server,
+		Price:    gconv.Int64((*res)[0]["price"]),
+		ReqLimit: router.ReqLimit,
+	}
+	rl := &util.ReqLimit{
+		Size: gconv.Int((*res)[0]["pool_size"]),
+		Key:  fmt.Sprintf("reqLimit_tripartite_%d_%d", router.Id, gconv.Int((*res)[0]["user_id"])),
+	}
+	sizeKey := router.ReqLimit.Key + "_size"
+	if rl.Size > 0 {
+		router.ReqLimit = rl
+		//数据库中调整了某个用户的某个接口并发数,重新初始化
+		if redis.GetInt("other", sizeKey) != router.ReqLimit.Size {
+			redis.PutCKV("other", sizeKey, router.ReqLimit.Size)
+			router.ReqLimit.Clear()
+			router.ReqLimit.Init()
+		}
+	} else {
+		redis.Del("other", sizeKey)
+		rl.Clear()
 	}
 	GCtx.RouterRule = router
 	//获取session

+ 2 - 0
core/router/router.go

@@ -5,6 +5,7 @@ import (
 )
 
 type Router struct {
+	Id       int            //
 	Status   int            //0:冻结不可用 1:正常可用
 	TimeOut  int64          //接口超时提醒,单位毫秒;默认500毫秒
 	ReqUrl   string         //请求地址
@@ -12,4 +13,5 @@ type Router struct {
 	Server   string         //服务地址
 	Price    int64          //单价
 	ReqLimit *util.ReqLimit //并发限制
+	IsFree   bool           //是否免费
 }

+ 6 - 7
core/util/reqLimit.go

@@ -10,20 +10,20 @@ type ReqLimit struct {
 	Size int
 }
 
-//
 func (r *ReqLimit) Init() {
-	r.Clear()
+	if ok, err := redis.Exists("other", r.Key); err != nil || ok {
+		return
+	}
 	for i := 0; i < r.Size; i++ {
 		redis.RPUSH("other", r.Key, 1)
 	}
 }
 
-//
 func (r *ReqLimit) Clear() {
 	redis.Del("other", r.Key)
 }
 
-//查询是否被限流
+// 查询是否被限流
 func (r *ReqLimit) IsLimit() bool {
 	if r.Size <= 0 {
 		return false
@@ -31,8 +31,8 @@ func (r *ReqLimit) IsLimit() bool {
 	return redis.LLEN("other", r.Key) == 0
 }
 
-//并发数限制
-//return true 被限制 false 正常
+// 并发数限制
+// return true 被限制 false 正常
 func (r *ReqLimit) Limit() bool {
 	if r.Size <= 0 {
 		return false
@@ -40,7 +40,6 @@ func (r *ReqLimit) Limit() bool {
 	return gconv.Int64(redis.LPOP("other", r.Key)) <= 0
 }
 
-//
 func (r *ReqLimit) UnLimit() {
 	if r.Size <= 0 {
 		return