Browse Source

battlepass

master
linquan 1 day ago
parent
commit
84acdd11ad
  1. 39
      api/v1/game/advertisement.go
  2. 12
      api/v1/game/manage.go
  3. 42
      api/v1/game/order.go
  4. 2
      api/v1/game/serverConfig.go
  5. 87
      api/v1/game/server_battle_pass.go
  6. 2
      go.sum
  7. 12
      internal/consts/consts.go
  8. 5
      internal/controller/game_order.go
  9. 10
      internal/controller/game_pub.go
  10. 10
      internal/controller/game_server.go
  11. 43
      internal/controller/server_battle_pass.go
  12. 2
      internal/dao/internal/advertisement_oceanegine.go
  13. 2
      internal/dao/internal/game_recharge.go
  14. 4
      internal/dao/internal/game_server_json_general.go
  15. 81
      internal/dao/internal/server_battle_pass.go
  16. 27
      internal/dao/server_battle_pass.go
  17. 1
      internal/model/do/advertisement_oceanegine.go
  18. 2
      internal/model/do/game_recharge.go
  19. 2
      internal/model/do/game_server_json_general.go
  20. 20
      internal/model/do/server_battle_pass.go
  21. 1
      internal/model/entity/advertisement_oceanegine.go
  22. 2
      internal/model/entity/game_recharge.go
  23. 2
      internal/model/entity/game_server_json_general.go
  24. 18
      internal/model/entity/server_battle_pass.go
  25. 4
      internal/router/router.go
  26. 74
      internal/service/hmsAccessToken.go
  27. 58
      internal/service/huaweiOrder.go
  28. 25
      internal/serviceGame/advertisement.go
  29. 24
      internal/serviceGame/cron.go
  30. 231
      internal/serviceGame/internal/advertisement.go
  31. 17
      internal/serviceGame/internal/dbinit.go
  32. 70
      internal/serviceGame/internal/manage.go
  33. 37
      internal/serviceGame/internal/rank.go
  34. 155
      internal/serviceGame/internal/server_battle_pass.go
  35. 6
      internal/serviceGame/manage.go
  36. 24
      internal/serviceGame/order.go
  37. 2
      internal/serviceGame/pub.go
  38. 68
      internal/serviceGame/server_battle_pass.go
  39. 14
      manifest/config/RootG2Ca.cer

39
api/v1/game/advertisement.go

