2025-01-07 11:09:07 +08:00

394 lines
10 KiB
Go

package ingame
import (
"encoding/json"
"f5"
"main/constant"
"main/model"
"main/service"
"q5"
"strings"
"github.com/gin-gonic/gin"
)
type InGameApi struct {
}
func (this *InGameApi) PreOrder(c *gin.Context) {
reqJson := struct {
AccountId string `json:"account_id" binding:"required"`
SessionId string `json:"session_id" binding:"required"`
GoodsId int32 `json:"goods_id" binding:"required"`
}{}
if err := c.ShouldBindJSON(&reqJson); err != nil {
f5.RspErr(c, 401, "params error")
return
}
nowTime := int32(f5.GetApp().GetRealSeconds())
order := new(model.InAppOrder)
order.AccountId = reqJson.AccountId
order.OrderId = q5.ToString(f5.GetApp().NewLockNodeUuid())
order.ItemId = reqJson.GoodsId
order.IP = this.getIP(c)
order.CreateTime = nowTime
order.ModifyTime = nowTime
if err := order.Create(); err != nil {
f5.RspErr(c, 500, "server internal error")
return
}
rspObj := struct {
ErrorCode int32 `json:"errcode"`
ErrMsg string `json:"errmsg"`
OrderId string `json:"order_id"`
}{
0,
"",
order.OrderId,
}
c.JSON(200, rspObj)
}
func (this *InGameApi) ServerPreOrder(c *gin.Context) {
accountId := c.Query("account_id")
goodsid := c.Query("goods_id")
sessionid := c.Query("session_id")
sign := c.Query("sign")
if strings.ToLower(q5.Md5Str(accountId+goodsid+constant.GLOBAL_SALT+sessionid)) != strings.ToLower(sign) {
f5.RspErr(c, 401, "sign err")
return
}
nowTime := int32(f5.GetApp().GetRealSeconds())
order := new(model.InAppOrder)
order.AccountId = accountId
order.OrderId = q5.ToString(f5.GetApp().NewLockNodeUuid())
order.ItemId = q5.SafeToInt32(goodsid)
order.IP = c.Query("user_ip")
order.CreateTime = nowTime
order.ModifyTime = nowTime
if err := order.Create(); err != nil {
f5.RspErr(c, 500, "server internal error")
return
}
rspObj := struct {
ErrorCode int32 `json:"errcode"`
ErrMsg string `json:"errmsg"`
OrderId string `json:"order_id"`
}{
0,
"",
order.OrderId,
}
c.JSON(200, rspObj)
}
func (this *InGameApi) PayDone(c *gin.Context) {
accountId := c.Query("account_id")
orderid := c.Query("order_id")
sessionid := c.Query("session_id")
sign := c.Query("sign")
if strings.ToLower(q5.Md5Str(accountId+orderid+constant.GLOBAL_SALT+sessionid)) != strings.ToLower(sign) {
f5.RspErr(c, 401, "sign err")
return
}
orderModel := new(model.InAppOrder)
if err, found := orderModel.Find(accountId, orderid); err != nil {
f5.RspErr(c, 500, "server internal error")
return
} else if !found {
f5.RspErr(c, 1, "order not found")
return
}
strs := strings.Split(accountId, "_")
if len(strs) < 3 {
f5.RspErr(c, 401, "params error1")
return
}
rediskey := "ls:accountid:" + accountId
str, err := service.Redis.Get(constant.LOGIN_REDIS, rediskey)
if err != nil {
f5.RspErr(c, 402, "invalid session")
return
}
data := map[string]interface{}{}
if json.Unmarshal([]byte(str), &data) != nil {
f5.RspErr(c, 402, "invalid session 1")
return
}
sessionkey := q5.SafeToString(data["session_key"])
if len(sessionkey) == 0 {
f5.GetSysLog().Debug("empty sessionkey:%s", accountId)
f5.RspErr(c, 402, "invalid session 2")
return
}
sessionkeytime := q5.SafeToInt64(data["update_time"])
if service.Wxpay.CheckExpireCache(accountId, sessionkeytime) {
f5.RspErr(c, 402, "session expired")
return
}
status := orderModel.Status
rspObj := struct {
ErrorCode int32 `json:"errcode"`
ErrMsg string `json:"errmsg"`
OrderId string `json:"order_id"`
Diamond int64 `json:"diamond"`
}{
OrderId: orderid,
}
for status < 2 {
gameid := q5.SafeToInt64(strs[1])
openid := q5.SafeToString(data["openid"])
userip := this.getIP(c)
balance, errcode, err := int64(0), int32(0), error(nil)
if status == 0 {
balance, errcode, err = service.Wxpay.QueryBalance(openid, gameid, userip, sessionkey)
if err != nil {
f5.RspErr(c, 500, "system busy")
return
}
} else {
balance = int64(orderModel.SpAmount)
}
if errcode == constant.WX_ERRCODE_OK && balance > 0 {
errcode = service.Wxpay.QueryPay(openid, gameid, userip, sessionkey, int32(balance), orderModel.OrderId)
if errcode == constant.WX_ERRCODE_OK {
status = 1
orderModel.Status = 2
orderModel.UpdateFields([]string{"status"})
rspObj.Diamond = balance
}
}
if errcode == constant.WX_ERRCODE_SESSIONERR || errcode == constant.WX_ERRCODE_SIGERR {
rspObj.ErrorCode = 402
rspObj.ErrMsg = "session overtime"
}
break
}
c.JSON(200, rspObj)
}
func (this *InGameApi) OrderInfo(c *gin.Context) {
reqJson := struct {
AccountId string `json:"account_id" binding:"required"`
SessionId string `json:"session_id" binding:"required"`
OrderId string `json:"order_id" binding:"required"`
}{}
if err := c.ShouldBindJSON(&reqJson); err != nil {
f5.RspErr(c, 401, "params error")
return
}
strs := strings.Split(reqJson.AccountId, "_")
if len(strs) < 3 {
f5.RspErr(c, 401, "params error1")
return
}
rediskey := "ls:accountid:" + reqJson.AccountId
str, err := service.Redis.Get(constant.LOGIN_REDIS, rediskey)
if err != nil {
f5.RspErr(c, 402, "invalid session")
return
}
data := map[string]interface{}{}
if json.Unmarshal([]byte(str), &data) != nil {
f5.RspErr(c, 402, "invalid session 1")
return
}
sessionkey := q5.SafeToString(data["session_key"])
if len(sessionkey) == 0 {
f5.GetSysLog().Debug("empty sessionkey:%s", reqJson.AccountId)
f5.RspErr(c, 402, "invalid session 2")
return
}
sessionkeytime := q5.SafeToInt64(data["update_time"])
if service.Wxpay.CheckExpireCache(reqJson.AccountId, sessionkeytime) {
f5.RspErr(c, 402, "session expired")
return
}
orderModel := new(model.InAppOrder)
if err, found := orderModel.Find(reqJson.AccountId, reqJson.OrderId); err != nil {
f5.RspErr(c, 500, "server internal error")
return
} else if !found {
f5.RspErr(c, 1, "not found")
return
}
rspObj := struct {
ErrorCode int32 `json:"errcode"`
ErrMsg string `json:"errmsg"`
OrderId string `json:"order_id"`
GoodsId int32 `json:"goods_id"`
Count int32 `json:"count"`
Others int32 `json:"others"`
Status int32 `json:"status"`
}{
OrderId: orderModel.OrderId,
GoodsId: orderModel.ItemId,
Count: orderModel.SpAmount,
Others: orderModel.SpOthers,
Status: orderModel.Status,
}
c.JSON(200, rspObj)
if orderModel.Status == 0 {
gameid := q5.SafeToInt64(strs[1])
openid := q5.SafeToString(data["openid"])
userip := this.getIP(c)
balance, errcode, err := service.Wxpay.QueryBalance(openid, gameid, userip, sessionkey)
if err != nil {
return
}
if errcode == constant.WX_ERRCODE_OK {
count, err := service.Wxpay.GetGoodsCount(gameid, int64(orderModel.ItemId))
if err != nil {
return
}
if balance >= count {
errcode = service.Wxpay.QueryPay(openid, gameid, userip, sessionkey, int32(balance), orderModel.OrderId)
if errcode == constant.WX_ERRCODE_OK {
orderModel.Status = 1
orderModel.SpAmount = int32(count)
orderModel.SpOthers = int32(balance - count)
orderModel.UpdateFields([]string{"status", "sp_amount", "sp_others"})
}
}
}
if errcode == constant.WX_ERRCODE_SESSIONERR || errcode == constant.WX_ERRCODE_SIGERR {
service.Wxpay.AddExpireInfo(reqJson.AccountId, sessionkeytime)
}
} else if orderModel.Status == 1 {
orderModel.Status = 2
orderModel.UpdateFields([]string{"status"})
}
}
func (this *InGameApi) OtherOrder(c *gin.Context) {
reqJson := struct {
AccountId string `json:"account_id" binding:"required"`
SessionId string `json:"session_id" binding:"required"`
}{}
if err := c.ShouldBindJSON(&reqJson); err != nil {
f5.RspErr(c, 401, "params error")
return
}
strs := strings.Split(reqJson.AccountId, "_")
if len(strs) < 3 {
f5.RspErr(c, 401, "params error1")
return
}
rediskey := "ls:accountid:" + reqJson.AccountId
str, err := service.Redis.Get(constant.LOGIN_REDIS, rediskey)
if err != nil {
f5.RspErr(c, 402, "invalid session")
return
}
data := map[string]interface{}{}
if json.Unmarshal([]byte(str), &data) != nil {
f5.RspErr(c, 402, "invalid session 1")
return
}
sessionkey := q5.SafeToString(data["session_key"])
if len(sessionkey) == 0 {
f5.GetSysLog().Debug("empty sessionkey:%s", reqJson.AccountId)
f5.RspErr(c, 402, "invalid session 2")
return
}
sessionkeytime := q5.SafeToInt64(data["update_time"])
if service.Wxpay.CheckExpireCache(reqJson.AccountId, sessionkeytime) {
f5.RspErr(c, 402, "session expired")
return
}
rspObj := struct {
ErrorCode int32 `json:"errcode"`
ErrMsg string `json:"errmsg"`
Count int64 `json:"count"`
}{}
gameid := q5.SafeToInt64(strs[1])
openid := q5.SafeToString(data["openid"])
userip := this.getIP(c)
balance, errcode, err := service.Wxpay.QueryBalance(openid, gameid, userip, sessionkey)
if err != nil {
f5.RspErr(c, 500, "wx server busy")
return
}
if errcode == constant.WX_ERRCODE_OK && balance > 0 {
nowTime := int32(f5.GetApp().GetRealSeconds())
order := new(model.InAppOrder)
order.AccountId = reqJson.AccountId
order.OrderId = "o" + q5.ToString(f5.GetApp().NewLockNodeUuid())
errcode = service.Wxpay.QueryPay(openid, gameid, userip, sessionkey, int32(balance), order.OrderId)
if errcode == constant.WX_ERRCODE_OK {
order.GameId = int32(gameid)
order.Channel = q5.SafeToInt32(strs[0])
order.IP = this.getIP(c)
order.Status = 2
order.SpOthers = int32(balance)
order.CreateTime = nowTime
order.ModifyTime = nowTime
if err := order.Create(); err != nil {
f5.GetSysLog().Error("record other order error:%s, %s, %d", reqJson.AccountId, order.OrderId, balance)
}
rspObj.Count = balance
}
} else if errcode == constant.WX_ERRCODE_SESSIONERR || errcode == constant.WX_ERRCODE_SIGERR {
service.Wxpay.AddExpireInfo(reqJson.AccountId, sessionkeytime)
rspObj.ErrorCode = 402
rspObj.ErrMsg = "invalid session 2"
}
c.JSON(200, rspObj)
}
func (iga *InGameApi) getIP(c *gin.Context) (ip string) {
ip = c.Request.Header.Get("X-Real-Ip")
if ip == "" {
ip = strings.Split(c.Request.Header.Get("X-Forwarded-For"), ",")[0]
}
if ip == "" {
ip = c.Request.RemoteAddr
}
return ip
}