This commit is contained in:
yangduo 2024-12-30 11:33:39 +08:00
parent e1bb4b963d
commit 44ce15c20b
9 changed files with 188 additions and 36 deletions

View File

@ -2,10 +2,12 @@ package v1
import ( import (
"main/api/v1/ingame" "main/api/v1/ingame"
"main/api/v1/mainservice"
) )
type ApiGroup struct { type ApiGroup struct {
InGameApiGroup ingame.ApiGroup InGameApiGroup ingame.ApiGroup
MainServiceApiGroup mainservice.MainServiceApi
} }
var ApiGroupApp = new(ApiGroup) var ApiGroupApp = new(ApiGroup)

View File

@ -58,7 +58,7 @@ func (this *InGameApi) ServerPreOrder(c *gin.Context) {
goodsid := c.Query("goods_id") goodsid := c.Query("goods_id")
sessionid := c.Query("session_id") sessionid := c.Query("session_id")
sign := c.Query("sign") sign := c.Query("sign")
if strings.ToLower(q5.Md5Str(accountId+goodsid+"f3a6a9a5-217a-4079-ab99-b5d69b8212be"+sessionid)) != strings.ToLower(sign) { if strings.ToLower(q5.Md5Str(accountId+goodsid+constant.GLOBAL_SALT+sessionid)) != strings.ToLower(sign) {
f5.RspErr(c, 401, "sign err") f5.RspErr(c, 401, "sign err")
return return
} }
@ -96,7 +96,7 @@ func (this *InGameApi) PayDone(c *gin.Context) {
orderid := c.Query("order_id") orderid := c.Query("order_id")
sessionid := c.Query("session_id") sessionid := c.Query("session_id")
sign := c.Query("sign") sign := c.Query("sign")
if strings.ToLower(q5.Md5Str(accountId+orderid+"f3a6a9a5-217a-4079-ab99-b5d69b8212be"+sessionid)) != strings.ToLower(sign) { if strings.ToLower(q5.Md5Str(accountId+orderid+constant.GLOBAL_SALT+sessionid)) != strings.ToLower(sign) {
f5.RspErr(c, 401, "sign err") f5.RspErr(c, 401, "sign err")
return return
} }

View File

@ -0,0 +1,5 @@
package mainservice
type ApiGroup struct {
MainServiceApi
}

View File

@ -0,0 +1,38 @@
package mainservice
import (
"f5"
"main/constant"
"main/service"
"q5"
"github.com/gin-gonic/gin"
)
type MainServiceApi struct {
}
func (this *MainServiceApi) RefreshToken(c *gin.Context) {
reqtime := q5.SafeToInt64(c.Query("time"))
reqsign := c.Query("sign")
nowTime := f5.GetApp().GetRealSeconds()
if reqtime > nowTime+30 || reqtime+30 < nowTime {
f5.RspErr(c, 400, "request error")
return
}
sign := service.Wxpay.GenSHA256Signature(c.Query("time")+constant.GLOBAL_SALT, constant.GLOBAL_SALT)
if reqsign != sign {
f5.RspErr(c, 400, "request error 2")
return
}
rspObj := struct {
Data []service.TokenInfo `json:"data"`
ErrCode int64 `json:"errcode"`
ErrMsg string `json:"errmsg"`
}{}
service.Wxpay.GetAccessTokenList(&rspObj.Data)
c.JSON(200, rspObj)
}

View File

@ -42,6 +42,9 @@ const (
const ( const (
WX_ERRCODE_OK = 0 WX_ERRCODE_OK = 0
WX_ERRCODE_BUSY = -1 WX_ERRCODE_BUSY = -1
WX_ERRCODE_UNAUTH_ACCESSTOKEN = 40014
WX_ERRCODE_MISSING_ACCESSTOKEN = 41001
WX_ERRCODE_EXPIRE_ACCESSTOKEN = 42001
WX_ERRCODE_SIGERR = 90010 WX_ERRCODE_SIGERR = 90010
WX_ERRCODE_PAYSIGERR = 90011 WX_ERRCODE_PAYSIGERR = 90011
WX_ERRCODE_SAMEBILLNO = 90012 WX_ERRCODE_SAMEBILLNO = 90012
@ -49,3 +52,7 @@ const (
WX_ERRCODE_SESSIONERR = 90016 WX_ERRCODE_SESSIONERR = 90016
WX_ERRCODE_PARAMERR = 90018 WX_ERRCODE_PARAMERR = 90018
) )
const (
GLOBAL_SALT = "f3a6a9a5-217a-4079-ab99-b5d69b8212be"
)

View File

@ -0,0 +1,5 @@
package mainservice
type RouterGroup struct {
MainServiceRouter
}

View File

@ -0,0 +1,14 @@
package mainservice
import (
"f5"
v1 "main/api/v1"
)
type MainServiceRouter struct{}
func (this *MainServiceRouter) InitRouter() {
api := v1.ApiGroupApp.MainServiceApiGroup
f5.GetApp().GetGinEngine().GET("/api/service/refresh",
api.RefreshToken)
}

View File

@ -4,15 +4,18 @@ import (
"f5" "f5"
"main/middleware" "main/middleware"
"main/router/ingame" "main/router/ingame"
"main/router/mainservice"
) )
type routerMgr struct { type routerMgr struct {
ingame ingame.RouterGroup ingame ingame.RouterGroup
mainservice mainservice.RouterGroup
} }
func (this *routerMgr) Init() { func (this *routerMgr) Init() {
f5.GetApp().GetGinEngine().Use(middleware.Cors()) f5.GetApp().GetGinEngine().Use(middleware.Cors())
this.ingame.IngameRouter.InitRouter() this.ingame.IngameRouter.InitRouter()
this.mainservice.MainServiceRouter.InitRouter()
f5.GetSysLog().Info("routerMgr.init") f5.GetSysLog().Info("routerMgr.init")

View File

@ -14,9 +14,10 @@ import (
"time" "time"
) )
type tokenItem struct { type TokenInfo struct {
token string GameId int64 `json:"gameid"`
expire int64 Token string `json:"token"`
Expire int64 `json:"expire"`
} }
type expireSession struct { type expireSession struct {
@ -25,9 +26,9 @@ type expireSession struct {
} }
type wxpay struct { type wxpay struct {
gamesGoods q5.ConcurrentMap[int64, map[int64]int64] //[gameid, [goodsid]count] gamesGoods q5.ConcurrentMap[int64, map[int64]int64] //[gameid, [goodsid]count]
accessTokens q5.ConcurrentMap[int64, tokenItem] //[gameid, tokenitem] accessTokens q5.ConcurrentMap[int64, TokenInfo] //[gameid, TokenInfo]
expireInfo q5.ConcurrentMap[string, *expireSession] //[accountid, expireSession] expireInfo q5.ConcurrentMap[string, *expireSession] //[accountid, expireSession]
refreshflag bool
} }
type WxQuery struct { type WxQuery struct {
@ -59,7 +60,7 @@ type WxPayRsp struct {
func (wp *wxpay) init() { func (wp *wxpay) init() {
wp.gamesGoods = q5.ConcurrentMap[int64, map[int64]int64]{} wp.gamesGoods = q5.ConcurrentMap[int64, map[int64]int64]{}
wp.accessTokens = q5.ConcurrentMap[int64, tokenItem]{} wp.accessTokens = q5.ConcurrentMap[int64, TokenInfo]{}
wp.expireInfo = q5.ConcurrentMap[string, *expireSession]{} wp.expireInfo = q5.ConcurrentMap[string, *expireSession]{}
mt.Table.Wxconfig.Traverse(func(w *mt.Wxconfig) bool { mt.Table.Wxconfig.Traverse(func(w *mt.Wxconfig) bool {
@ -77,17 +78,15 @@ func (wp *wxpay) init() {
gamegoods[q5.SafeToInt64(data["id"])] = q5.SafeToInt64(data["count"]) gamegoods[q5.SafeToInt64(data["id"])] = q5.SafeToInt64(data["count"])
} }
wp.gamesGoods.Store(w.GetGameid(), gamegoods) wp.gamesGoods.Store(w.GetGameid(), gamegoods)
wp.accessTokens.Store(w.GetGameid(), tokenItem{}) wp.accessTokens.Store(w.GetGameid(), TokenInfo{})
} }
return true return true
}) })
wp.gamesGoods.Range(func(gameid int64, value map[int64]int64) bool {
wp.freshAccessToken(gameid)
return true
})
go wp.checkExpireInfo() go wp.checkExpireInfo()
wp.refreshflag = true
go wp.checkAccessToken()
} }
func (wp *wxpay) unInit() { func (wp *wxpay) unInit() {
@ -128,8 +127,9 @@ func (wp *wxpay) freshAccessToken(gameid int64) (token string) {
if rspObj.ErrCode == 0 { if rspObj.ErrCode == 0 {
tokenitem, _ := wp.accessTokens.Load(gameid) tokenitem, _ := wp.accessTokens.Load(gameid)
tokenitem.token = rspObj.Token tokenitem.GameId = gameid
tokenitem.expire = rspObj.Expire + f5.GetApp().GetRealSeconds() tokenitem.Token = rspObj.Token
tokenitem.Expire = rspObj.Expire + f5.GetApp().GetRealSeconds()
wp.accessTokens.Store(gameid, *tokenitem) wp.accessTokens.Store(gameid, *tokenitem)
} }
@ -147,11 +147,17 @@ func (wp *wxpay) getAccessToken(gameid int64) (token string) {
cfg, exist := wp.accessTokens.Load(gameid) cfg, exist := wp.accessTokens.Load(gameid)
nowTime := f5.GetApp().GetRealSeconds() nowTime := f5.GetApp().GetRealSeconds()
if exist { if exist {
if cfg.expire > nowTime+60 { if cfg.Expire > nowTime+6 {
return cfg.token if cfg.Expire < nowTime+30 && !wp.refreshflag {
wp.refreshflag = true
}
return cfg.Token
} }
return wp.freshAccessToken(gameid) if !wp.refreshflag {
wp.refreshflag = true
}
return ""
} }
return "" return ""
} }
@ -196,9 +202,9 @@ func (wp *wxpay) QueryBalance(openid string, gameid int64, userip string, sessio
queryuri := "/wxa/game/getbalance" queryuri := "/wxa/game/getbalance"
query := WxQuery{ query := WxQuery{
AccessToken: wp.getAccessToken(gameid), AccessToken: wp.getAccessToken(gameid),
Signature: wp.genSHA256Signature(poststr, sessionkey), Signature: wp.GenSHA256Signature(poststr, sessionkey),
SigMethod: "hmac_sha256", SigMethod: "hmac_sha256",
PaySig: wp.genSHA256Signature(queryuri+"&"+poststr, cfg.GetAppkey()), PaySig: wp.GenSHA256Signature(queryuri+"&"+poststr, cfg.GetAppkey()),
} }
params := map[string]string{} params := map[string]string{}
@ -235,6 +241,7 @@ func (wp *wxpay) QueryBalance(openid string, gameid int64, userip string, sessio
sendRequest = false sendRequest = false
default: default:
f5.GetSysLog().Info("err msg:%s", rspJson.ErrMsg) f5.GetSysLog().Info("err msg:%s", rspJson.ErrMsg)
wp.checkErrorCode(rspJson.ErrCode)
} }
}) })
@ -276,9 +283,9 @@ func (wp *wxpay) QueryPay(openid string, gameid int64, userip string, sessionkey
queryuri := "/wxa/game/pay" queryuri := "/wxa/game/pay"
query := WxQuery{ query := WxQuery{
AccessToken: wp.getAccessToken(gameid), AccessToken: wp.getAccessToken(gameid),
Signature: wp.genSHA256Signature(poststr, sessionkey), Signature: wp.GenSHA256Signature(poststr, sessionkey),
SigMethod: "hmac_sha256", SigMethod: "hmac_sha256",
PaySig: wp.genSHA256Signature(queryuri+"&"+poststr, cfg.GetAppkey()), PaySig: wp.GenSHA256Signature(queryuri+"&"+poststr, cfg.GetAppkey()),
} }
params := map[string]string{} params := map[string]string{}
@ -314,6 +321,7 @@ func (wp *wxpay) QueryPay(openid string, gameid int64, userip string, sessionkey
sendRequest = false sendRequest = false
default: default:
f5.GetSysLog().Info("err msg:%s", rspJson.ErrMsg) f5.GetSysLog().Info("err msg:%s", rspJson.ErrMsg)
wp.checkErrorCode(rspJson.ErrCode)
} }
}) })
@ -348,12 +356,19 @@ func (wp *wxpay) CheckExpireCache(accountid string, expire int64) bool {
return true return true
} }
func (wp *wxpay) genSHA256Signature(str string, key string) string { func (wp *wxpay) GenSHA256Signature(str string, key string) string {
mac := hmac.New(sha256.New, []byte(key)) mac := hmac.New(sha256.New, []byte(key))
_, _ = mac.Write([]byte(str)) _, _ = mac.Write([]byte(str))
return strings.ToLower(hex.EncodeToString(mac.Sum(nil))) return strings.ToLower(hex.EncodeToString(mac.Sum(nil)))
} }
func (wp *wxpay) GetAccessTokenList(data *[]TokenInfo) {
wp.accessTokens.Range(func(key int64, value TokenInfo) bool {
*data = append(*data, value)
return true
})
}
func (wp *wxpay) checkExpireInfo() { func (wp *wxpay) checkExpireInfo() {
for { for {
time.Sleep(time.Minute * 30) time.Sleep(time.Minute * 30)
@ -371,3 +386,66 @@ func (wp *wxpay) checkExpireInfo() {
} }
} }
} }
func (wp *wxpay) checkAccessToken() {
for {
time.Sleep(time.Second)
if !wp.refreshflag {
continue
}
if f5.IsOnlineEnv() {
wp.gamesGoods.Range(func(gameid int64, value map[int64]int64) bool {
wp.freshAccessToken(gameid)
return true
})
} else {
url := "https://payservice.kingsome.cn/api/service/refresh"
nowtimestr := q5.SafeToString(f5.GetApp().GetRealSeconds())
params := map[string]string{
"time": nowtimestr,
"sign": wp.GenSHA256Signature(nowtimestr+constant.GLOBAL_SALT, constant.GLOBAL_SALT),
}
f5.GetHttpCliMgr().SendGoStyleRequest(
url,
params,
func(hcr f5.HttpCliResponse) {
if hcr.GetErr() != nil {
return
}
rspObj := struct {
Data []TokenInfo `json:"data"`
ErrCode int64 `json:"errcode"`
ErrMsg string `json:"errmsg"`
}{}
f5.GetSysLog().Debug("get online payservice rsp:%s", hcr.GetRawData())
if json.Unmarshal([]byte(hcr.GetRawData()), &rspObj) != nil {
return
}
if rspObj.ErrCode == 0 {
for _, dataitem := range rspObj.Data {
wp.accessTokens.Store(dataitem.GameId, dataitem)
}
}
})
}
wp.refreshflag = false
}
}
func (wp *wxpay) checkErrorCode(errcode int32) {
if errcode == constant.WX_ERRCODE_EXPIRE_ACCESSTOKEN ||
errcode == constant.WX_ERRCODE_MISSING_ACCESSTOKEN ||
errcode == constant.WX_ERRCODE_UNAUTH_ACCESSTOKEN {
if !wp.refreshflag {
wp.refreshflag = true
}
}
}