@ -54,6 +54,7 @@ type ATHAReq struct {
Idfv string `p:"idfv"`
AndroidId string `p:"android_id"`
PackageName string `p:"package_name"`
UnitId string `p:"unitId"`
}
type HugeAmount struct {
@ -91,6 +92,7 @@ type CSHAReq struct {
Id string `p:"id"`
Idfa string `p:"idfa"`
Properties string `p:"properties"`
UnitId string `p:"unitId"`
}
type CSHARes struct {
@ -106,6 +108,7 @@ type AdvertiseHAReq struct {
Idfa string `p:"idfa"`
PackageName string `p:"package_name"`
Properties string `p:"properties"`
UnitId string `p:"unitId"`
}
type AdvertiseHARes struct {
@ -182,3 +185,39 @@ type AdvertiseHA5Res struct {
g.Meta `mime:"application/json"`
Code int `json:"code"`
}
type GetAccessTokenReq struct {
g.Meta `path:"/advertise/getAccessToken" tags:"ad" method:"post" summary:"GetAccessToken"`
State string `p:"state"`
AuthCode string `p:"auth_code"`
}
type GetAccessTokenRes struct {
g.Meta `mime:"application/json"`
Msg string `json:"msg"`
}
type RefreshAccessTokenReq struct {
g.Meta `path:"/advertise/refreshAccessToken" tags:"ad" method:"post" summary:"refreshAccessToken"`
}
type RefreshAccessTokenRes struct {
g.Meta `mime:"application/json"`
}
type GetCostReportReq struct {
g.Meta `path:"/advertise/getCostReport" tags:"ad" method:"post" summary:"getCostReport"`
AdvertiserId string `p:"advertiserId"`
StartDate string `p:"startDate"`
EndDate string `p:"endDate"`
}
type CostReport struct {
Cost float32 `json:"cost"`
DateTime string `json:"dateTime"`
}
type GetCostReportRes struct {
g.Meta `mime:"application/json"`
List []CostReport `json:"list"`
}

12
api/v1/game/manage.go

@ -242,3 +242,15 @@ type DelAccountReq struct {
type DelAccountRes struct {
}
type LogAccountReq struct {
g.Meta `path:"/mange/logAccount" tags:"账号" method:"get" summary:"删除账号"`
Server int32 `p:"server"`
Day int32 `p:"day"`
CDate string `p:"cDate"`
}
type LogAccountRes struct {
g.Meta `mime:"application/json"`
//List []entity.LoginLogoutInfo `p:"list"`
}

42
api/v1/game/order.go

@ -289,3 +289,45 @@ type GetTransactionIdRes struct {
g.Meta `mime:"application/json"`
Order *SignedTransaction `json:"order"`
}
// 获取订单号
type GetHuaWeiOrderListReq struct {
g.Meta `path:"/order/getHuaWeiOrderList" tags:"订单" method:"get" summary:"获取订单号"`
ContinuationToken string `p:"continuationToken"`
StartAt string `p:"startAt"`
EndAt string `p:"endAt"`
}
type HuaWeiOrderResponse struct {
ResponseCode string `json:"responseCode"`
ResponseMessage string `json:"responseMessage"`
ContinuationToken string `json:"continuationToken"`
OrderInfoList []HuaWeiOrderInfo `json:"orderInfoList"`
}
type HuaWeiOrderInfo struct {
OrderNo string `json:"orderNo"`
RequestId string `json:"requestId"`
Country string `json:"country"`
MerchantId string `json:"merchantId"`
ApplicationId string `json:"applicationId"`
OrderTime int64 `json:"orderTime"`
TradeTime int64 `json:"tradeTime"`
ProductId string `json:"productId"`
ProductName string `json:"productName"`
PayMoney string `json:"payMoney"`
CouponAmt string `json:"couponAmt"`
MpAmt string `json:"mpAmt"`
MpRfdAmt string `json:"mpRfdAmt"`
Currency string `json:"currency"`
PayType int32 `json:"payType"`
TradeState int32 `json:"tradeState"` //订单状态,取值如下: 0:成功 2:失败 4:未支付
TradeType string `json:"tradeType"`
OriOrderNo string `json:"oriOrderNo"`
RefundTime int64 `json:"refundTime"`
RefundMoney string `json:"refundMoney"`
}
type GetHuaWeiOrderListRes struct {
g.Meta `mime:"application/json"`
Order HuaWeiOrderResponse `json:"order"`
}

2
api/v1/game/serverConfig.go

@ -102,6 +102,8 @@ type GetServerConfigRes struct {
Platform int `json:"platform" description:""`
InnerIp string `json:"innerIp" description:""`
CreateTime int64 `json:"createTime" description:""`
ActivityDbUrl string `json:"activityDbUrl" description:""`
ActivityDbName string `json:"activityDbName" description:""`
}
type ServerReloadDllReq struct {

87
api/v1/game/server_battle_pass.go

@ -0,0 +1,87 @@
package game
import (
"github.com/gogf/gf/v2/frame/g"
"tyj_admin/internal/model/entity"
)
type GetBattlePassReq struct {
g.Meta `path:"/battlePass/get" tags:"战令" method:"get" summary:"获取战令"`
ServerId int32 `p:"serverId"`
PeriodId int32 `p:"periodId"`
}
type GetBattlePassRes struct {
g.Meta `mime:"application/json"`
List []map[string]interface{} `json:"list"`
}
type CheckPeriodIdReq struct {
g.Meta `path:"/battlePass/checkPeriodId" tags:"战令" method:"get" summary:"获取战令"`
PeriodId int32 `p:"periodId"`
}
type CheckPeriodIdRes struct {
g.Meta `mime:"application/json"`
List []map[string]interface{} `json:"list"`
}
type UpdateBattlePassReq struct {
g.Meta `path:"/battlePass/update" tags:"战令" method:"get" summary:"更新战令"`
Id string `p:"Id"`
BeginTime string `p:"BeginTime"`
EndTime string `p:"EndTime"`
State int32 `p:"State"`
//Server int32 `p:"Server"`
//PeriodId int32 `p:"PeriodId"`
}
type UpdateBattlePassRes struct {
}
type InsertBattlePassReq struct {
g.Meta `path:"/battlePass/insert" tags:"战令" method:"get" summary:"添加战令"`
BeginTime string `p:"BeginTime"`
EndTime string `p:"EndTime"`
State int32 `p:"State"`
Server int32 `p:"Server"`
PeriodId int32 `p:"PeriodId"`
}
type InsertBattlePassRes struct {
}
type CheckBattlePassReq struct {
g.Meta `path:"/battlePass/check" tags:"战令" method:"get" summary:"校验战令"`
BeginTime string `p:"BeginTime"`
Server int64 `p:"Server"`
PeriodId int64 `p:"PeriodId"`
}
type CheckBattlePassRes struct {
g.Meta `mime:"application/json"`
Total int64 `json:"total"`
}
type InsertBattlePassLogReq struct {
g.Meta `path:"/battlePassLog/add" tags:"log接口" method:"post" summary:"操作日志"`
PeriodId int32 `p:"periodId"`
Server int32 `p:"server"`
Uid int64 `p:"unitId"`
}
type InsertBattlePassLogRes struct {
g.Meta `mime:"application/json"`
}
type GetBattlePassLogReq struct {
g.Meta `path:"/battlePassLog/get" tags:"log接口" method:"get" summary:"操作日志"`
PeriodId int32 `p:"periodId"`
}
type GetBattlePassLogRes struct {
g.Meta `mime:"application/json"`
List []entity.ServerBattlePass `json:"list"`
RechargeTotal int `json:"rechargeTotal"`
Total int `json:"total"`
}

2
go.sum

@ -67,6 +67,8 @@ github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyM
github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cristalhq/jwt/v3 v3.1.0 h1:iLeL9VzB0SCtjCy9Kg53rMwTcrNm+GHyVcz2eUujz6s=
github.com/cristalhq/jwt/v3 v3.1.0/go.mod h1:XOnIXst8ozq/esy5N1XOlSyQqBd+84fxJ99FK+1jgL8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

12
internal/consts/consts.go

@ -97,3 +97,15 @@ const CHARSETDef = "0123456789abcdefghijklmnopqrstuvwxyz"
const CHARSETSpecial = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
const DEFAULT_HOST = "127.0.0.1"
const (
ADVERTISE_DATA_SAVE = "oceanengine"
ADVERTISE_REFRESH_TOKEN = "refresh_token"
ADVERTISE_ACCESS_TOKEN = "access_token"
ADVERTISE_TOKEN_REFRESH_TIME = "refresh_token_time"
ADVERTISE_TOKEN_REFRESH_SIGN = "refresh_token_sign"
)
const (
PeachAdmin_Db_Battle_pass = "BattlePass"
)

5
internal/controller/game_order.go

@ -95,3 +95,8 @@ func (c *orderController) GetTransactionId(ctx context.Context, req *game.GetTra
res, err = serviceGame.GameOrder().GetTransactionId(ctx, req)
return
}
func (c *orderController) GetHuaWeiOrderList(ctx context.Context, req *game.GetHuaWeiOrderListReq) (res *game.GetHuaWeiOrderListRes, err error) {
res, err = serviceGame.GameOrder().GetHuaWeiOrderList(ctx, req)
return
}

10
internal/controller/game_pub.go

@ -176,3 +176,13 @@ func (c *pubController) AdvertiseHugeAmount5(ctx context.Context, req *game.Adve
err = serviceGame.Advertisement().AdvertiseHugeAmount1(ctx, req.Androidid, req.Idfa, req.Os, req.Callback, req.TIMESTAMP)
return
}
func (c *pubController) GetAccessToken(ctx context.Context, req *game.GetAccessTokenReq) (res *game.GetAccessTokenRes, err error) {
res, err = serviceGame.Advertisement().GetAccessToken(ctx, req)
return
}
func (c *pubController) RefreshAccessToken(ctx context.Context, req *game.RefreshAccessTokenReq) (res *game.RefreshAccessTokenRes, err error) {
res, err = serviceGame.Advertisement().RefreshAccessToken(ctx, req)
return
}

10
internal/controller/game_server.go

@ -109,3 +109,13 @@ func (c *serverController) GetTransactionId(ctx context.Context, req *game.GetTr
res, err = serviceGame.GameOrder().GetTransactionId(ctx, req)
return
}
func (c *serverController) BattlePass(ctx context.Context, req *game.InsertBattlePassLogReq) (res *game.InsertBattlePassLogRes, err error) {
res, err = serviceGame.GameBattlePass().BattlePassLog(ctx, req)
return
}
func (c *serverController) LogAccount(ctx context.Context, req *game.LogAccountReq) (res *game.LogAccountRes, err error) {
res, err = serviceGame.GameManage().LogAccount(ctx, req)
return
}

43
internal/controller/server_battle_pass.go

@ -0,0 +1,43 @@
package controller
import (
"context"
"tyj_admin/api/v1/game"
"tyj_admin/internal/serviceGame"
)
var GameBattlePass = battlePassController{}
type battlePassController struct {
BaseController
}
func (c *battlePassController) Get(ctx context.Context, req *game.GetBattlePassReq) (res *game.GetBattlePassRes, err error) {
res, err = serviceGame.GameBattlePass().Get(ctx, req)
return
}
func (c *battlePassController) CheckPeriodId(ctx context.Context, req *game.CheckPeriodIdReq) (res *game.CheckPeriodIdRes, err error) {
res, err = serviceGame.GameBattlePass().CheckPeriodId(ctx, req)
return
}
func (c *battlePassController) Update(ctx context.Context, req *game.UpdateBattlePassReq) (res *game.UpdateBattlePassRes, err error) {
res, err = serviceGame.GameBattlePass().Update(ctx, req)
return
}
func (c *battlePassController) Insert(ctx context.Context, req *game.InsertBattlePassReq) (res *game.InsertBattlePassRes, err error) {
res, err = serviceGame.GameBattlePass().Insert(ctx, req)
return
}
func (c *battlePassController) Check(ctx context.Context, req *game.CheckBattlePassReq) (res *game.CheckBattlePassRes, err error) {
res, err = serviceGame.GameBattlePass().Check(ctx, req)
return
}
func (c *battlePassController) GetBattlePassLog(ctx context.Context, req *game.GetBattlePassLogReq) (res *game.GetBattlePassLogRes, err error) {
res, err = serviceGame.GameBattlePass().GetBattlePassLog(ctx, req)
return
}

2
internal/dao/internal/advertisement_oceanegine.go

@ -29,6 +29,7 @@ type AdvertisementOceanegineColumns struct {
CDate string //
Idfa string //
Os string // 安卓:0 IOS:1 其他:3
UnitId string //
}
// advertisementOceanegineColumns holds the columns for table advertisement_oceanegine.
@ -42,6 +43,7 @@ var advertisementOceanegineColumns = AdvertisementOceanegineColumns{
CDate: "c_date",
Idfa: "idfa",
Os: "os",
UnitId: "unitId",
}
// NewAdvertisementOceanegineDao creates and returns a new DAO object for table data access.

2
internal/dao/internal/game_recharge.go

@ -21,7 +21,7 @@ type GameRechargeDao struct {
// GameRechargeColumns defines and stores column names for table game_recharge.
type GameRechargeColumns struct {
Id string //
UnitId string // 账号
UnitId string // 唯一ID
Channel string // 渠道
Server string // 区服
Amount string // 充值金额

4
internal/dao/internal/game_server_json_general.go

@ -27,6 +27,8 @@ type GameServerJsonGeneralColumns struct {
RechargeWhiteListIps string //
GmWhiteListUrl string //
BackstageRechargeUrl string //
ActivityDbUrl string //
ActivityDbName string //
}
// gameServerJsonGeneralColumns holds the columns for table game_server_json_general.
@ -38,6 +40,8 @@ var gameServerJsonGeneralColumns = GameServerJsonGeneralColumns{
RechargeWhiteListIps: "recharge_white_list_ips",
GmWhiteListUrl: "gm_white_list_url",
BackstageRechargeUrl: "backstage_recharge_url",
ActivityDbUrl: "activity_db_url",
ActivityDbName: "activity_db_name",
}
// NewGameServerJsonGeneralDao creates and returns a new DAO object for table data access.

81
internal/dao/internal/server_battle_pass.go

@ -0,0 +1,81 @@
// ==========================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package internal
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
)
// ServerBattlePassDao is the data access object for table server_battle_pass.
type ServerBattlePassDao struct {
table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of current DAO.
columns ServerBattlePassColumns // columns contains all the column names of Table for convenient usage.
}
// ServerBattlePassColumns defines and stores column names for table server_battle_pass.
type ServerBattlePassColumns struct {
Id string //
Server string // 区服
Uid string // 账号id
PeriodId string // 战令期数
CDate string // 创建时间
}
// serverBattlePassColumns holds the columns for table server_battle_pass.
var serverBattlePassColumns = ServerBattlePassColumns{
Id: "id",
Server: "server",
Uid: "uid",
PeriodId: "period_id",
CDate: "c_date",
}
// NewServerBattlePassDao creates and returns a new DAO object for table data access.
func NewServerBattlePassDao() *ServerBattlePassDao {
return &ServerBattlePassDao{
group: "default",
table: "server_battle_pass",
columns: serverBattlePassColumns,
}
}
// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *ServerBattlePassDao) DB() gdb.DB {
return g.DB(dao.group)
}
// Table returns the table name of current dao.
func (dao *ServerBattlePassDao) Table() string {
return dao.table
}
// Columns returns all column names of current dao.
func (dao *ServerBattlePassDao) Columns() ServerBattlePassColumns {
return dao.columns
}
// Group returns the configuration group name of database of current dao.
func (dao *ServerBattlePassDao) Group() string {
return dao.group
}
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *ServerBattlePassDao) Ctx(ctx context.Context) *gdb.Model {
return dao.DB().Model(dao.table).Safe().Ctx(ctx)
}
// Transaction wraps the transaction logic using function f.
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
// It commits the transaction and returns nil if function f returns nil.
//
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function.
func (dao *ServerBattlePassDao) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) (err error) {
return dao.Ctx(ctx).Transaction(ctx, f)
}

27
internal/dao/server_battle_pass.go

@ -0,0 +1,27 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package dao
import (
"tyj_admin/internal/dao/internal"
)
// internalServerBattlePassDao is internal type for wrapping internal DAO implements.
type internalServerBattlePassDao = *internal.ServerBattlePassDao
// serverBattlePassDao is the data access object for table server_battle_pass.
// You can define custom methods on it to extend its functionality as you wish.
type serverBattlePassDao struct {
internalServerBattlePassDao
}
var (
// ServerBattlePass is globally public accessible object for table server_battle_pass operations.
ServerBattlePass = serverBattlePassDao{
internal.NewServerBattlePassDao(),
}
)
// Fill with you ideas below.

1
internal/model/do/advertisement_oceanegine.go

@ -21,4 +21,5 @@ type AdvertisementOceanegine struct {
CDate *gtime.Time //
Idfa interface{} //
Os interface{} // 安卓:0 IOS:1 其他:3
UnitId interface{} //
}

2
internal/model/do/game_recharge.go

@ -13,7 +13,7 @@ import (
type GameRecharge struct {
g.Meta `orm:"table:game_recharge, do:true"`
Id interface{} //
UnitId interface{} // 账号
UnitId interface{} // 唯一ID
Channel interface{} // 渠道
Server interface{} // 区服
Amount interface{} // 充值金额

2
internal/model/do/game_server_json_general.go

@ -18,4 +18,6 @@ type GameServerJsonGeneral struct {
RechargeWhiteListIps interface{} //
GmWhiteListUrl interface{} //
BackstageRechargeUrl interface{} //
ActivityDbUrl interface{} //
ActivityDbName interface{} //
}

20
internal/model/do/server_battle_pass.go

@ -0,0 +1,20 @@
// =================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// ServerBattlePass is the golang structure of table server_battle_pass for DAO operations like Where/Data.
type ServerBattlePass struct {
g.Meta `orm:"table:server_battle_pass, do:true"`
Id interface{} //
Server interface{} // 区服
Uid interface{} // 账号id
PeriodId interface{} // 战令期数
CDate *gtime.Time // 创建时间
}

1
internal/model/entity/advertisement_oceanegine.go

@ -19,4 +19,5 @@ type AdvertisementOceanegine struct {
CDate *gtime.Time `json:"cDate" description:""`
Idfa string `json:"idfa" description:""`
Os int `json:"os" description:"安卓:0 IOS:1 其他:3"`
UnitId int64 `json:"unitId" description:""`
}

2
internal/model/entity/game_recharge.go

@ -11,7 +11,7 @@ import (
// GameRecharge is the golang structure for table game_recharge.
type GameRecharge struct {
Id int64 `json:"id" description:""`
UnitId int64 `json:"unitId" description:"账号"`
UnitId int64 `json:"unitId" description:"唯一ID"`
Channel string `json:"channel" description:"渠道"`
Server int `json:"server" description:"区服"`
Amount int `json:"amount" description:"充值金额"`

2
internal/model/entity/game_server_json_general.go

@ -13,4 +13,6 @@ type GameServerJsonGeneral struct {
RechargeWhiteListIps string `json:"rechargeWhiteListIps" description:""`
GmWhiteListUrl string `json:"gmWhiteListUrl" description:""`
BackstageRechargeUrl string `json:"backstageRechargeUrl" description:""`
ActivityDbUrl string `json:"activityDbUrl" description:""`
ActivityDbName string `json:"activityDbName" description:""`
}

18
internal/model/entity/server_battle_pass.go

@ -0,0 +1,18 @@
// =================================================================================
// Code generated by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// ServerBattlePass is the golang structure for table server_battle_pass.
type ServerBattlePass struct {
Id int64 `json:"id" description:""`
Server int `json:"server" description:"区服"`
Uid int64 `json:"uid" description:"账号id"`
PeriodId int `json:"periodId" description:"战令期数"`
CDate *gtime.Time `json:"cDate" description:"创建时间"`
}

4
internal/router/router.go

@ -175,6 +175,7 @@ func GameBindController(group *ghttp.RouterGroup) {
controller.Advertisement,
controller.GameBug,
controller.GameChannel,
controller.GameBattlePass,
)
})
}
@ -186,6 +187,7 @@ func GameBindFrontController(group *ghttp.RouterGroup) {
controller.OutCCD,
controller.OutId,
controller.GameRebate,
controller.GameServer)
controller.GameServer,
)
})
}

74
internal/service/hmsAccessToken.go

@ -0,0 +1,74 @@
package service
import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
)
type DemoConfig struct {
ClientSecret string
ClientId string
TokenUrl string
RootUrlOrder string
AccessToken string
}
func GetDefaultConfig() *DemoConfig {
var demoConfig DemoConfig
// TODO: (clientId, clientSecret, tokenUrl)请使用实际值替换
// App secret, 在AppGallery Connect创建应用之后,系统自动分配的公钥
demoConfig.ClientSecret = "524921589d516c7216951aa389c030681923cd22dfc4477871f9306430eefb6d"
// client id指的是您的APP ID
// App ID, 在AppGallery Connect创建应用之后,系统自动分配的唯一标识符
demoConfig.ClientId = "112487401"
// 用于获取authorization token的url,具体请参见基于OAuth 2.0开放鉴权
demoConfig.TokenUrl = "https://oauth-login.cloud.huawei.com/oauth2/v3/token"
return &demoConfig
}
type AtResponse struct {
AccessToken string `json:"access_token"`
}
type AtClient struct {
}
var AtDemo = &AtClient{}
func (atDemo *AtClient) GetAppAt() (string, error) {
demoConfig := GetDefaultConfig()
urlValue := url.Values{"grant_type": {"client_credentials"}, "client_secret": {demoConfig.ClientSecret}, "client_id": {demoConfig.ClientId}}
resp, err := http.PostForm(demoConfig.TokenUrl, urlValue)
if err != nil {
return "", err
}
defer resp.Body.Close()
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
var atResponse AtResponse
json.Unmarshal(bodyBytes, &atResponse)
if atResponse.AccessToken != "" {
return atResponse.AccessToken, nil
} else {
return "", errors.New("Get token fail, " + string(bodyBytes))
}
}
func BuildAuthorization() (string, error) {
appAt, err := AtDemo.GetAppAt()
if err != nil {
return "", err
}
oriString := fmt.Sprintf("APPAT:%s", appAt)
var authString = base64.StdEncoding.EncodeToString([]byte(oriString))
var authHeaderString = fmt.Sprintf("Basic %s", authString)
return authHeaderString, nil
}

58
internal/service/huaweiOrder.go

@ -0,0 +1,58 @@
package service
import (
"encoding/json"
"errors"
"fmt"
"github.com/gogf/gf/v2/encoding/gjson"
"io/ioutil"
"net/http"
"strings"
"time"
"tyj_admin/api/v1/game"
)
func GetHuaWeiConfig() *DemoConfig {
var demoConfig DemoConfig
demoConfig.RootUrlOrder = "https://orders-drcn.iap.cloud.huawei.com.cn/applications/v1/merchantQuery"
return &demoConfig
}
func GetHuaWeiOrderList(continuationToken string, startAt, endAt int64) (*game.HuaWeiOrderResponse, error) {
demoConfig := GetHuaWeiConfig()
urlValue := map[string]interface{}{
"startAt": startAt,
"endAt": endAt,
}
if len(continuationToken) > 0 {
urlValue["continuationToken"] = continuationToken
}
var atResponse game.HuaWeiOrderResponse
req, err := http.NewRequest("POST", demoConfig.RootUrlOrder, strings.NewReader(gjson.MustEncodeString(urlValue)))
if err != nil {
return &atResponse, err
}
auth, _ := BuildAuthorization()
req.Header.Set("Authorization", auth)
req.Header.Set("Content-Type", "application/json; charset=UTF-8")
req.Header.Set("Accept", "application/json")
client := &http.Client{Timeout: 15 * time.Second}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("API请求失败: %v", err)
}
defer resp.Body.Close()
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return &atResponse, err
}
_ = json.Unmarshal(bodyBytes, &atResponse)
if atResponse.ResponseCode != "" {
return &atResponse, nil
} else {
return &atResponse, errors.New("Get order fail, " + string(bodyBytes))
}
}

25
internal/serviceGame/advertisement.go

@ -17,6 +17,8 @@ type IAdvertisement interface {
ConversionHugeAmount(ctx context.Context, req *game.CSHAReq) (res *game.CSHARes, err error)
AdvertiseHugeAmount(ctx context.Context, req *game.AdvertiseHAReq) (res *game.AdvertiseHARes, err error)
AdvertiseHugeAmount1(ctx context.Context, androidId, idfa, os, callBack, timestamp string) (err error)
GetAccessToken(ctx context.Context, req *game.GetAccessTokenReq) (res *game.GetAccessTokenRes, err error)
RefreshAccessToken(ctx context.Context, req *game.RefreshAccessTokenReq) (res *game.RefreshAccessTokenRes, err error)
}
type advertisementImpl struct {
@ -46,18 +48,18 @@ func (g *advertisementImpl) AttributionHugeAmount(ctx context.Context, req *game
return
}
func (g *advertisementImpl) AdvertiseHugeAmount(ctx context.Context, req *game.AdvertiseHAReq) (res *game.AdvertiseHARes, err error) {
res = new(game.AdvertiseHARes)
res, err = internal.AdvertiseHugeAmount(ctx, req)
return
}
func (g *advertisementImpl) ConversionHugeAmount(ctx context.Context, req *game.CSHAReq) (res *game.CSHARes, err error) {
res = new(game.CSHARes)
res, err = internal.ConversionHugeAmount(ctx, req)
return
}
func (g *advertisementImpl) AdvertiseHugeAmount(ctx context.Context, req *game.AdvertiseHAReq) (res *game.AdvertiseHARes, err error) {
res = new(game.AdvertiseHARes)
res, err = internal.AdvertiseHugeAmount(ctx, req)
return
}
func (g *advertisementImpl) AdvertiseHugeAmount1(ctx context.Context, androidId, idfa, os, callBack, timestamp string) (err error) {
osInt, err := strconv.Atoi(os)
if err != nil {
@ -81,3 +83,14 @@ func (g *advertisementImpl) AdvertiseHugeAmount1(ctx context.Context, androidId,
})
return
}
func (g *advertisementImpl) GetAccessToken(ctx context.Context, req *game.GetAccessTokenReq) (res *game.GetAccessTokenRes, err error) {
res = new(game.GetAccessTokenRes)
res.Msg = internal.GetAccessToken(ctx, req.AuthCode)
return
}
func (g *advertisementImpl) RefreshAccessToken(ctx context.Context, req *game.RefreshAccessTokenReq) (res *game.RefreshAccessTokenRes, err error) {
internal.RefreshAccessToken(ctx)
return
}

24
internal/serviceGame/cron.go

@ -16,6 +16,8 @@ import (
var (
notices []entity.GameNoticeLog
mails []entity.Mail
advertiseTime time.Time
)
func init() {
@ -30,12 +32,14 @@ func init() {
_ = model.Scan(&notices)
mails, _ = internal.GetCornMails(ctx, consts.Mail_Send_Time)
go func() {
for {
//从定时器中获取数据
t := <-ticker.C
gameCronService.Cron(t.UnixMilli())
gameCronService.MailCron(t.UnixMilli())
gameCronService.CronAdvertisement(ctx, t.Unix())
}
}()
@ -197,3 +201,23 @@ func (c *gameCronImpl) MailCron(sTime int64) {
}
return
}
func (c *gameCronImpl) CronAdvertisement(ctx context.Context, sTime int64) {
rdbTop := internal.RedisDbList[0]
rdbTop.Do(ctx, "select", 0)
redisRes := rdbTop.HGet(ctx, consts.ADVERTISE_DATA_SAVE, consts.ADVERTISE_TOKEN_REFRESH_TIME)
if redisRes.Val() == "" {
return
}
advertiseTime, _ = time.ParseInLocation(consts.TIME_FORMAT, redisRes.Val(), time.Local)
now := advertiseTime.Unix() + 23*60*60
redisSign := rdbTop.HGet(ctx, consts.ADVERTISE_DATA_SAVE, consts.ADVERTISE_TOKEN_REFRESH_SIGN)
if redisSign.Val() == "1" {
return
}
if now <= sTime {
rdbTop.HSet(ctx, consts.ADVERTISE_DATA_SAVE, consts.ADVERTISE_TOKEN_REFRESH_SIGN, 1)
internal.RefreshAccessToken(ctx)
rdbTop.HSet(ctx, consts.ADVERTISE_DATA_SAVE, consts.ADVERTISE_TOKEN_REFRESH_SIGN, 0)
}
}

231
internal/serviceGame/internal/advertisement.go

@ -117,9 +117,9 @@ func AttributionHugeAmount(ctx context.Context, req *game.ATHAReq) (res *game.AT
var adData []entity.AdvertisementOceanegine
model := dao.AdvertisementOceanegine.Ctx(ctx).Order("last_touch_time desc")
if req.Platform == "android" {
if req.AndroidId != "" {
_ = model.Where("adv_android_id=?", req.AndroidId).Scan(&adData)
}
//if req.AndroidId != "" {
_ = model.Where("adv_android_id=?", req.AndroidId).Page(1, 1).Scan(&adData)
//}
if len(adData) == 0 {
log.Printf("AttributionHugeAmount: adData is nil %s", gjson.MustEncodeString(req))
err = errors.New("account is nil")
@ -127,19 +127,19 @@ func AttributionHugeAmount(ctx context.Context, req *game.ATHAReq) (res *game.AT
}
data["android_id"] = req.AndroidId
} else if req.Platform == "ios" {
if req.Idfa != "" {
_ = model.Where("idfa=?", req.Idfa).Scan(&adData)
}
//if req.Idfa != "" {
_ = model.Where("idfa=?", req.Idfa).Page(1, 1).Scan(&adData)
//}
//if len(adData) == 0 {
// if req.Idfv != "" {
// _ = model.Where("adv_idfv=?", req.Idfv).Scan(&adData)
// }
if len(adData) == 0 {
if req.Idfv != "" {
_ = model.Where("adv_idfv=?", req.Idfv).Scan(&adData)
}
if len(adData) == 0 {
log.Printf("AttributionHugeAmount: adData is nil %s", gjson.MustEncodeString(req))
err = errors.New("account is nil")
return
}
log.Printf("AttributionHugeAmount: adData is nil %s", gjson.MustEncodeString(req))
err = errors.New("account is nil")
return
}
//}
data["idfv"] = req.Idfv
} else {
err = errors.New("platform is error " + req.Platform)
@ -155,37 +155,55 @@ func AttributionHugeAmount(ctx context.Context, req *game.ATHAReq) (res *game.AT
if err != nil {
return
}
json, err := gjson.DecodeToJson(tmp)
resJson, err := gjson.DecodeToJson(tmp)
if err != nil {
return
}
if json != nil && json.Get("code").Int() == 0 {
callbackUrl := json.Get("callback_url").String()
callbackParam := json.Get("callback_param").String()
androidId := json.Get("adv_android_id").String()
if androidId == "" {
androidId = req.AndroidId
}
idfa := json.Get("idfa").String()
if idfa == "" {
idfa = req.Idfa
if resJson != nil && resJson.Get("code").Int() == 0 {
callbackUrl := resJson.Get("callback_url").String()
callbackParam := resJson.Get("callback_param").String()
if callbackParam == "" {
err = errors.New("callbackParam nil")
return
}
advIdfv := json.Get("adv_idfv").String()
if advIdfv == "" {
advIdfv = req.Idfv
androidId := resJson.Get("adv_android_id").String()
//if androidId == "" {
// androidId = req.AndroidId
//}
idfa := resJson.Get("idfa").String()
//if idfa == "" {
// idfa = req.Idfa
//}
advIdfv := resJson.Get("adv_idfv").String()
//if advIdfv == "" {
// advIdfv = req.Idfv
//}
lastTouchTime := resJson.Get("last_touch_time").Int64() * 1000
if adData[0].LastTouchTime == lastTouchTime {
err = errors.New("lastTouchTime repeat")
return
}
lastTouchTime := json.Get("last_touch_time").Int64()
advertiseData := do.AdvertisementOceanegine{AdvAndroidId: androidId, Idfa: idfa, AdvIdfv: advIdfv,
CallbackUrl: callbackUrl, CallbackParam: callbackParam, LastTouchTime: lastTouchTime * 1000}
CallbackUrl: callbackUrl, CallbackParam: callbackParam, LastTouchTime: lastTouchTime, UnitId: req.UnitId}
if req.Platform == "android" {
advertiseData.Os = 0
if androidId == "00000000-0000-0000-0000-000000000000" || androidId == "" {
err = errors.New("androidId default")
return
}
} else if req.Platform == "ios" {
advertiseData.Os = 1
if idfa == "00000000-0000-0000-0000-000000000000" || idfa == "" {
err = errors.New("idfa default")
return
}
if advIdfv == "" {
err = errors.New("adv_idfv default")
return
}
}
if callbackParam == "" {
return
}
_, err = dao.AdvertisementOceanegine.Ctx(ctx).Insert(advertiseData)
} else {
err = errors.New("获取失败")
@ -203,9 +221,9 @@ func ConversionHugeAmount(ctx context.Context, req *game.CSHAReq) (res *game.CSH
}
model := dao.AdvertisementOceanegine.Ctx(ctx).Order("last_touch_time desc")
if req.Platform == "android" {
if req.Id != "" {
_ = model.Where("adv_android_id=?", req.Id).Scan(&adData)
}
//if req.Id != "" && req.Id != "00000000-0000-0000-0000-000000000000" {
_ = model.Where("adv_android_id=?", req.Id).Page(1, 1).Scan(&adData)
//}
if len(adData) == 0 {
log.Printf("ConversionHugeAmount: adData is nil %s", gjson.MustEncodeString(req))
err = errors.New("account is nil")
@ -213,19 +231,19 @@ func ConversionHugeAmount(ctx context.Context, req *game.CSHAReq) (res *game.CSH
}
device["android_id"] = req.Id
} else if req.Platform == "ios" {
if req.Idfa != "" {
_ = model.Where("idfa=?", req.Idfa).Scan(&adData)
}
//if req.Idfa != "" && req.Idfa != "00000000-0000-0000-0000-000000000000" {
_ = model.Where("idfa=?", req.Idfa).Page(1, 1).Scan(&adData)
//}
//if len(adData) == 0 {
// if req.Id != "" {
// _ = model.Where("adv_idfv=?", req.Id).Scan(&adData)
// }
if len(adData) == 0 {
if req.Id != "" {
_ = model.Where("adv_idfv=?", req.Id).Scan(&adData)
}
if len(adData) == 0 {
log.Printf("ConversionHugeAmount: adData is nil %s", gjson.MustEncodeString(req))
err = errors.New("account is nil")
return
}
log.Printf("ConversionHugeAmount: adData is nil %s", gjson.MustEncodeString(req))
err = errors.New("account is nil")
return
}
//}
device["idfv"] = req.Id
} else {
err = errors.New("platform is error " + req.Platform)
@ -267,9 +285,9 @@ func ConversionHugeAmount(ctx context.Context, req *game.CSHAReq) (res *game.CSH
if err != nil {
return
}
json, err := gjson.DecodeToJson(tmp)
if json != nil && json.Get("code").Int() != 0 {
err = errors.New(json.Get("message").String())
resJson, err := gjson.DecodeToJson(tmp)
if resJson != nil && resJson.Get("code").Int() != 0 {
err = errors.New(resJson.Get("message").String())
}
return
}
@ -293,6 +311,7 @@ func HugeAmount(ctx context.Context, req *game.AdvertiseHAReq) {
Idfa: req.Idfa,
EventType: req.EventType,
Properties: req.Properties,
UnitId: req.UnitId,
}
req2.Id = req.Id
_, err := ConversionHugeAmount(ctx, &req2)
@ -304,6 +323,7 @@ func HugeAmount(ctx context.Context, req *game.AdvertiseHAReq) {
Platform: req.Platform,
PackageName: req.PackageName,
Idfa: req.Idfa,
UnitId: req.UnitId,
}
if req.Platform == "android" {
req1.AndroidId = req.Id
@ -320,3 +340,114 @@ func HugeAmount(ctx context.Context, req *game.AdvertiseHAReq) {
}
return
}
func GetAccessToken(ctx context.Context, authCode string) string {
url := "https://api.oceanengine.com/open_api/oauth2/access_token/"
g.Client().SetHeader("Access-Token ", "application/json;charset=UTF-8")
data := map[string]interface{}{
"app_id": Oceanengine.Appid, "secret": Oceanengine.Secret, "auth_code": authCode,
}
marshal, _ := json.Marshal(data)
bytes, err := g.Client().Post(ctx, url, string(marshal))
if err != nil {
return ""
}
src := string(bytes.ReadAll())
tmp, err := gcharset.ToUTF8("UTF-8", src)
if err != nil {
return ""
}
fmt.Println("GetAccessToken - json: ", tmp)
resJson, err := gjson.DecodeToJson(tmp)
if err != nil {
return ""
}
if resJson != nil && resJson.Get("code").Int() == 0 {
resData := resJson.GetJson("data")
rdbTop := RedisDbList[0]
rdbTop.Do(ctx, "select", 0)
rdbTop.HSet(ctx, consts.ADVERTISE_DATA_SAVE, consts.ADVERTISE_ACCESS_TOKEN, resData.Get(consts.ADVERTISE_ACCESS_TOKEN).String())
rdbTop.HSet(ctx, consts.ADVERTISE_DATA_SAVE, consts.ADVERTISE_ACCESS_TOKEN, resData.Get(consts.ADVERTISE_REFRESH_TOKEN).String())
rdbTop.HSet(ctx, consts.ADVERTISE_DATA_SAVE, consts.ADVERTISE_TOKEN_REFRESH_TIME, time.Now().Format(consts.TIME_FORMAT))
return "获取成功"
}
return ""
}
func RefreshAccessToken(ctx context.Context) {
url := "https://ad.oceanengine.com/open_api/oauth2/refresh_token/"
rdbTop := RedisDbList[0]
rdbTop.Do(ctx, "select", 0)
redisRes := rdbTop.HGet(ctx, consts.ADVERTISE_DATA_SAVE, consts.ADVERTISE_REFRESH_TOKEN)
g.Client().SetHeader("Access-Token ", "application/json;charset=UTF-8")
data := map[string]interface{}{
"app_id": Oceanengine.Appid, "secret": Oceanengine.Secret, "grant_type": "refresh_token", "refresh_token": redisRes.Val(),
}
marshal, _ := json.Marshal(data)
bytes, err := g.Client().Post(ctx, url, string(marshal))
if err != nil {
return
}
src := string(bytes.ReadAll())
tmp, err := gcharset.ToUTF8("UTF-8", src)
if err != nil {
return
}
fmt.Println("RefreshAccessToken - json: ", tmp)
resJson, err := gjson.DecodeToJson(tmp)
if err != nil {
return
}
if resJson != nil && resJson.Get("code").Int() == 0 {
resData := resJson.GetJson("data")
rdbTop.Do(ctx, "select", 0)
rdbTop.HSet(ctx, consts.ADVERTISE_DATA_SAVE, consts.ADVERTISE_ACCESS_TOKEN, resData.Get(consts.ADVERTISE_ACCESS_TOKEN).String())
rdbTop.HSet(ctx, consts.ADVERTISE_DATA_SAVE, consts.ADVERTISE_REFRESH_TOKEN, resData.Get(consts.ADVERTISE_REFRESH_TOKEN).String())
rdbTop.HSet(ctx, consts.ADVERTISE_DATA_SAVE, consts.ADVERTISE_TOKEN_REFRESH_TIME, time.Now().Format(consts.TIME_FORMAT))
}
return
}
func GetCostReport(ctx context.Context, req *game.GetCostReportReq) (res *game.GetCostReportRes, err error) {
res = new(game.GetCostReportRes)
g.Client().SetHeader("Access-Token ", "application/json;charset=UTF-8")
url := "https://ad.oceanengine.com/open_api/2/report/advertiser/get/"
log.Printf("sendMsgHugeAmount - url: %s, data: %s", url, gjson.MustEncodeString(req))
bytes, err := g.Client().Get(ctx, url, map[string]interface{}{
"advertiser_id": req.AdvertiserId,
"start_date ": req.StartDate,
"end_date ": req.EndDate,
"fields": []string{"cost"},
"time_granularity": "STAT_TIME_GRANULARITY_DAILY",
})
if err != nil {
return res, err
}
src := string(bytes.ReadAll())
tmp, err := gcharset.ToUTF8("UTF-8", src)
if err != nil {
return res, err
}
fmt.Println("Deposit - json: ", tmp)
resJson, err := gjson.DecodeToJson(tmp)
if err != nil {
return res, err
}
if resJson != nil && resJson.Get("code").Int() == 0 {
data := resJson.GetJson("data")
list := data.GetJsons("list")
for _, v := range list {
datetime := v.Get("stat_datetime").String()
cost := v.Get("cost").Float32()
res.List = append(res.List, game.CostReport{
Cost: cost,
DateTime: datetime,
})
}
}
return res, err
}

17
internal/serviceGame/internal/dbinit.go

@ -22,6 +22,11 @@ type MongoType struct {
Id string `json:"id"`
}
type OceanengineMap struct {
Appid string `json:"appid"`
Secret string `json:"secret"`
}
var (
MongoDatabaseList map[string]*qmgo.Database
MongoConfigs map[string]MongoType
@ -34,6 +39,7 @@ var (
Md5key string
CallbackKey string
Webhook string
Oceanengine OceanengineMap
)
func init() {
@ -74,6 +80,7 @@ func init() {
}
WebHookInit(ctx)
OceanengineInit(ctx)
}
func RedisInit(config []map[string]interface{}) {
@ -182,3 +189,13 @@ func WebHookInit(ctx context.Context) {
}
Webhook = webhook.String()
}
func OceanengineInit(ctx context.Context) {
c, err := g.Cfg().Get(ctx, "game.oceanengine")
if err != nil {
return
}
oceanengine := c.MapStrStr()
Oceanengine.Appid = oceanengine["appid"]
Oceanengine.Secret = oceanengine["secret"]
}

70
internal/serviceGame/internal/manage.go

@ -9,6 +9,9 @@ import (
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"os"
"strconv"
"time"
"tyj_admin/api/v1/game"
"tyj_admin/internal/consts"
@ -291,3 +294,70 @@ func RegisterNum(ctx context.Context, req *game.RegisterCountReq) (res *game.Reg
g.Log().Info(ctx, "a== ", res)
return
}
func LogAccount(ctx context.Context, req *game.LogAccountReq) (res *game.LogAccountRes, err error) {
res = new(game.LogAccountRes)
modelTotal := dao.LoginLogoutInfo.Ctx(ctx)
if req.Server != 0 {
modelTotal = modelTotal.Where(`server=?`, req.Server)
}
day := int32(1000)
if req.Day != 0 {
day = req.Day
}
cDate := "2025-07-18 00:00:00"
if req.CDate != "" {
cDate = req.CDate
}
var list []entity.LoginLogoutInfo
err = modelTotal.
Fields("uid", "server", "max(day) day", "max(c_date) c_date").
Where("c_date>=", cDate).
Where("day>=", day).
Group("server", "uid").
Scan(&list)
for _, v := range list {
getUnitDay(ctx, v.Server, v.Uid, v.Day)
}
return
}
func getUnitDay(ctx context.Context, server int, uid int64, day int) {
mongodb, ok := MongoDatabaseList[fmt.Sprint(server)]
if !ok {
g.Log().Info(ctx, "err== db is nil")
return
}
query := bson.M{"_id": uid, "C.Day": bson.M{"$lt": day}}
stores := []map[string]interface{}{}
err := mongodb.Collection("Unit").Find(ctx, query).Select(bson.M{"_id": 1, "UniqueId": 1, "C.Day": 1}).All(&stores)
if err != nil {
g.Log().Info(ctx, "err== ", err)
return
}
if len(stores) <= 0 {
g.Log().Infof(ctx, "uid: %d, server: %d err== unit is nil", uid, server)
return
}
var uDay int
child := stores[0]["C"].(primitive.A)
for _, v := range child {
item := v.(map[string]interface{})
if _, ok := item["Day"]; ok {
uDay, _ = strconv.Atoi(fmt.Sprint(item["Day"]))
}
}
if uDay > day {
g.Log().Infof(ctx, "uid: %d, server: %d err== old > now", uid, server)
return
}
data := fmt.Sprintf("uid: %d, server: %d, oldDay: %d, now: %d \r", uid, server, day, uDay)
f, _ := os.OpenFile("main.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
_, err = f.Write([]byte(data))
if err1 := f.Close(); err1 != nil && err == nil {
err = err1
}
//g.Log().Info(ctx, "err== ", err)
return
}

37
internal/serviceGame/internal/rank.go

@ -4,7 +4,6 @@ import (
"context"
"errors"
"fmt"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"go.mongodb.org/mongo-driver/bson"
@ -49,7 +48,7 @@ func UpdateRankAward(ctx context.Context, data map[string]interface{}) (err erro
delete(data, "StringId")
delete(data, "_id")
//filter["Type"] = data["Type"]
log.Print("UpdateAward", filter, data)
//log.Print("UpdateAward", filter, data)
err = MongoDatabaseList["0"].Collection("RankAward").UpdateOne(ctx, filter, bson.M{"$set": data})
log.Print("RankAward", filter, data, err)
@ -59,9 +58,9 @@ func UpdateRankAward(ctx context.Context, data map[string]interface{}) (err erro
func InsertRankAward(ctx context.Context, data map[string]interface{}) (err error) {
data["_id"] = gtime.TimestampNano()
data["_t"] = "RankAward"
log.Print("InsertAward", data)
//log.Print("InsertAward", data)
ss, err := MongoDatabaseList["0"].Collection("RankAward").InsertOne(ctx, data)
log.Print("InsertAward %v", ss)
log.Printf("InsertAward %v", ss)
return
}
@ -82,15 +81,15 @@ func GetRank(ctx context.Context, req *game.GetRankReq) (res *game.GetRankRes, e
//stopTimeObj, _ := time.ParseInLocation(dateFormat, setStop, loc)
filter["BeginTime"] = bson.M{"$gte": setStart, "$lt": setStop}
fmt.Println("GetRank ", setStart, setStop, filter)
//fmt.Println("GetRank ", setStart, setStop, filter)
}
fmt.Println("GetRank ", filter)
//fmt.Println("GetRank ", filter)
res = new(game.GetRankRes)
err = MongoDatabaseList["0"].Collection("Rank").Find(ctx, filter).Sort("BeginTime").All(&res.Rank)
for _, v := range res.Rank {
v["StringId"] = fmt.Sprint(v["_id"])
}
fmt.Println("GetRank ", res)
//fmt.Println("GetRank ", res)
return
}
@ -125,7 +124,7 @@ func UpdateRank(ctx context.Context, data map[string]interface{}) (err error) {
//filter["Type"] = data["Type"]
delete(data, "StringId")
delete(data, "_id")
log.Print("UpdateRank", filter, data)
//log.Print("UpdateRank", filter, data)
err = MongoDatabaseList["0"].Collection("Rank").UpdateOne(ctx, filter, bson.M{"$set": data})
log.Print("UpdateRank", filter, data, err)
@ -142,22 +141,22 @@ func InsertRank(ctx context.Context, data map[string]interface{}) (err error) {
} else {
data["_t"] = "RankDaily"
}
log.Print("InsertRank", data["Type"] == consts.AWARD_STAGE, data)
//log.Print("InsertRank", data["Type"] == consts.AWARD_STAGE, data)
delete(data, "StringId")
ss, err := MongoDatabaseList["0"].Collection("Rank").InsertOne(ctx, data)
log.Print("InsertRank %v", ss)
log.Printf("InsertRank %v", ss)
return
}
func DelRank(ctx context.Context, id string) (err error) {
log.Print("DelRank", id)
//log.Print("DelRank", id)
idInt, _ := strconv.ParseInt(id, 10, 64)
err = MongoDatabaseList["0"].Collection("Rank").RemoveId(ctx, idInt)
return
}
func CheckRank(ctx context.Context, data map[string]interface{}) (total int64, res string, err error) {
log.Print("DelRank", data)
//log.Print("DelRank", data)
filter := bson.M{"$and": bson.A{bson.M{"$or": bson.A{
bson.M{"$and": bson.A{
bson.M{"BeginTime": bson.M{"$lte": fmt.Sprint(data["BeginTime"])}},
@ -170,11 +169,11 @@ func CheckRank(ctx context.Context, data map[string]interface{}) (total int64, r
bson.M{"BeginTime": bson.M{"$lt": fmt.Sprint(data["EndTime"])}}}}}},
bson.M{"_t": "RankStage"}}}
log.Print("CheckPropExchange filter %v", filter)
//log.Print("CheckPropExchange filter %v", filter)
all := make([]map[string]interface{}, 1)
total, err = MongoDatabaseList["0"].Collection("Rank").Find(ctx, filter).Count()
err = MongoDatabaseList["0"].Collection("Rank").Find(ctx, filter).All(&all)
log.Print("CheckPropExchange filter %v", res)
//log.Print("CheckPropExchange filter %v", res)
for _, v := range all {
res = fmt.Sprint(v["_id"])
}
@ -182,11 +181,11 @@ func CheckRank(ctx context.Context, data map[string]interface{}) (total int64, r
}
func AddRankGroup(ctx context.Context, req *game.AddRankGroupReq) (res *game.AddRankGroupRes, err error) {
log.Print("AddRankGroup", req)
//log.Print("AddRankGroup", req)
filter := bson.M{"Name": req.Name, "StageGroupId": req.StageGroupId}
res = new(game.AddRankGroupRes)
log.Print("AddRankGroup filter %v", filter)
//log.Printf("AddRankGroup filter %v", filter)
err = MongoDatabaseList["0"].Collection("RankGroupName").Find(ctx, filter).All(&res)
err = MongoDatabaseList["0"].Collection("RankGroupName").UpdateOne(ctx, filter, bson.M{"$set": filter})
@ -194,10 +193,10 @@ func AddRankGroup(ctx context.Context, req *game.AddRankGroupReq) (res *game.Add
}
func GetRankGroup(ctx context.Context, req *game.AddRankGroupReq) (res *game.AddRankGroupRes, err error) {
log.Print("AddRankGroup", req)
//log.Print("AddRankGroup", req)
filter := bson.M{"Name": req.Name, "StageGroupId": req.StageGroupId}
log.Print("AddRankGroup filter %v", filter)
//log.Printf("AddRankGroup filter %v", filter)
err = MongoDatabaseList["0"].Collection("RankGroupName").UpdateOne(ctx, filter, bson.M{"$set": filter})
res = new(game.AddRankGroupRes)
@ -205,7 +204,7 @@ func GetRankGroup(ctx context.Context, req *game.AddRankGroupReq) (res *game.Add
}
func GetGameRank(ctx context.Context, req *game.GetGameRankReq) (res *game.GetGameRankRes, err error) {
log.Printf("GetGameRank: %s", gjson.MustEncodeString(req))
//log.Printf("GetGameRank: %s", gjson.MustEncodeString(req))
res = new(game.GetGameRankRes)
mongo, ok := MongoDatabaseList[fmt.Sprint(req.ServerId)]
if !ok {

155
internal/serviceGame/internal/server_battle_pass.go

@ -0,0 +1,155 @@
package internal
import (
"context"
"errors"
"fmt"
"github.com/gogf/gf/v2/encoding/gcharset"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"go.mongodb.org/mongo-driver/bson"
"log"
"strconv"
"time"
"tyj_admin/api/v1/game"
"tyj_admin/internal/consts"
"tyj_admin/internal/dao"
"tyj_admin/internal/model/do"
"tyj_admin/utils"
)
func GetBattlePass(ctx context.Context, req *game.GetBattlePassReq) (res *game.GetBattlePassRes, err error) {
res = new(game.GetBattlePassRes)
filter := bson.M{}
if req.ServerId != 0 {
filter["Server"] = req.ServerId
}
if req.PeriodId != 0 {
filter["PeriodId"] = req.PeriodId
}
err = MongoDatabaseList["0"].Collection(consts.PeachAdmin_Db_Battle_pass).Find(ctx, filter).All(&res.List)
if err != nil {
return
}
for _, v := range res.List {
v["StringId"] = fmt.Sprint(v["_id"])
}
return res, err
}
func CheckPeriodId(ctx context.Context, req *game.CheckPeriodIdReq) (res *game.CheckPeriodIdRes, err error) {
res = new(game.CheckPeriodIdRes)
filter := bson.M{"$or": bson.A{bson.M{"PeriodId": req.PeriodId}, bson.M{"PeriodId": bson.M{"$gt": req.PeriodId}, "BeginTime": bson.M{"$lte": time.Now().Unix()}}}}
log.Printf("CheckPeriodId filter %v", gjson.MustEncodeString(filter))
err = MongoDatabaseList["0"].Collection(consts.PeachAdmin_Db_Battle_pass).Find(ctx, filter).All(&res.List)
return
}
func UpdateBattlePass(ctx context.Context, req *game.UpdateBattlePassReq) (err error) {
data := bson.M{}
id, _ := strconv.ParseInt(req.Id, 10, 64)
filter := bson.M{"_id": id}
if req.BeginTime != "" {
data["BeginTime"], _ = strconv.ParseInt(req.BeginTime, 10, 64)
}
if req.EndTime != "" {
data["EndTime"], _ = strconv.ParseInt(req.EndTime, 10, 64)
}
if req.State != 0 {
data["State"] = req.State
}
err = MongoDatabaseList["0"].Collection(consts.PeachAdmin_Db_Battle_pass).UpdateOne(ctx, filter, bson.M{"$set": data})
if req.State != 0 {
go SendMsgToC(ctx, id, req.State)
}
return
}
func SendMsgToC(ctx context.Context, id int64, state int32) (res *game.MailSendRes, err error) {
res = new(game.MailSendRes)
filter := bson.M{"_id": id}
var list []map[string]interface{}
err = MongoDatabaseList["0"].Collection(consts.PeachAdmin_Db_Battle_pass).Find(ctx, filter).All(&list)
if len(list) == 0 {
g.Log().Info(ctx, "BattlePass SendMsgToC - req: ", gjson.MustEncodeString(list))
return
}
ip := ServerConfig[fmt.Sprint(list[0]["Server"])]
reqData := map[string]interface{}{"periodId": list[0]["PeriodId"], "state": state}
url := "http://" + ip + "/BattlePass?periodId=" + fmt.Sprint(list[0]["PeriodId"]) + "&state=" + fmt.Sprint(state)
srcCharset := "UTF-8"
g.Client().SetHeader("Content-Type", "application/json;charset=UTF-8")
g.Log().Info(ctx, "BattlePass SendMsgToC - req: ", url, gjson.MustEncodeString(reqData))
bytes := g.Client().GetBytes(ctx, url)
src := string(bytes)
if g.IsEmpty(src) {
return
}
tmp, _ := gcharset.ToUTF8(srcCharset, src)
json, err1 := gjson.DecodeToJson(tmp)
if err1 != nil {
return
}
if json.Get("Error").Int() != 200 {
return
}
g.Log().Info(ctx, "BattlePass - success ", gjson.MustEncodeString(reqData))
return
}
func InsertBattlePass(ctx context.Context, req *game.InsertBattlePassReq) (err error) {
var list []map[string]interface{}
filter1 := bson.M{"Server": req.Server, "PeriodId": bson.M{"$gt": req.PeriodId}, "BeginTime": bson.M{"$lte": time.Now().Unix()}}
filter := bson.M{"$or": bson.A{bson.M{"Server": req.Server, "periodId": req.PeriodId}, filter1}}
err = MongoDatabaseList["0"].Collection(consts.PeachAdmin_Db_Battle_pass).Find(ctx, filter).All(&list)
if len(list) > 0 {
return errors.New("重复期数或永久关闭")
}
data := bson.M{}
data["_id"], _ = strconv.ParseInt(fmt.Sprintf("%d%d", gtime.TimestampMilli(), utils.RandInt(100, 999)), 10, 64)
data["State"] = req.State
data["Server"] = req.Server
data["BeginTime"], _ = strconv.ParseInt(req.BeginTime, 10, 64)
data["EndTime"], _ = strconv.ParseInt(req.EndTime, 10, 64)
data["PeriodId"] = req.PeriodId
ss, err := MongoDatabaseList["0"].Collection(consts.PeachAdmin_Db_Battle_pass).InsertOne(ctx, data)
log.Printf("InsertBattlePass %v, data: %s", ss, gjson.MustEncodeString(data))
return
}
func CheckBattlePass(ctx context.Context, req *game.CheckBattlePassReq) (total int64, err error) {
log.Print("CheckBattlePass", gjson.MustEncodeString(req))
filter1 := bson.M{"$and": bson.A{bson.M{"PeriodId": req.PeriodId}, bson.M{"Server": req.Server}}}
log.Printf("CheckBattlePass filter %v", gjson.MustEncodeString(filter1))
total, err = MongoDatabaseList["0"].Collection(consts.PeachAdmin_Db_Battle_pass).Find(ctx, filter1).Count()
if total > 0 {
err = errors.New(fmt.Sprint(req.Server) + "区期数重复配置")
return
}
//beginTime, _ := strconv.ParseInt(req.BeginTime, 10, 64)
//log.Print("CheckBattlePass", gjson.MustEncodeString(req))
//filter := bson.M{"$and": bson.A{bson.M{"BeginTime": bson.M{"$gte": beginTime}}, bson.M{"Server": req.Server}}}
//log.Printf("CheckBattlePass filter %v", gjson.MustEncodeString(filter))
//total, err = MongoDatabaseList["0"].Collection(consts.PeachAdmin_Db_Battle_pass).Find(ctx, filter).Count()
return total, err
}
func BattlePassLog(ctx context.Context, req *game.InsertBattlePassLogReq) (res *game.InsertBattlePassLogRes, err error) {
res = new(game.InsertBattlePassLogRes)
ss, err := dao.ServerBattlePass.Ctx(ctx).Insert(do.ServerBattlePass{Server: req.Server, Uid: req.Uid, PeriodId: req.PeriodId})
log.Printf("InsertBattlePass %v", ss)
return
}
func GetBattlePassLog(ctx context.Context, req *game.GetBattlePassLogReq) (res *game.GetBattlePassLogRes, err error) {
res = new(game.GetBattlePassLogRes)
err = dao.ServerBattlePass.Ctx(ctx).Where("period_id=?", req.PeriodId).Fields("count(DISTINCT uid) uid", "server").Group("server").Scan(&res.List)
res.Total, err = dao.ServerBattlePass.Ctx(ctx).Fields("DISTINCT uid").Where("period_id=?", req.PeriodId).Count()
res.RechargeTotal, err = dao.GameRecharge.Ctx(ctx).Fields("DISTINCT unitId").Where("status=?", 2).Count()
return
}

6
internal/serviceGame/manage.go

@ -34,6 +34,7 @@ type IGameManage interface {
GetShopItemLog(ctx context.Context, req *game.GetShopItemLogReq) (res *game.GetShopItemLogRes, err error)
GetShopItemList(ctx context.Context, req *game.GetShopItemListReq) (res *game.GetShopItemListRes, err error)
GetOperLog(ctx context.Context, req *game.GetOperLogReq) (res *game.GetOperLogRes, err error)
LogAccount(ctx context.Context, req *game.LogAccountReq) (res *game.LogAccountRes, err error)
}
type gameManageImpl struct {
@ -363,3 +364,8 @@ func (ga *gameManageImpl) GetOperLog(ctx context.Context, req *game.GetOperLogRe
res, err = internal.GetOperLog(ctx, req)
return
}
func (ga *gameManageImpl) LogAccount(ctx context.Context, req *game.LogAccountReq) (res *game.LogAccountRes, err error) {
res, err = internal.LogAccount(ctx, req)
return
}

24
internal/serviceGame/order.go

@ -43,6 +43,7 @@ type IGameOrder interface {
AddRechargeSign(ctx context.Context, req *game.AddRechargeSignReq) (res *game.AddRechargeSignRes, err error)
ResetRechargeSign(ctx context.Context, req *game.ResetRechargeSignReq) (res *game.ResetRechargeSignRes, err error)
GetTransactionId(ctx context.Context, req *game.GetTransactionIdReq) (res *game.GetTransactionIdRes, err error)
GetHuaWeiOrderList(ctx context.Context, req *game.GetHuaWeiOrderListReq) (res *game.GetHuaWeiOrderListRes, err error)
}
type gameOrderImpl struct {
@ -223,15 +224,13 @@ func (o gameOrderImpl) GetOrders(ctx context.Context, req *game.OrderSearchReq)
return nil, err
}
orderModel = orderModel.Where(`unitId in (?) `, uid)
}
if req.Id != "" {
} else if req.Id != "" {
uid, err := strconv.ParseInt(req.Id, 10, 64)
if err != nil {
return nil, err
}
orderModel = orderModel.Where(`unitId=? `, uid)
}
if req.Uid != 0 {
} else if req.Uid != 0 {
uid, err := internal.GetIdToUid(ctx, int64(req.Uid))
if err != nil {
return nil, err
@ -401,7 +400,7 @@ func (o gameOrderImpl) GetOrderBehavior(ctx context.Context, req *game.OrderBeha
if req.StartTime == "" {
return nil, errors.New("填写注册时间!")
}
g.Try(ctx, func(ctx context.Context) {
err = g.Try(ctx, func(ctx context.Context) {
modelTotal := dao.GameRegister.Ctx(ctx)
modelTotal = modelTotal.Where(`STR_TO_DATE(create_time, "%Y-%m-%d")=?`, req.StartTime)
modelTotal.Fields("max(channel) as channel, count(1) as totalAccount").Group("channel").Scan(&res.Account)
@ -429,7 +428,7 @@ func (o gameOrderImpl) GetRechargePer(ctx context.Context, req *game.RechargePer
if req.StartTime == "" || req.EndTime == "" {
return nil, errors.New("填写注册时间!")
}
g.Try(ctx, func(ctx context.Context) {
err = g.Try(ctx, func(ctx context.Context) {
modelTotal := dao.GameRegister.Ctx(ctx)
modelTotal = modelTotal.Where(`tradeNo NOT LIKE 'GM%'`).Where(`STR_TO_DATE(create_time, "%Y-%m-%d")>=?`, req.StartTime).Where(`STR_TO_DATE(create_time, "%Y-%m-%d")<=?`, req.EndTime)
modelTotal.Fields("max(channel) as channel, count(1) as totalAccount, STR_TO_DATE(create_time, \"%Y-%m-%d\") as createTime").Group("channel,STR_TO_DATE(create_time, \"%Y-%m-%d\")").Scan(&res.Account)
@ -635,3 +634,16 @@ func (o gameOrderImpl) GetTransactionId(ctx context.Context, req *game.GetTransa
res.Order = order
return
}
func (o gameOrderImpl) GetHuaWeiOrderList(ctx context.Context, req *game.GetHuaWeiOrderListReq) (res *game.GetHuaWeiOrderListRes, err error) {
res = new(game.GetHuaWeiOrderListRes)
startAt, _ := strconv.ParseInt(req.StartAt, 10, 64)
endAt, _ := strconv.ParseInt(req.EndAt, 10, 64)
order, err := service.GetHuaWeiOrderList(req.ContinuationToken, startAt, endAt)
if err != nil {
log.Printf("查询失败: %v", err)
return
}
res.Order = *order
return
}

2
internal/serviceGame/pub.go

@ -151,6 +151,8 @@ func (c *gamePubImpl) GetServerConfig(ctx context.Context, req *game.GetServerCo
res.RechargeWhiteListIps = general[0].RechargeWhiteListIps
res.GmWhiteListUrl = general[0].GmWhiteListUrl
res.BackstageRechargeUrl = general[0].BackstageRechargeUrl
res.ActivityDbUrl = general[0].ActivityDbUrl
res.ActivityDbName = general[0].ActivityDbName
})
log.Println(err1)

68
internal/serviceGame/server_battle_pass.go

@ -0,0 +1,68 @@
package serviceGame
import (
"context"
"log"
"tyj_admin/api/v1/game"
"tyj_admin/internal/serviceGame/internal"
)
type IGameBattlePass interface {
Get(ctx context.Context, req *game.GetBattlePassReq) (res *game.GetBattlePassRes, err error)
CheckPeriodId(ctx context.Context, req *game.CheckPeriodIdReq) (res *game.CheckPeriodIdRes, err error)
Update(ctx context.Context, req *game.UpdateBattlePassReq) (res *game.UpdateBattlePassRes, err error)
Insert(ctx context.Context, req *game.InsertBattlePassReq) (res *game.InsertBattlePassRes, err error)
Check(ctx context.Context, req *game.CheckBattlePassReq) (res *game.CheckBattlePassRes, err error)
BattlePassLog(ctx context.Context, req *game.InsertBattlePassLogReq) (res *game.InsertBattlePassLogRes, err error)
GetBattlePassLog(ctx context.Context, req *game.GetBattlePassLogReq) (res *game.GetBattlePassLogRes, err error)
}
type gameBattlePassImpl struct {
}
var gameBattlePassService = gameBattlePassImpl{}
func GameBattlePass() IGameBattlePass {
return &gameBattlePassService
}
func (g *gameBattlePassImpl) Get(ctx context.Context, req *game.GetBattlePassReq) (res *game.GetBattlePassRes, err error) {
res, err = internal.GetBattlePass(ctx, req)
return
}
func (g *gameBattlePassImpl) CheckPeriodId(ctx context.Context, req *game.CheckPeriodIdReq) (res *game.CheckPeriodIdRes, err error) {
res, err = internal.CheckPeriodId(ctx, req)
return
}
func (g *gameBattlePassImpl) Update(ctx context.Context, req *game.UpdateBattlePassReq) (res *game.UpdateBattlePassRes, err error) {
err = internal.UpdateBattlePass(ctx, req)
log.Print("UpdateBattlePass: ", err)
return
}
func (g *gameBattlePassImpl) Insert(ctx context.Context, req *game.InsertBattlePassReq) (res *game.InsertBattlePassRes, err error) {
err = internal.InsertBattlePass(ctx, req)
log.Print("InsertBattlePass: ", err)
return
}
func (g *gameBattlePassImpl) Check(ctx context.Context, req *game.CheckBattlePassReq) (res *game.CheckBattlePassRes, err error) {
res = new(game.CheckBattlePassRes)
res.Total, err = internal.CheckBattlePass(ctx, req)
log.Print("CheckBattlePass: ", err)
return
}
func (g *gameBattlePassImpl) BattlePassLog(ctx context.Context, req *game.InsertBattlePassLogReq) (res *game.InsertBattlePassLogRes, err error) {
res, err = internal.BattlePassLog(ctx, req)
log.Print("InsertBattlePass: ", err)
return
}
func (g *gameBattlePassImpl) GetBattlePassLog(ctx context.Context, req *game.GetBattlePassLogReq) (res *game.GetBattlePassLogRes, err error) {
res, err = internal.GetBattlePassLog(ctx, req)
log.Print("GetBattlePassLog: ", err)
return
}

14
manifest/config/RootG2Ca.cer

@ -0,0 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICGjCCAaGgAwIBAgIIShhpn519jNAwCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC
Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE
AwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDMxNjAzMDQzOVoXDTQ5MDMx
NjAzMDQzOVowUzELMAkGA1UEBhMCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE
CwwKSHVhd2VpIENCRzEeMBwGA1UEAwwVSHVhd2VpIENCRyBSb290IENBIEcyMHYw
EAYHKoZIzj0CAQYFK4EEACIDYgAEWidkGnDSOw3/HE2y2GHl+fpWBIa5S+IlnNrs
GUvwC1I2QWvtqCHWmwFlFK95zKXiM8s9yV3VVXh7ivN8ZJO3SC5N1TCrvB2lpHMB
wcz4DA0kgHCMm/wDec6kOHx1xvCRo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
AQH/BAUwAwEB/zAdBgNVHQ4EFgQUo45a9Vq8cYwqaiVyfkiS4pLcIAAwCgYIKoZI
zj0EAwMDZwAwZAIwMypeB7P0IbY7c6gpWcClhRznOJFj8uavrNu2PIoz9KIqr3jn
BlBHJs0myI7ntYpEAjBbm8eDMZY5zq5iMZUC6H7UzYSix4Uy1YlsLVV738PtKP9h
FTjgDHctXJlC5L7+ZDY=
-----END CERTIFICATE-----
Loading…
Cancel
Save