Compare commits

...

6 Commits

Author SHA1 Message Date
ayflying
9f337df9de 计划任务延时启动 2025-02-28 15:12:20 +08:00
ayflying
45ffdc37fb 增加ip获取 2025-02-28 14:53:05 +08:00
ayflying
6765eff93f 增加埋点服务 2025-02-28 14:32:12 +08:00
ayflying
fab208c121 系统日志服务写入 2025-02-28 14:21:48 +08:00
ayflying
e45e8c7572 还原到标准service 2025-02-28 12:17:17 +08:00
ayflying
e9540d0971 活动模块,计划任务模块 加入第三方 2025-02-28 12:12:03 +08:00
116 changed files with 5037 additions and 74 deletions

View File

@@ -1,29 +0,0 @@
package act
import (
"github.com/gogf/gf/v2/os/gtime"
)
type act struct {
}
type Sql struct {
UID uint64 `gorm:"primaryKey;comment:玩家编号"`
ActID int `gorm:"primaryKey;comment:活动编号"`
Action string `gorm:"type:text;comment:活动配置"`
UpdatedAt *gtime.Time `gorm:"index;comment:更新时间"`
}
func New() *act {
return &act{}
}
func (s *act) CreateTable(name string) {
//prefix := g.DB().GetPrefix()
//
//g.DB()
//g.DB().Exec(gctx.New())
}

View File

@@ -1,13 +0,0 @@
create table shiningu_game_act
(
uid bigint not null comment '玩家编号',
act_id int not null comment '活动编号',
action text null comment '活动配置',
updated_at datetime null comment '更新时间',
primary key (uid, act_id)
)
comment '玩家活动数据' charset = utf8mb4;
create index shiningu_game_act_uid_index
on shiningu_game_act (uid);

View File

@@ -1,19 +0,0 @@
package act
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
)
// 查询表格时候存在
func (s *act) TableExists(name string) bool {
Prefix := g.DB().GetPrefix()
get, err := g.DB().TableFields(gctx.New(), Prefix+name)
if err != nil {
g.Log().Error(gctx.New(), err)
}
if get != nil {
return true
}
return false
}

12
api/admin/v1/log.go Normal file
View File

@@ -0,0 +1,12 @@
package v1
import (
"github.com/ayflying/utility_go/internal/model/entity"
"github.com/gogf/gf/v2/frame/g"
)
type SystemLog struct {
entity.SystemLog
Data g.Map `json:"data" dc:"操作数据"`
//Post g.Map `json:"post" dc:"提交数据"`
}

15
api/callback/callback.go Normal file
View File

@@ -0,0 +1,15 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package callback
import (
"context"
"github.com/ayflying/utility_go/api/callback/v1"
)
type ICallbackV1 interface {
Ip(ctx context.Context, req *v1.IpReq) (res *v1.IpRes, err error)
}

20
api/callback/v1/ip.go Normal file
View File

@@ -0,0 +1,20 @@
package v1
import "github.com/gogf/gf/v2/frame/g"
type IpReq struct {
g.Meta `path:"/callback/ip/{ip}" tags:"回调响应" method:"get" summary:"获取ip"`
Ip string `json:"ip" dc:"ip"`
}
type IpRes struct {
g.Meta `mime:"application/json" example:"string"`
Address []string `json:"address" dc:"地区名"`
}
type Ip struct {
Country string `json:"country" dc:"国家"` //国家
Region string `json:"region" dc:"地区"` //地区
Province string `json:"province" dc:"省份"` //省份
City string `json:"city" dc:"城市"` //城市
District string `json:"district" dc:"区县"` //区县
}

180
api/system/v1/cron.pb.go Normal file
View File

@@ -0,0 +1,180 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc v3.20.0
// source: system/v1/cron.proto
package v1
import (
reflect "reflect"
sync "sync"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 定义 CronType 计划任务 枚举
type CronType int32
const (
CronType_UNKNOWN CronType = 0 // 未知类型
CronType_SECOND CronType = 1 // 每秒触发一次
CronType_MINUTE CronType = 2 // 每分钟触发一次
CronType_HOUR CronType = 3 // 每小时触发一次
CronType_DAILY CronType = 4 // 每天触发一次
CronType_WEEK CronType = 5 // 每周触发一次
CronType_MONTH CronType = 6 // 每月触发一次
CronType_YEAR CronType = 7 // 每年触发一次
CronType_MONDAY CronType = 8 // 每周一触发一次
CronType_TUESDAY CronType = 9 // 每周二触发一次
CronType_WEDNESDAY CronType = 10 // 每周三触发一次
CronType_THURSDAY CronType = 11 // 每周四触发一次
CronType_FRIDAY CronType = 12 // 每周五触发一次
CronType_SATURDAY CronType = 13 // 每周六触发一次
CronType_SUNDAY CronType = 14 // 每周日触发一次
)
// Enum value maps for CronType.
var (
CronType_name = map[int32]string{
0: "UNKNOWN",
1: "SECOND",
2: "MINUTE",
3: "HOUR",
4: "DAILY",
5: "WEEK",
6: "MONTH",
7: "YEAR",
8: "MONDAY",
9: "TUESDAY",
10: "WEDNESDAY",
11: "THURSDAY",
12: "FRIDAY",
13: "SATURDAY",
14: "SUNDAY",
}
CronType_value = map[string]int32{
"UNKNOWN": 0,
"SECOND": 1,
"MINUTE": 2,
"HOUR": 3,
"DAILY": 4,
"WEEK": 5,
"MONTH": 6,
"YEAR": 7,
"MONDAY": 8,
"TUESDAY": 9,
"WEDNESDAY": 10,
"THURSDAY": 11,
"FRIDAY": 12,
"SATURDAY": 13,
"SUNDAY": 14,
}
)
func (x CronType) Enum() *CronType {
p := new(CronType)
*p = x
return p
}
func (x CronType) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (CronType) Descriptor() protoreflect.EnumDescriptor {
return file_system_v1_cron_proto_enumTypes[0].Descriptor()
}
func (CronType) Type() protoreflect.EnumType {
return &file_system_v1_cron_proto_enumTypes[0]
}
func (x CronType) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use CronType.Descriptor instead.
func (CronType) EnumDescriptor() ([]byte, []int) {
return file_system_v1_cron_proto_rawDescGZIP(), []int{0}
}
var File_system_v1_cron_proto protoreflect.FileDescriptor
var file_system_v1_cron_proto_rawDesc = []byte{
0x0a, 0x14, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x72, 0x6f, 0x6e,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2a, 0xbf,
0x01, 0x0a, 0x08, 0x43, 0x72, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55,
0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x45, 0x43, 0x4f,
0x4e, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x49, 0x4e, 0x55, 0x54, 0x45, 0x10, 0x02,
0x12, 0x08, 0x0a, 0x04, 0x48, 0x4f, 0x55, 0x52, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x41,
0x49, 0x4c, 0x59, 0x10, 0x04, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x45, 0x45, 0x4b, 0x10, 0x05, 0x12,
0x09, 0x0a, 0x05, 0x4d, 0x4f, 0x4e, 0x54, 0x48, 0x10, 0x06, 0x12, 0x08, 0x0a, 0x04, 0x59, 0x45,
0x41, 0x52, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x4f, 0x4e, 0x44, 0x41, 0x59, 0x10, 0x08,
0x12, 0x0b, 0x0a, 0x07, 0x54, 0x55, 0x45, 0x53, 0x44, 0x41, 0x59, 0x10, 0x09, 0x12, 0x0d, 0x0a,
0x09, 0x57, 0x45, 0x44, 0x4e, 0x45, 0x53, 0x44, 0x41, 0x59, 0x10, 0x0a, 0x12, 0x0c, 0x0a, 0x08,
0x54, 0x48, 0x55, 0x52, 0x53, 0x44, 0x41, 0x59, 0x10, 0x0b, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x52,
0x49, 0x44, 0x41, 0x59, 0x10, 0x0c, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x41, 0x54, 0x55, 0x52, 0x44,
0x41, 0x59, 0x10, 0x0d, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x55, 0x4e, 0x44, 0x41, 0x59, 0x10, 0x0e,
0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61,
0x79, 0x66, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x2f, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x5f,
0x67, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x76, 0x31,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_system_v1_cron_proto_rawDescOnce sync.Once
file_system_v1_cron_proto_rawDescData = file_system_v1_cron_proto_rawDesc
)
func file_system_v1_cron_proto_rawDescGZIP() []byte {
file_system_v1_cron_proto_rawDescOnce.Do(func() {
file_system_v1_cron_proto_rawDescData = protoimpl.X.CompressGZIP(file_system_v1_cron_proto_rawDescData)
})
return file_system_v1_cron_proto_rawDescData
}
var file_system_v1_cron_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_system_v1_cron_proto_goTypes = []interface{}{
(CronType)(0), // 0: system.CronType
}
var file_system_v1_cron_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_system_v1_cron_proto_init() }
func file_system_v1_cron_proto_init() {
if File_system_v1_cron_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_system_v1_cron_proto_rawDesc,
NumEnums: 1,
NumMessages: 0,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_system_v1_cron_proto_goTypes,
DependencyIndexes: file_system_v1_cron_proto_depIdxs,
EnumInfos: file_system_v1_cron_proto_enumTypes,
}.Build()
File_system_v1_cron_proto = out.File
file_system_v1_cron_proto_rawDesc = nil
file_system_v1_cron_proto_goTypes = nil
file_system_v1_cron_proto_depIdxs = nil
}

261
cmd/middleware.go Normal file
View File

@@ -0,0 +1,261 @@
package cmd
import (
"github.com/ayflying/utility_go/service"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/text/gstr"
)
//func MiddlewareAnonymous(r *ghttp.Request) {
// // 中间件处理逻辑
// r.Response.CORSDefault()
//
// ip := r.GetClientIp()
// r.SetCtxVar("ip", ip)
//
// //各种回调的日志返回
// //get, _ := r.GetJson()
// get := r.GetRequestMapStrStr()
// delete(get, "r")
// delete(get, "s")
// delete(get, "t")
// delete(get, "data")
// getJson, _ := gjson.EncodeString(get)
// g.Log("cmd").Debugf(r.GetCtx(), "from|%v|%v|%v", 0, r.RequestURI, getJson)
//
// r.Middleware.Next()
//
// //中间件后置
// err := r.GetError()
// if err != nil {
// code, err2 := strconv.Atoi(err.Error())
// if err2 != nil {
// return
// }
// if _, ok := consts.ErrCodeList[code]; ok {
// //g.Dump("===error:", gerror.Code(r.GetError()).Code())
// msg := g.Map{
// "code": code,
// "message": consts.ErrCodeList[code],
// //"data": r.GetHandlerResponse(),
// }
// r.Response.WriteJson(msg)
// //错误码置空
// r.SetError(nil)
// //g.Log("cmd").Debugf(r.GetCtx(), "to|%v|%v|%v", uid, r.RequestURI, msg)
// return
// }
// }
//
// //回复
// res, _ := gjson.EncodeString(r.GetHandlerResponse())
// g.Log("cmd").Debugf(r.GetCtx(), "to|%v|%v|%v", 0, r.RequestURI, res)
//}
func MiddlewareAdmin(r *ghttp.Request) {
// 中间件处理逻辑
r.Response.CORSDefault()
ip := r.GetClientIp()
r.SetCtxVar("ip", ip)
get := r.Cookie.Get("uid")
if get == nil {
//调试模式允许不验证用户名
debug, _ := g.Cfg().GetWithEnv(nil, "debug")
if !debug.Bool() {
msg := g.Map{
"code": 403,
"message": "登录失败",
//"data": r.GetHandlerResponse(),
}
//r.SetError(http.Error(r,"403",http.StatusForbidden))
r.Response.WriteJson(msg)
gerror.NewCode(gcode.CodeNil, "登录失败")
return
}
}
uid := get.Int()
r.Middleware.Next()
//后置所有post都写入日志
if r.Method == "POST" {
//黑名单列表
LogUrl := []string{
"/system/chatgpt",
}
if !gstr.InArray(LogUrl, r.RequestURI) {
//写入日志
service.SystemLog().AddLog(uid, r.RequestURI, ip, r.GetFormMap())
}
} else {
//需要写入的get
LogUrl := []string{
"/admin/config/mall/del",
"/admin/config/shop/del",
"/admin/group/del",
"/admin/user/del",
"/admin/community/posts/del",
"/admin/community/posts/limit",
"/admin/community/posts/limit/del",
"/admin/community/reply/del",
"/admin/community/recommend",
}
for _, item := range LogUrl {
if item == r.RequestURI {
service.SystemLog().AddLog(uid, r.RequestURI, ip, r.GetFormMap())
}
}
}
}
//// 中间件
//func Middleware(r *ghttp.Request) {
// // 中间件处理逻辑
// r.Response.CORSDefault()
//
// //获取玩家的guid
// guid := r.Header.Get("guid")
//
// //获取所有请求的信息
// get := r.GetRequestMapStrStr()
//
// //cacheKey := fmt.Sprintf("sign:%s", guid)
//
// ////进入debug模式
// //debugBool := g.Cfg().MustGetWithCmd(nil, "debug")
// ////如果收到签名,开始验证签名
// //if sign, _ := get["s"]; !debugBool.Bool() && sign != "" {
// //
// // //如果连续两次使用相同sign直接抛出
// // getSign, _ := aycache.New().Get(nil, cacheKey)
// // if getSign.String() == sign {
// // //中间件授权错误
// // msg := g.Map{
// // "code": 11000,
// // "message": consts.ErrCodeList[11000],
// // }
// // r.Response.WriteJson(msg)
// // return
// // }
// // aycache.New().Set(nil, cacheKey, sign, time.Minute*10)
// //
// // secretKey := "asdkjqwhiasdoplmwofjk/aws"
// // nonce := get["r"]
// // timestamp := get["t"]
// //
// // message := timestamp + nonce
// //
// // timeUnix := time.Now().Unix() - gconv.Int64(timestamp)
// // if timeUnix > 600 || timeUnix < -600 {
// // //中间件授权错误
// // msg := g.Map{
// // "code": 11000,
// // "message": consts.ErrCodeList[11000],
// // }
// // r.Response.WriteJson(msg)
// // return
// // }
// //
// // // 创建 HMAC 对象
// // h := hmac.New(sha256.New, []byte(secretKey))
// //
// // // 更新 HMAC 对象的数据
// // h.Write([]byte(message))
// //
// // // 获取 HMAC 的十六进制表示
// // signature := hex.EncodeToString(h.Sum(nil))
// //
// // //如果加密算法不一致
// // if signature != sign {
// // //中间件授权错误
// // msg := g.Map{
// // "code": 11000,
// // "message": consts.ErrCodeList[11000],
// // }
// // r.Response.WriteJson(msg)
// // return
// // }
// //}
//
// uid, _ := service.MemberUser().Guid2uid(guid)
// if uid == 0 {
// //中间件授权错误
// msg := g.Map{
// "code": 11000,
// "message": consts.ErrCodeList[11000],
// //"data": r.GetHandlerResponse(),
// }
// r.Response.WriteJson(msg)
//
// return
// }
// r.SetCtxVar("guid", guid)
// r.SetCtxVar("uid", uid)
//
// ip := r.GetClientIp()
// r.SetCtxVar("ip", ip)
//
// delete(get, "r")
// delete(get, "s")
// delete(get, "t")
// delete(get, "data")
// //前置输出服务器收到信息
// getJson, _ := gjson.EncodeString(get)
// //后置输出服务器返回信息
// if r.GetCtxVar("not_log").IsEmpty() {
// g.Log("cmd").Debugf(r.GetCtx(), "from|%v|%v|%v", uid, r.RequestURI, getJson)
// }
//
// //运行开始时间
// RunStartTime := gtime.Now()
//
// //proto.Marshal()
//
// //中间件核心
// r.Middleware.Next()
//
// //返回运行时
// if getTime := gtime.Now().Sub(RunStartTime); getTime > time.Millisecond*1000 {
// g.Log().Debugf(nil, "当前运行时间:%v,uid=%d,url=%s", getTime, uid, r.RequestURI)
// }
//
// //中间件后置
// err := r.GetError()
// if err != nil {
// code, err2 := strconv.Atoi(err.Error())
// if err2 != nil {
// return
// }
// if _, ok := consts.ErrCodeList[code]; ok {
// //g.Dump("===error:", gerror.Code(r.GetError()).Code())
// msg := g.Map{
// "code": code,
// "message": consts.ErrCodeList[code],
// //"data": r.GetHandlerResponse(),
// }
// msgJson, _ := gjson.EncodeString(msg)
// r.Response.WriteJson(msgJson)
// //错误码置空
// r.SetError(nil)
// g.Log("cmd").Debugf(r.GetCtx(), "to|%v|%v|%v", uid, r.RequestURI, msg)
// return
// }
// }
//
// //后置输出服务器返回信息
// if r.GetCtxVar("not_log").IsEmpty() {
// res, _ := gjson.EncodeString(r.GetHandlerResponse())
// g.Log("cmd").Debugf(r.GetCtx(), "to|%v|%v|%v", uid, r.RequestURI, res)
// }
//
//}

View File

@@ -0,0 +1,5 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package callback

View File

@@ -0,0 +1,15 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package callback
import (
"github.com/ayflying/utility_go/api/callback"
)
type ControllerV1 struct{}
func NewV1() callback.ICallbackV1 {
return &ControllerV1{}
}

View File

@@ -0,0 +1,14 @@
package callback
import (
"context"
"github.com/ayflying/utility_go/service"
"github.com/ayflying/utility_go/api/callback/v1"
)
func (c *ControllerV1) Ip(ctx context.Context, req *v1.IpReq) (res *v1.IpRes, err error) {
res = &v1.IpRes{}
res.Address = service.Ip2Region().GetIp(req.Ip)
return
}

25
go.mod
View File

@@ -6,13 +6,21 @@ require (
github.com/apolloconfig/agollo/v4 v4.4.0 github.com/apolloconfig/agollo/v4 v4.4.0
github.com/ayflying/excel2json v1.1.2 github.com/ayflying/excel2json v1.1.2
github.com/elastic/go-elasticsearch/v8 v8.17.0 github.com/elastic/go-elasticsearch/v8 v8.17.0
github.com/go-pay/crypto v0.0.1
github.com/go-pay/gopay v1.5.109
github.com/go-pay/util v0.0.4
github.com/gogf/gf/contrib/config/apollo/v2 v2.8.3 github.com/gogf/gf/contrib/config/apollo/v2 v2.8.3
github.com/gogf/gf/v2 v2.8.3 github.com/gogf/gf/v2 v2.8.3
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20241220152942-06eb5c6e8230
github.com/minio/minio-go/v7 v7.0.85 github.com/minio/minio-go/v7 v7.0.85
github.com/xuri/excelize/v2 v2.9.0 github.com/xuri/excelize/v2 v2.9.0
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602
google.golang.org/api v0.44.0
google.golang.org/protobuf v1.26.0
) )
require ( require (
cloud.google.com/go v0.81.0 // indirect
github.com/360EntSecGroup-Skylar/excelize v1.4.1 // indirect github.com/360EntSecGroup-Skylar/excelize v1.4.1 // indirect
github.com/BurntSushi/toml v1.4.0 // indirect github.com/BurntSushi/toml v1.4.0 // indirect
github.com/clbanning/mxj/v2 v2.7.0 // indirect github.com/clbanning/mxj/v2 v2.7.0 // indirect
@@ -24,8 +32,15 @@ require (
github.com/go-ini/ini v1.67.0 // indirect github.com/go-ini/ini v1.67.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-pay/errgroup v0.0.3 // indirect
github.com/go-pay/smap v0.0.2 // indirect
github.com/go-pay/xlog v0.0.3 // indirect
github.com/go-pay/xtime v0.0.2 // indirect
github.com/goccy/go-json v0.10.4 // indirect github.com/goccy/go-json v0.10.4 // indirect
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/gax-go/v2 v2.0.5 // indirect
github.com/gorilla/websocket v1.5.3 // indirect github.com/gorilla/websocket v1.5.3 // indirect
github.com/grokify/html-strip-tags-go v0.1.0 // indirect github.com/grokify/html-strip-tags-go v0.1.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect
@@ -52,14 +67,18 @@ require (
github.com/subosito/gotenv v1.2.0 // indirect github.com/subosito/gotenv v1.2.0 // indirect
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect
go.opencensus.io v0.23.0 // indirect
go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect
go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect
go.opentelemetry.io/otel/sdk v1.24.0 // indirect go.opentelemetry.io/otel/sdk v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect
golang.org/x/crypto v0.31.0 // indirect golang.org/x/crypto v0.33.0 // indirect
golang.org/x/net v0.33.0 // indirect golang.org/x/net v0.33.0 // indirect
golang.org/x/sys v0.28.0 // indirect golang.org/x/sys v0.30.0 // indirect
golang.org/x/text v0.21.0 // indirect golang.org/x/text v0.22.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect
google.golang.org/grpc v1.38.0 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect

41
go.sum
View File

@@ -17,6 +17,7 @@ cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKP
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
cloud.google.com/go v0.81.0 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8=
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
@@ -102,6 +103,20 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-pay/crypto v0.0.1 h1:B6InT8CLfSLc6nGRVx9VMJRBBazFMjr293+jl0lLXUY=
github.com/go-pay/crypto v0.0.1/go.mod h1:41oEIvHMKbNcYlWUlRWtsnC6+ASgh7u29z0gJXe5bes=
github.com/go-pay/errgroup v0.0.3 h1:DB4s8e8oWYDyETKQ1y1riMJ7y29zE1uIsMCSjEOFSbU=
github.com/go-pay/errgroup v0.0.3/go.mod h1:0+4b8mvFMS71MIzsaC+gVvB4x37I93lRb2dqrwuU8x8=
github.com/go-pay/gopay v1.5.109 h1:rF9bCUaAuz2jWHwgIuIfgrAejFOMufo9UsNENouFVcU=
github.com/go-pay/gopay v1.5.109/go.mod h1:1B4NjEWKwRtJeNk2YhYwjcIJuwtxrOK0nZsh5slqrWI=
github.com/go-pay/smap v0.0.2 h1:kKflYor5T5FgZltPFBMTFfjJvqYMHr5VnIFSEyhVTcA=
github.com/go-pay/smap v0.0.2/go.mod h1:HW9oAo0okuyDYsbpbj5fJFxnNj/BZorRGFw26SxrNWw=
github.com/go-pay/util v0.0.4 h1:TuwSU9o3Qd7m9v1PbzFuIA/8uO9FJnA6P7neG/NwPyk=
github.com/go-pay/util v0.0.4/go.mod h1:Tsdhs8Ib9J9b4+NKNO1PHh5hWHhlg98PthsX0ckq6PM=
github.com/go-pay/xlog v0.0.3 h1:avyMhCL/JgBHreoGx/am/kHxfs1udDOAeVqbmzP/Yes=
github.com/go-pay/xlog v0.0.3/go.mod h1:mH47xbobrdsSHWsmFtSF5agWbMHFP+tK0ZbVCk5OAEw=
github.com/go-pay/xtime v0.0.2 h1:7YR4/iuELsEHpJ6LUO0SVK80hQxDO9MLCfuVYIiTCRM=
github.com/go-pay/xtime v0.0.2/go.mod h1:W1yRbJaSt4CSBcdAtLBQ8xajiN/Pl5hquGczUcUE9xE=
github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM=
github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
@@ -113,6 +128,7 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@@ -138,6 +154,7 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -174,6 +191,7 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
@@ -223,6 +241,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20241220152942-06eb5c6e8230 h1:B0oaMTAQKDZd8cwYT0qsAI7+c3KbFeBNA8GhgoBMXWw=
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20241220152942-06eb5c6e8230/go.mod h1:C5LA5UO2ZXJrLaPLYtE1wUJMiyd/nwWaCO5cw/2pSHs=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM= github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM=
github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
@@ -239,8 +259,6 @@ github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.84 h1:D1HVmAF8JF8Bpi6IU4V9vIEj+8pc+xU88EWMs2yed0E=
github.com/minio/minio-go/v7 v7.0.84/go.mod h1:57YXpvc5l3rjPdhqNrDsvVlY0qPI6UTk1bflAe+9doY=
github.com/minio/minio-go/v7 v7.0.85 h1:9psTLS/NTvC3MWoyjhjXpwcKoNbkongaCSF3PNpSuXo= github.com/minio/minio-go/v7 v7.0.85 h1:9psTLS/NTvC3MWoyjhjXpwcKoNbkongaCSF3PNpSuXo=
github.com/minio/minio-go/v7 v7.0.85/go.mod h1:57YXpvc5l3rjPdhqNrDsvVlY0qPI6UTk1bflAe+9doY= github.com/minio/minio-go/v7 v7.0.85/go.mod h1:57YXpvc5l3rjPdhqNrDsvVlY0qPI6UTk1bflAe+9doY=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
@@ -330,6 +348,7 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
@@ -349,8 +368,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -437,6 +456,7 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602 h1:0Ja1LBD+yisY6RWM/BH7TJVXWsSjs2VwBSmvSX4HdBc=
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -492,8 +512,8 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -502,8 +522,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -583,6 +603,7 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
google.golang.org/api v0.44.0 h1:URs6qR1lAxDsqWITsQXI4ZkGiYJ5dHtRNiCpfs2OeKA=
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -590,6 +611,7 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -631,6 +653,7 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -651,6 +674,7 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
@@ -663,6 +687,7 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=

17
hack/config.yaml Normal file
View File

@@ -0,0 +1,17 @@
# CLI tool, only in development environment.
# https://goframe.org/pages/viewpage.action?pageId=3673173
gfcli:
gen:
ctrl:
dstFolder: "controller"
service:
dstFolder: "service"
pb:
path: "manifest/protobuf"
api: "api"
docker:
build: "-a amd64 -s linux -p temp -ew"
tagPrefixes:
- "hub.docker.com"
# - "git.7cuu.com"
tag: "latest"

53
internal/game/act/act.go Normal file
View File

@@ -0,0 +1,53 @@
package act
import (
"fmt"
"github.com/ayflying/utility_go/aycache"
"github.com/ayflying/utility_go/service"
"github.com/gogf/gf/v2/container/gvar"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/gtime"
"time"
)
var (
Cache = aycache.New()
ActIdListIsShow map[int]func(uid int64) bool
RedDotList map[string]func(uid int64) int32
)
func GetCacheKey(uid int64, actId int) string {
return fmt.Sprintf("actRedDot:%s:%d:%d", gtime.Now().Format("Ymd"), actId, uid)
}
// 刷新缓存
func RefreshCache(uid int64, actId int) {
Cache.Remove(gctx.New(), GetCacheKey(uid, actId))
service.GameAct().RefreshGetRedDotCache(uid)
}
func GetRedDot(uid int64, actId int) *gvar.Var {
get, _ := Cache.Get(nil, GetCacheKey(uid, actId))
return get
}
func SetRedDot(uid int64, actId int, redDot int32) {
Cache.Set(nil, GetCacheKey(uid, actId), redDot, time.Hour)
}
// 注册隐藏活动接口
func AddIsShowRegistrar(actId int, isShow func(uid int64) bool) {
if ActIdListIsShow == nil {
ActIdListIsShow = make(map[int]func(uid int64) bool)
}
ActIdListIsShow[actId] = isShow
}
// 注册红点接口
func AddRedDotRegistrar(key string, redDot func(uid int64) int32) {
if RedDotList == nil {
RedDotList = make(map[string]func(uid int64) int32)
}
RedDotList[key] = redDot
}

View File

@@ -0,0 +1,266 @@
package gameAct
import (
"fmt"
"github.com/ayflying/utility_go/aycache"
"github.com/ayflying/utility_go/internal/game/act"
"github.com/ayflying/utility_go/internal/model/do"
"github.com/ayflying/utility_go/internal/model/entity"
service2 "github.com/ayflying/utility_go/service"
"github.com/ayflying/utility_go/tools"
"github.com/gogf/gf/v2/container/gset"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/gtime"
"strconv"
"strings"
"time"
)
var (
ctx = gctx.New()
Name = "game_act"
ActList = gset.New(true)
)
type sGameAct struct {
}
func new() *sGameAct {
return &sGameAct{}
}
func init() {
service2.RegisterGameAct(new())
}
// Info 获取活动信息
//
// @Description: 根据用户ID和活动ID获取活动信息
// @receiver s *sGameAct: 代表活动操作的结构体实例
// @param uid int64: 用户ID
// @param actId int: 活动ID
// @return data *v1.Act: 返回活动信息结构体指针
// @return err error: 返回错误信息
func (s *sGameAct) Info(uid int64, actId int) (data *g.Var, err error) {
if uid == 0 || actId == 0 {
g.Log().Error(ctx, "当前参数为空")
return
}
// 构造缓存键名
keyCache := fmt.Sprintf("act:%v:%v", actId, uid)
// 尝试从Redis缓存中获取活动信息
get, err := g.Redis().Get(ctx, keyCache)
if !get.IsEmpty() {
// 如果缓存中存在将数据扫描到data结构体中并返回
data = get
return
}
// 从数据库中查询活动信息
getDb, err := g.Model(Name).Where(do.GameAct{
Uid: uid,
ActId: actId,
}).Fields("action").OrderDesc("updated_at").Value()
getDb.Scan(&data)
if data == nil || data.IsEmpty() {
return
}
// 将查询到的活动信息保存到Redis缓存中
_, err = g.Redis().Set(ctx, keyCache, data)
var ActUidUpdateTimeCacheKey = fmt.Sprintf("act:update:%d", uid)
aycache.New("redis").Set(ctx, ActUidUpdateTimeCacheKey, uid, time.Hour*24*3)
return
}
// Set 将指定用户的活动信息存储到Redis缓存中。
//
// @Description:
// @receiver s *sGameAct: 表示sGameAct类型的实例。
// @param uid int64: 用户的唯一标识。
// @param actId int: 活动的唯一标识。
// @param data interface{}: 要存储的活动信息数据。
// @return err error: 返回错误信息如果操作成功则返回nil。
func (s *sGameAct) Set(uid int64, actId int, data interface{}) (err error) {
if uid == 0 || actId == 0 {
g.Log().Error(ctx, "当前参数为空")
return
}
// 构造缓存键名
keyCache := fmt.Sprintf("act:%v:%v", actId, uid)
if data == nil {
_, err = g.Redis().Del(ctx, keyCache)
return
}
// 将活动信息保存到Redis缓存并将用户ID添加到活动索引集合中
_, err = g.Redis().Set(ctx, keyCache, data)
//插入集合
ActList.Add(actId)
return
}
func (s *sGameAct) Saves() (err error) {
//遍历执行
ActList.Iterator(func(i interface{}) bool {
err = s.Save(i.(int))
return true
})
return
}
func (s *sGameAct) Save(actId int) (err error) {
cacheKey := fmt.Sprintf("act:%v:*", actId)
//获取当前用户的key值
//keys, err := utils.RedisScan(cacheKey)
//if len(keys) > 10000 {
// keys = keys[:10000]
//}
//循环获取缓存数据
err = tools.Redis.RedisScanV2(cacheKey, func(keys []string) (err error) {
var add []interface{}
var delKey []string
for _, cacheKey = range keys {
result := strings.Split(cacheKey, ":")
actId, err = strconv.Atoi(result[1])
var uid int64
uid, err = strconv.ParseInt(result[2], 10, 64)
if err != nil {
continue
}
cacheGet, _ := g.Redis().Get(ctx, cacheKey)
//最后删除key
delKey = append(delKey, cacheKey)
if uid == 0 {
//跳过为空的用户缓存
continue
}
if cacheGet.IsEmpty() {
//空数据也不巴保存
continue
}
var ActUidUpdateTimeCacheKey = fmt.Sprintf("act:update:%d", uid)
//如果有活跃,跳过持久化
if getBool, _ := aycache.New("redis").Contains(ctx, ActUidUpdateTimeCacheKey); getBool {
continue
}
////如果1天没有活跃跳过
//user, _ := service.MemberUser().Info(uid)
//if user.UpdatedAt.Seconds < gtime.Now().Add(consts.ActSaveTime).Unix() {
// continue
//}
//获取数据库数据
var data *entity.GameAct
// 从数据库中查询活动信息
err = g.Model(Name).Where(do.GameAct{
Uid: uid,
ActId: actId,
}).Fields("uid,act_id").Scan(&data)
if err != nil {
g.Log().Debugf(ctx, "当前数据错误: %v", cacheKey)
continue
}
actionData := cacheGet.String()
if data == nil {
//data =
add = append(add, &do.GameAct{
ActId: actId,
Uid: uid,
Action: actionData,
})
} else {
//覆盖数据
data.Action = actionData
add = append(add, data)
}
}
//批量写入数据库
if len(add) > 0 {
dbRes, err2 := g.Model(Name).Batch(30).Data(add).Save()
add = make([]interface{}, 0)
if err2 != nil {
g.Log().Error(ctx, err2)
return
}
for _, v := range delKey {
_, err2 = g.Redis().Del(ctx, v)
if err2 != nil {
g.Log().Error(ctx, err2)
return
}
}
delKey = make([]string, 0)
count, _ := dbRes.RowsAffected()
g.Log().Debugf(ctx, "当前 %v 写入数据库: %v 条", actId, count)
}
if err != nil {
g.Log().Error(ctx, "当前临时数据入库失败: %v", err)
}
return err
})
return
}
// 清空GetRedDot缓存
func (s *sGameAct) RefreshGetRedDotCache(uid int64) {
//cacheKey2 := fmt.Sprintf("gameAct:GetRedDot:%d", uid)
cacheKey := fmt.Sprintf("gameAct:GetRedDot:%s:%d", gtime.Now().Format("Ymd"), uid)
act.Cache.Remove(gctx.New(), cacheKey)
}
//
//func (s *sGameAct) GetRedDot(uid int64) (res map[string]int32, err error) {
// cacheKey := fmt.Sprintf("gameAct:GetRedDot:%s:%d", gtime.Now().Format("Ymd"), uid)
// if get, _ := act.Cache.Get(ctx, cacheKey); !get.IsEmpty() {
// err = get.Scan(&res)
// return
// }
//
// res = make(map[string]int32)
//
// //res["notice_count"] = 0
// //获取所有帖子红点
// for _, v := range communityNotice.Types {
// res[fmt.Sprintf("notice_%d", v)], err = service.CommunityNotice().Ping(uid, noticeV1.NoticeType(v))
// }
//
// //邮件红点
// res["mail_count"], err = service.GameMail().RedDot(uid)
//
// //act1可领取数量
// res["act1_count"], err = act1.New().RedDot(uid)
//
// //act2可领取数量
// res["act2_count"], err = act2.New().RedDot(uid)
//
// //成就红点
// res["act4_count"], err = act4.New().RedDot(uid)
//
// //广告点击
// res["act6_count"], err = act6.New().RedDot(uid)
//
// for k, v := range act.RedDotList {
// res[k] = v(uid)
// }
//
// aycache.New().Set(ctx, cacheKey, res, time.Hour)
// return
//}

View File

@@ -0,0 +1,104 @@
package ip2region
import (
"github.com/ayflying/utility_go/service"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/gfile"
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
"net"
"strings"
)
var (
ctx = gctx.New()
)
type sIp2region struct {
searcher *xdb.Searcher
}
func New() *sIp2region {
s := &sIp2region{}
s.Load()
return s
}
func init() {
service.RegisterIp2Region(New())
}
// Load 加载到内存中
//
// @Description: 加载ip2region数据库到内存中。
// @receiver s *sIp2region: sIp2region的实例。
func (s *sIp2region) Load() {
var err error
//var dbPath = "/mnt/s3/ip2region.xdb"
var dbPath = "lib/ip2region.xdb"
if gfile.IsEmpty(dbPath) {
//下载文件
putData, err2 := g.Client().Discovery(nil).
Get(ctx, "https://resource.luoe.cn/pgk/ip2region.xdb")
if err2 != nil {
return
}
err = gfile.PutBytes(dbPath, putData.ReadAll())
}
cBuff := gfile.GetBytes(dbPath)
/*
var cBuff []byte
if gres.Contains(dbPath) {
cBuff = gres.GetContent(dbPath)
} else {
cBuff = gfile.GetBytes(dbPath)
}
*/
// 基于读取的内容,创建查询对象
s.searcher, err = xdb.NewWithBuffer(cBuff)
if err != nil {
g.Log().Errorf(ctx, "无法创建内容为的搜索器: %s", err)
return
}
}
func (s *sIp2region) GetIp(ip string) (res []string) {
res = make([]string, 5)
if s.searcher == nil {
return
}
//如果是ipv6直接跳过
if s.isIPv6(ip) {
return
}
region, err := s.searcher.SearchByStr(ip)
if err != nil {
return
}
res = strings.Split(region, "|")
return
}
// isIPv6 判断输入字符串是否为IPv6地址
//
// @Description: 通过解析输入的IP字符串判断其是否为IPv6地址。
// @receiver s *sIp2region: 代表`sIp2region`类型的实例,本函数中未使用,可忽略。
// @param ipStr string: 待判断的IP地址字符串。
// @return bool: 返回true表示是IPv6地址返回false表示不是IPv6地址。
func (s *sIp2region) isIPv6(ipStr string) bool {
// 尝试将输入字符串解析为IP地址
ip := net.ParseIP(ipStr)
// 尝试将IP地址转换为IPv4格式
ipv4 := ip.To4()
// 如果转换为IPv4格式不为nil则说明是IPv4地址返回false
if ipv4 != nil {
return false
}
// 如果无法转换为IPv4格式则说明是IPv6地址返回true
return true
}

View File

@@ -0,0 +1,135 @@
package logData
import (
"context"
"github.com/ayflying/utility_go/service"
"github.com/ayflying/utility_go/tools"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"time"
)
var (
ctx = gctx.New()
//pathStr = "runtime/log/logData"
//te thinkingdata.TDAnalytics
//logChannel chan map[string]interface{}
//wg sync.WaitGroup
)
type sLogData struct {
}
func New() *sLogData {
return &sLogData{}
}
func init() {
service.RegisterLogData(New())
//加载日志模块
//service.LogData().Load()
}
func (s *sLogData) Load() {
//数数科技初始化配置
//// 创建 LogConfig 配置文件
//config := thinkingdata.TDLogConsumerConfig{
// Directory: pathStr, // 事件采集的文件路径
// //FileSize: 99, //单个日志文件的最大大小MB
//}
//// 初始化 logConsumer
//consumer, _ := thinkingdata.NewLogConsumerWithConfig(config)
//// 创建 te 对象
//te = thinkingdata.New(consumer)
//日志写入通道开启
//logAppend()
}
// UserSet 方法
//
// @Description: 设置用户信息。
// @receiver s: sLogData 的实例,表示日志数据的结构体。
// @param accountId: 账户ID用于标识账户是字符串格式。
// @param uid: 用户的ID是整型的唯一标识符。
// @param data: 要设置的用户信息以键值对的形式提供是map[string]interface{}类型,支持多种用户属性。
// @return err: 执行过程中可能出现的错误如果执行成功则返回nil。
func (s *sLogData) UserSet(accountId string, uid int64, data map[string]interface{}) (err error) {
// 将用户ID转换为字符串格式的唯一标识
//distinctId := strconv.FormatInt(uid, 10)
// 使用accountId和distinctId以及data来设置用户信息此处调用外部方法完成设置。
//te.UserSet(accountId, distinctId, data)
data["#uid"] = uid
data["#time"] = time.Now()
data["#type"] = "user_set"
//data["_id"], _ = uuid.NewUUID()
//data["#name"] = name
g.Log("elk").Info(nil, data)
//todo 暂时关闭update
//err = s.Update(uid, data)
return
}
// Track 函数记录特定事件。
//
// @Description: 用于跟踪和记录一个指定事件的发生,收集相关数据。
// @receiver s: sLogData 的实例,代表日志数据的存储或处理实体。
// @param accountId: 账户ID用于标识事件所属的账户。
// @param uid: 用户的ID一个整型数值用于区分不同的用户。
// @param name: 事件名称,标识所记录的具体事件。
// @param data: 事件相关的数据映射,包含事件的详细信息。
// @return err: 错误信息如果操作成功则为nil。
func (s *sLogData) Track(ctx context.Context, accountId string, uid int64, name string, data map[string]interface{}) {
// 将用户ID转换为字符串格式的唯一标识
//distinctId := strconv.FormatInt(uid, 10)
// 调用te.Track函数来实际记录事件传入账户ID、用户唯一标识、事件名称及事件数据
//te.Track(accountId, distinctId, name, data)
if data == nil {
return
}
data["#uid"] = uid
data["#event_name"] = name
data["#time"] = time.Now()
data["#type"] = "track"
//data["_id"], _ = uuid.NewUUID()
//道具类型特殊格式化
if get, ok := data["items"]; ok {
if get != nil {
data["items"] = tools.Tools.Items2Map(get.([][]int64))
}
}
g.Log("elk").Info(nil, data)
//err = s.Add(data)
//由于实时写入日志太占用资源,关闭日志写入方法
return
}
//// 上报用不了,弃用
//func (s *sLogData) Send() (err error) {
// consumer, err := thinkingdata.NewBatchConsumer("https://yoyatime-server-release.yoyaworld.com/callback", "dev")
// te = thinkingdata.New(consumer)
// err = te.Flush()
// return
//}
//func (s *sLogData) Flush() (err error) {
// //调用flush接口数据会立即写入文件生产环境注意避免频繁调用flush引发IO或网络开销问题
// err = te.Flush()
// return
//}
//
//func (s *sLogData) Close() {
// // 关闭通道,表示没有更多的日志条目需要写入
// if logChannel != nil {
// close(logChannel)
// wg.Wait() // 等待通道监听goroutine结束
// }
//
// te.Close()
//}

13
internal/logic/logic.go Normal file
View File

@@ -0,0 +1,13 @@
// ==========================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// ==========================================================================
package logic
import (
_ "github.com/ayflying/utility_go/internal/logic/gameAct"
_ "github.com/ayflying/utility_go/internal/logic/ip2region"
_ "github.com/ayflying/utility_go/internal/logic/logData"
_ "github.com/ayflying/utility_go/internal/logic/systemCron"
_ "github.com/ayflying/utility_go/internal/logic/systemLog"
)

View File

@@ -0,0 +1,71 @@
package systemCron
import (
"encoding/json"
"fmt"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/gclient"
"github.com/gogf/gf/v2/os/gtime"
)
type Status struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
Status int `json:"status"`
} `json:"data"`
}
func (s *sSystemCron) Guardian(DingTalkWebHook string) {
var list []struct {
Name string
Address string
}
cfg, _ := g.Cfg().Get(ctx, "serverList")
cfg.Scan(&list)
for _, v := range list {
get, err := g.Client().Discovery(nil).Get(ctx, v.Address+"/callback/status")
defer get.Close()
if err != nil {
s.DingTalk(DingTalkWebHook, fmt.Sprintf("监控报警:服务端访问失败 (%v 服务器),err=%v", v.Name, err))
} else if get.StatusCode != 200 {
s.DingTalk(DingTalkWebHook, fmt.Sprintf("监控报警:服务端访问失败 (%v 服务器),code=%v,err=%v", v.Name, get.StatusCode, err))
} else {
var ststus Status
err = json.Unmarshal(get.ReadAll(), &ststus)
if ststus.Code != 0 {
s.DingTalk(DingTalkWebHook, fmt.Sprintf("监控报警:服务端访问失败 (%v 服务器),msg=%v", v.Name, ststus.Message))
}
}
}
}
// DingTalk 发送钉钉消息
//
// @Description: 向指定的钉钉机器人发送消息。
// @receiver s: 系统定时任务结构体指针。
// @param value: 要发送的消息内容。
func (s *sSystemCron) DingTalk(DingTalkWebHook string, value string) (res *gclient.Response) {
// 从配置中获取发送者名称
name, _ := g.Cfg().Get(ctx, "name")
// 定义钉钉机器人发送消息的URL其中access_token为固定值
url := DingTalkWebHook
url += "&timestamp=" + gtime.Now().TimestampMilliStr()
// 使用goroutine异步发送消息
var post = g.Map{
"msgtype": "text",
"text": g.Map{
"content": "通知姬 " + name.String() + "\n" + value + "\n" + gtime.Now().String(),
},
}
// 构建发送的消息体,包含消息类型和内容
res, err := g.Client().Discovery(nil).ContentJson().Post(ctx, url, post)
if err != nil {
g.Log().Info(ctx, err)
}
return
}

View File

@@ -0,0 +1,5 @@
package systemCron
func (s *sSystemCron) ReadLog() {
}

View File

@@ -0,0 +1,305 @@
package systemCron
import (
"context"
"github.com/ayflying/utility_go/api/system/v1"
"github.com/ayflying/utility_go/service"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gcron"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/os/gtimer"
"sync"
"time"
)
var (
ctx = gctx.New()
)
// sSystemCron 结构体定义了系统定时任务的秒计时器。
// 它包含了不同时间周期的任务,如秒、分钟、小时、天、周、月、年以及特定的工作日任务。
type sSystemCron struct {
//互斥锁
Lock sync.Mutex
// 每秒执行的任务
SecondlyTask []func() error
// 每分钟执行的任务
MinutelyTask []func() error
// 每小时执行的任务
HourlyTask []func() error
// 每天执行的任务
DailyTask []func() error
// 每周执行的任务
WeeklyTask []func() error
// 每月执行的任务
MonthlyTask []func() error
// 每年执行的任务
YearlyTask []func() error
// 每周一执行的任务
MondayTask []func() error
// 每周二执行的任务
TuesdayTask []func() error
// 每周三执行的任务
WednesdayTask []func() error
// 每周四执行的任务
ThursdayTask []func() error
// 每周五执行的任务
FridayTask []func() error
// 每周六执行的任务
SaturdayTask []func() error
// 每周日执行的任务
SundayTask []func() error
}
func New() *sSystemCron {
return &sSystemCron{}
}
func init() {
service.RegisterSystemCron(New())
}
// AddCron 添加一个定时任务到相应的调度列表中。
//
// @Description: 根据指定的类型将函数添加到不同的任务列表中,以供后续执行。
// @receiver s: sSystemCron的实例代表一个调度系统。
// @param typ: 任务的类型,决定该任务将被添加到哪个列表中。对应不同的时间间隔。
// @param _func: 要添加的任务函数该函数执行时应该返回一个error。
func (s *sSystemCron) AddCron(typ v1.CronType, _func func() error) {
//加锁
s.Lock.Lock()
defer s.Lock.Unlock()
switch typ {
case v1.CronType_SECOND:
s.SecondlyTask = append(s.SecondlyTask, _func) // 将函数添加到每秒执行的任务列表中
case v1.CronType_MINUTE:
s.MinutelyTask = append(s.MinutelyTask, _func) // 将函数添加到每分钟执行的任务列表中
case v1.CronType_HOUR:
s.HourlyTask = append(s.HourlyTask, _func) // 将函数添加到每小时执行的任务列表中
case v1.CronType_DAILY:
s.DailyTask = append(s.DailyTask, _func) // 将函数添加到每日执行的任务列表中
case v1.CronType_WEEK:
s.WeeklyTask = append(s.WeeklyTask, _func) // 将函数添加到每周执行的任务列表中
case v1.CronType_MONTH:
s.MonthlyTask = append(s.MonthlyTask, _func) // 将函数添加到每月执行的任务列表中
case v1.CronType_YEAR:
s.YearlyTask = append(s.YearlyTask, _func) // 将函数添加到每年执行的任务列表中
case v1.CronType_MONDAY:
s.MondayTask = append(s.MondayTask, _func) // 将函数添加到每周一执行的任务列表中
case v1.CronType_TUESDAY:
s.TuesdayTask = append(s.TuesdayTask, _func) // 将函数添加到每周二的任务列表中
case v1.CronType_WEDNESDAY:
s.WednesdayTask = append(s.WednesdayTask, _func) // 将函数添加到每周三执行的任务列表中
case v1.CronType_THURSDAY:
s.ThursdayTask = append(s.ThursdayTask, _func) // 将函数添加到每周四执行的任务列表中
case v1.CronType_FRIDAY:
s.FridayTask = append(s.FridayTask, _func) // 将函数添加到每周五执行的任务列表中
case v1.CronType_SATURDAY:
s.SaturdayTask = append(s.SaturdayTask, _func) // 将函数添加到每周六执行的任务列表中
case v1.CronType_SUNDAY:
s.SundayTask = append(s.SundayTask, _func) // 将函数添加到每周日的任务列表中
}
}
// StartCron 开始计划任务执行
//
// @Description:
// @receiver s
// @return err
func (s *sSystemCron) StartCron() (err error) {
g.Log().Debug(ctx, "启动计划任务定时器详情")
//每秒任务
gtimer.SetInterval(ctx, time.Second, func(ctx context.Context) {
//g.Log().Debug(ctx, "每秒定时器")
err = s.secondlyTask()
})
//每分钟任务
_, err = gcron.AddSingleton(ctx, "0 * * * * *", func(ctx context.Context) {
//g.Log().Debug(ctx, "每分钟定时器")
err = s.minutelyTask()
})
//每小时任务
_, err = gcron.AddSingleton(ctx, "0 0 * * * *", func(ctx context.Context) {
g.Log().Debug(ctx, "每小时定时器")
err = s.hourlyTask()
})
//每天任务
_, err = gcron.AddSingleton(ctx, "0 0 0 * * *", func(ctx context.Context) {
g.Log().Debug(ctx, "每日定时器")
err = s.dailyTask()
})
//每周任务
_, err = gcron.AddSingleton(ctx, "0 0 0 * * 1", func(ctx context.Context) {
g.Log().Debug(ctx, "每周一定时器")
err = s.weeklyTask(1)
})
//每周二任务
_, err = gcron.AddSingleton(ctx, "0 0 0 * * 2", func(ctx context.Context) {
g.Log().Debug(ctx, "每周二定时器")
err = s.weeklyTask(2)
})
//周三任务
_, err = gcron.AddSingleton(ctx, "0 0 0 * * 3", func(ctx context.Context) {
g.Log().Debug(ctx, "周三定时器")
err = s.weeklyTask(3)
})
//周四任务
_, err = gcron.AddSingleton(ctx, "0 0 0 * * 4", func(ctx context.Context) {
g.Log().Debug(ctx, "周四定时器")
err = s.weeklyTask(4)
})
//周五任务
_, err = gcron.AddSingleton(ctx, "0 0 0 * * 5", func(ctx context.Context) {
g.Log().Debug(ctx, "周五定时器")
err = s.fridayTask()
})
//周六任务
_, err = gcron.AddSingleton(ctx, "0 0 0 * * 6", func(ctx context.Context) {
g.Log().Debug(ctx, "周六定时器")
err = s.weeklyTask(6)
})
//周日任务
_, err = gcron.AddSingleton(ctx, "0 0 0 * * 0", func(ctx context.Context) {
g.Log().Debug(ctx, "周日定时器")
err = s.weeklyTask(7)
})
//每月任务
_, err = gcron.AddSingleton(ctx, "0 0 0 1 * *", func(ctx context.Context) {
g.Log().Debug(ctx, "每月定时器")
err = s.monthlyTask()
})
_, err = gcron.AddSingleton(ctx, "0 0 0 1 1 *", func(ctx context.Context) {
g.Log().Debug(ctx, "每年定时器")
err = s.monthlyTask()
})
return
}
// 每妙任务
func (s *sSystemCron) secondlyTask() (err error) {
if len(s.SecondlyTask) == 0 {
return
}
for _, _func := range s.SecondlyTask {
err = _func()
if err != nil {
g.Log().Error(ctx, err)
}
}
return
}
// 每分钟任务
func (s *sSystemCron) minutelyTask() (err error) {
if len(s.MinutelyTask) == 0 {
return
}
for _, _func := range s.MinutelyTask {
err = _func()
if err != nil {
g.Log().Error(ctx, err)
}
}
return
}
// 每小时任务
func (s *sSystemCron) hourlyTask() (err error) {
if len(s.HourlyTask) == 0 {
return
}
for _, _func := range s.HourlyTask {
err = _func()
if err != nil {
g.Log().Error(ctx, err)
}
}
return
}
// 每天任务
func (s *sSystemCron) dailyTask() (err error) {
if len(s.DailyTask) == 0 {
return
}
for _, _func := range s.DailyTask {
err = _func()
if err != nil {
g.Log().Error(ctx, err)
}
}
return
}
// 每周任务
func (s *sSystemCron) weeklyTask(day int) (err error) {
var arr []func() error
switch day {
case 1:
arr = s.MondayTask
case 2:
arr = s.TuesdayTask
case 3:
arr = s.WednesdayTask
case 4:
arr = s.ThursdayTask
case 5:
arr = s.FridayTask
case 6:
arr = s.SaturdayTask
case 7:
arr = s.SundayTask
default:
arr = s.WeeklyTask
return
}
if len(arr) == 0 {
return
}
for _, _func := range arr {
err = _func()
if err != nil {
g.Log().Error(ctx, err)
}
}
return
}
// 周五任务
func (s *sSystemCron) fridayTask() (err error) {
if len(s.FridayTask) == 0 {
return
}
for _, _func := range s.FridayTask {
err = _func()
if err != nil {
g.Log().Error(ctx, err)
}
}
return
}
// 每月任务
func (s *sSystemCron) monthlyTask() (err error) {
if len(s.MonthlyTask) == 0 {
return
}
for _, _func := range s.MonthlyTask {
err = _func()
if err != nil {
g.Log().Error(ctx, err)
}
}
return
}

View File

@@ -0,0 +1,66 @@
package systemLog
import (
"context"
v1 "github.com/ayflying/utility_go/api/admin/v1"
"github.com/ayflying/utility_go/service"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
)
type sSystemLog struct {
ctx context.Context
}
var (
ctx = gctx.New()
//db = dao.AdminSystemLog.Ctx(ctx)
name = "system_log"
)
func init() {
service.RegisterSystemLog(New())
}
func New() *sSystemLog {
return &sSystemLog{}
}
func (s *sSystemLog) List(page int) (list []*v1.SystemLog, max int, err error) {
//var list = []*AdminSystemLog{}
max, _ = g.Model(name).Count()
g.Model(name).OrderDesc("created_at").Page(page, 100).Scan(&list)
return
}
// 写入操作日志
func (s *sSystemLog) AddLog(uid int, url string, ip string, data g.Map) (id int64, err error) {
//跳过空日志
if data == nil {
return
}
//如果存在这些值,直接跳过不写入日志
paichu := []string{
"/api/install",
"/activity/url/log/add",
"/system/update",
"/api/cdkey",
}
for _, item := range paichu {
if item == url {
return
}
}
var post v1.SystemLog
//uid := g.RequestFromCtx(ctx).Header.Get("x-uid")
post.Uid = uid
post.Url = url
post.Ip = ip
post.Data = data
id, err = g.Model(name).InsertAndGetId(post)
return
}

View File

@@ -0,0 +1,18 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// CommunityFans is the golang structure of table shiningu_community_fans for DAO operations like Where/Data.
type CommunityFans struct {
g.Meta `orm:"table:shiningu_community_fans, do:true"`
Uid interface{} // 用户编号
Fans interface{} // 粉丝编号
CreatedAt *gtime.Time // 关注时间
}

View File

@@ -0,0 +1,19 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// CommunityFeeds is the golang structure of table shiningu_community_feeds for DAO operations like Where/Data.
type CommunityFeeds struct {
g.Meta `orm:"table:shiningu_community_feeds, do:true"`
Id interface{} // 流水
Uid interface{} //
PostId interface{} // 帖子编号
CreatedAt *gtime.Time // 创建时间
}

View File

@@ -0,0 +1,23 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// CommunityGift is the golang structure of table shiningu_community_gift for DAO operations like Where/Data.
type CommunityGift struct {
g.Meta `orm:"table:shiningu_community_gift, do:true"`
Id interface{} //
Uid interface{} // 收礼玩家编号
FromUid interface{} // 送礼玩家编号
Type interface{} // 送礼类型
Pid interface{} // 帖子编号
ItemId interface{} // 礼物编号
Count interface{} // 礼物数量
CreatedAt *gtime.Time // 创建时间
}

View File

@@ -0,0 +1,16 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
)
// CommunityMenu is the golang structure of table shiningu_community_menu for DAO operations like Where/Data.
type CommunityMenu struct {
g.Meta `orm:"table:shiningu_community_menu, do:true"`
Id interface{} //
Name interface{} // 栏目名称
}

View File

@@ -0,0 +1,25 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// CommunityNotice is the golang structure of table shiningu_community_notice for DAO operations like Where/Data.
type CommunityNotice struct {
g.Meta `orm:"table:shiningu_community_notice, do:true"`
Id interface{} //
Uid interface{} // 用户编号
FromUid interface{} // 对方用户编号
Type interface{} // 类型
Sid interface{} // 来源编号
Content interface{} // 正文
Extend interface{} // 附加属性
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
Status interface{} // 通知状态
}

View File

@@ -0,0 +1,38 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// CommunityPosts is the golang structure of table shiningu_community_posts for DAO operations like Where/Data.
type CommunityPosts struct {
g.Meta `orm:"table:shiningu_community_posts, do:true"`
Id interface{} // 帖子编号
Tid interface{} // 帖子栏目
Uid interface{} // 发布者
Click interface{} // 点击数
LikeCount interface{} // 点赞数量
CollectCount interface{} // 收藏数量
Popularity interface{} // 人气度热度
Charm interface{} // 魅力值
Language interface{} // 语言
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
DeletedAt *gtime.Time // 删除时间
Topic1 interface{} // 话题1
Topic2 interface{} // 话题2
Status interface{} // 帖子状态 -1限流 0 正常
Recommend interface{} // 小编推荐
Extend interface{} // 附加信息
At interface{} // 用户的at功能
Period interface{} // 最新期数
Price interface{} // 当前价格
Index interface{} // 索引编号
Gesture interface{} // 手势
CharacterNum interface{} // 角色数量
}

View File

@@ -0,0 +1,28 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
)
// CommunityPosts0 is the golang structure of table shiningu_community_posts_0 for DAO operations like Where/Data.
type CommunityPosts0 struct {
g.Meta `orm:"table:shiningu_community_posts_0, do:true"`
Id interface{} // 帖子编号
Title interface{} // 标题
Content interface{} // 帖子正文
Images interface{} // 帖子图片批量
Image interface{} // 图片
ImagesRatio interface{} // 图片长宽比
Like interface{} // 点赞
Collect interface{} // 收藏
Extend interface{} // 附加信息
At interface{} // at
Data interface{} // 内容属性
UseIds interface{} // 最新期数
Share interface{} // 分享帖子
AiScore interface{} //
}

View File

@@ -0,0 +1,28 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
)
// CommunityPosts1 is the golang structure of table shiningu_community_posts_1 for DAO operations like Where/Data.
type CommunityPosts1 struct {
g.Meta `orm:"table:shiningu_community_posts_1, do:true"`
Id interface{} // 帖子编号
Title interface{} // 标题
Content interface{} // 帖子正文
Images interface{} // 帖子图片批量
Image interface{} // 图片
ImagesRatio interface{} // 图片长宽比
Like interface{} // 点赞
Collect interface{} // 收藏
Extend interface{} // 附加信息
At interface{} // at
Data interface{} // 内容属性
UseIds interface{} // 最新期数
Share interface{} // 分享帖子
AiScore interface{} //
}

View File

@@ -0,0 +1,17 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
)
// CommunityPostsDetails is the golang structure of table shiningu_community_posts_details for DAO operations like Where/Data.
type CommunityPostsDetails struct {
g.Meta `orm:"table:shiningu_community_posts_details, do:true"`
Id interface{} //
Attachment interface{} // 帖子附件
SlotsImg interface{} // 槽位图片
}

View File

@@ -0,0 +1,17 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// CommunityPostsHotDel is the golang structure of table shiningu_community_posts_hot_del for DAO operations like Where/Data.
type CommunityPostsHotDel struct {
g.Meta `orm:"table:shiningu_community_posts_hot_del, do:true"`
Id interface{} // 帖子编号
CreatedAt *gtime.Time // 创建时间
}

View File

@@ -0,0 +1,19 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// CommunityPostsRecommend is the golang structure of table shiningu_community_posts_recommend for DAO operations like Where/Data.
type CommunityPostsRecommend struct {
g.Meta `orm:"table:shiningu_community_posts_recommend, do:true"`
Pid interface{} // 帖子编号
Type interface{} // 推荐类型
CreatedAt *gtime.Time // 创建时间
EndTime *gtime.Time // 结束时间
}

View File

@@ -0,0 +1,28 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// CommunityPostsReply is the golang structure of table shiningu_community_posts_reply for DAO operations like Where/Data.
type CommunityPostsReply struct {
g.Meta `orm:"table:shiningu_community_posts_reply, do:true"`
Id interface{} // 唯一id
Pid interface{} // 主贴id
Uid interface{} //
Uid2 interface{} // 被回复者的uid
Content interface{} // 正文
Extend interface{} // 附加数据
TopId interface{} // 上级id
CreatedAt *gtime.Time // 创建时间
Sort interface{} // 跟帖顺序
AiScore interface{} // 机器评分
Status interface{} // 状态
At interface{} // 用户的at功能
Like interface{} // 回复点赞
}

View File

@@ -0,0 +1,22 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
)
// CommunityUser is the golang structure of table shiningu_community_user for DAO operations like Where/Data.
type CommunityUser struct {
g.Meta `orm:"table:shiningu_community_user, do:true"`
Uid interface{} //
Like interface{} // 点赞
Like2 interface{} // 帖子回复点赞
Collect interface{} // 收藏
FollowNum interface{} // 关注数量
FansNum interface{} // 粉丝数量
Gift interface{} // 礼物值
Blacklist interface{} // 黑名单
}

View File

@@ -0,0 +1,25 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// ConfigAct is the golang structure of table shiningu_config_act for DAO operations like Where/Data.
type ConfigAct struct {
g.Meta `orm:"table:shiningu_config_act, do:true"`
Id interface{} // 流水编号
Type interface{} // 活动类型
Actid interface{} // 活动编号
Name interface{} // 活动名称
Hid interface{} // 活动标识
Data interface{} // 活动数据
StartTime *gtime.Time // 开始时间
EndTime *gtime.Time // 结束时间
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
}

View File

@@ -0,0 +1,32 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// ConfigModalBox is the golang structure of table shiningu_config_modal_box for DAO operations like Where/Data.
type ConfigModalBox struct {
g.Meta `orm:"table:shiningu_config_modal_box, do:true"`
Id interface{} // 主键
ModalBoxId interface{} // 弹框id
UserType interface{} // 特定用户
Tips interface{} // 弹框tips选项
Name interface{} // 名称
Title interface{} // 标题
Content interface{} // 正文
Type interface{} // 类型
Style interface{} // 样式
Weight interface{} // 权重
Attachments interface{} // 附件
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
Status interface{} // 状态 1开始 0关闭
Notes interface{} // 备注
StartTime *gtime.Time // 开始时间
EndTime *gtime.Time // 结束时间
}

View File

@@ -0,0 +1,19 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// GameAct is the golang structure of table shiningu_game_act for DAO operations like Where/Data.
type GameAct struct {
g.Meta `orm:"table:shiningu_game_act, do:true"`
Uid interface{} // 玩家编号
ActId interface{} // 活动编号
Action interface{} // 活动配置
UpdatedAt *gtime.Time // 更新时间
}

View File

@@ -0,0 +1,18 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
)
// GameBag is the golang structure of table shiningu_game_bag for DAO operations like Where/Data.
type GameBag struct {
g.Meta `orm:"table:shiningu_game_bag, do:true"`
Uid interface{} // 用户标识
List interface{} // 道具数据
Book interface{} // 图鉴
Hand interface{} // 手势
}

View File

@@ -0,0 +1,19 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// GameConfig is the golang structure of table shiningu_game_config for DAO operations like Where/Data.
type GameConfig struct {
g.Meta `orm:"table:shiningu_game_config, do:true"`
Name interface{} // 配置名称
Data interface{} // 配置内容
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
}

View File

@@ -0,0 +1,18 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// GameKv is the golang structure of table shiningu_game_kv for DAO operations like Where/Data.
type GameKv struct {
g.Meta `orm:"table:shiningu_game_kv, do:true"`
Uid interface{} // 用户
Kv interface{} // 变量
UpdatedAt *gtime.Time // 更新时间
}

View File

@@ -0,0 +1,27 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// GameMail is the golang structure of table shiningu_game_mail for DAO operations like Where/Data.
type GameMail struct {
g.Meta `orm:"table:shiningu_game_mail, do:true"`
Id interface{} // 流水
Uid interface{} // 用户标识
Type interface{} // 类型
Title interface{} // 标题
Content interface{} // 正文
Items interface{} // 奖励道具
HaveItems interface{} // 是否有附件
CreatedAt *gtime.Time // 创建时间
Sign interface{} // 署名
EndTime *gtime.Time // 结束时间
Extend interface{} // 附加参数
Status interface{} // 状态
}

View File

@@ -0,0 +1,23 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// GameMailMass is the golang structure of table shiningu_game_mail_mass for DAO operations like Where/Data.
type GameMailMass struct {
g.Meta `orm:"table:shiningu_game_mail_mass, do:true"`
Id interface{} // 主键
Title interface{} // 标题
Type interface{} // 类型
Content interface{} // 正文
CreatedAt *gtime.Time // 创建时间
Items interface{} // 奖励
Sign interface{} // 署名
EndTime *gtime.Time // 结束时间
}

View File

@@ -0,0 +1,16 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
)
// GameMailUser is the golang structure of table shiningu_game_mail_user for DAO operations like Where/Data.
type GameMailUser struct {
g.Meta `orm:"table:shiningu_game_mail_user, do:true"`
Uid interface{} //
Mass interface{} // 群发邮件领取列表
}

View File

@@ -0,0 +1,29 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// GamePay is the golang structure of table shiningu_game_pay for DAO operations like Where/Data.
type GamePay struct {
g.Meta `orm:"table:shiningu_game_pay, do:true"`
OrderId interface{} // 订单编号
Uid interface{} //
TerraceOrderId interface{} // 平台订单id
Device interface{} // 设备名称
Channel interface{} // 支付渠道
ShopId interface{} // 商品id
Cent interface{} // 美分(不要使用小数点)
PackageName interface{} // 包名
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
PayTime *gtime.Time // 支付时间
Status interface{} // 状态
Token interface{} // 支付标识
Ip interface{} // ip地址
}

View File

@@ -0,0 +1,25 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// GameRank is the golang structure of table shiningu_game_rank for DAO operations like Where/Data.
type GameRank struct {
g.Meta `orm:"table:shiningu_game_rank, do:true"`
Key interface{} //
RankId interface{} // 排行榜编号
Type interface{} // 排行榜类型
Data interface{} // 数据
CreatedAt *gtime.Time // 排行榜创建时间
StartTime *gtime.Time // 榜单开始时间
EndTime *gtime.Time // 榜单结束时间
Status interface{} //
Image interface{} // 结算封面
FirstUid interface{} // 第一名的用户id
}

View File

@@ -0,0 +1,20 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
)
// GameStage is the golang structure of table shiningu_game_stage for DAO operations like Where/Data.
type GameStage struct {
g.Meta `orm:"table:shiningu_game_stage, do:true"`
Uid interface{} // 用户标识
Chapter interface{} // 章节
WinData interface{} // 通关过的数据
StageData interface{} // 关卡数据
Star interface{} // 章节获得的总星
RwdData interface{} // 通关奖励领取
}

View File

@@ -0,0 +1,21 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// MemberAuthorize is the golang structure of table shiningu_member_authorize for DAO operations like Where/Data.
type MemberAuthorize struct {
g.Meta `orm:"table:shiningu_member_authorize, do:true"`
Code interface{} // 授权码
Uid interface{} // 用户标识
Type interface{} // 认证方式
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
CreateIp interface{} // 创建ip
}

View File

@@ -0,0 +1,18 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// MemberBan is the golang structure of table shiningu_member_ban for DAO operations like Where/Data.
type MemberBan struct {
g.Meta `orm:"table:shiningu_member_ban, do:true"`
Uid interface{} // 用户编号
CreatedAt *gtime.Time // 禁用时间
Type interface{} // 禁用类型
}

View File

@@ -0,0 +1,18 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// MemberFriend is the golang structure of table shiningu_member_friend for DAO operations like Where/Data.
type MemberFriend struct {
g.Meta `orm:"table:shiningu_member_friend, do:true"`
Uid interface{} // 当前用户
Uid2 interface{} // 对方编号
CreatedAt *gtime.Time // 创建时间
}

View File

@@ -0,0 +1,18 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// MemberLimit is the golang structure of table shiningu_member_limit for DAO operations like Where/Data.
type MemberLimit struct {
g.Meta `orm:"table:shiningu_member_limit, do:true"`
Uid interface{} // 用户uid
CreatedAt *gtime.Time // 创建时间
Data interface{} // 玩家权限
}

View File

@@ -0,0 +1,24 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// MemberSave is the golang structure of table shiningu_member_save for DAO operations like Where/Data.
type MemberSave struct {
g.Meta `orm:"table:shiningu_member_save, do:true"`
Uid interface{} // 用户编号
Type interface{} // 存档类型
Slot interface{} // 存档槽位
Data interface{} // 存档内容
S3 interface{} // s3地址
UpdatedAt *gtime.Time // 更新时间
Name interface{} // 自定义名字
Image interface{} // 上传图片
UseIds interface{} // 使用的道具id
}

View File

@@ -0,0 +1,42 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// MemberUser is the golang structure of table shiningu_member_user for DAO operations like Where/Data.
type MemberUser struct {
g.Meta `orm:"table:shiningu_member_user, do:true"`
Uid interface{} // 用户标识
Guid interface{} // 用户本次登录标识
Gid interface{} // 用户组编号
AccountLogin interface{} // 社交账号登录
CreatedAt *gtime.Time // 创建时间
UpdatedAt *gtime.Time // 更新时间
DeletedAt *gtime.Time // 删除时间
Nickname interface{} // 昵称
Phone interface{} // 绑定手机
Email interface{} // 绑定邮箱
Money interface{} // 充值货币
Save interface{} // 储存路径
Slots interface{} // 槽位数量
OnlineDuration interface{} // 在线时长
OnlineStatus interface{} // 在线状态
OnlineTime *gtime.Time // 上线时间
OfflineTime *gtime.Time // 离线时间
CreateIp interface{} // 创号ip地址
UpdateIp interface{} // 更新IP地址
Level interface{} // 等级
Exp interface{} // 经验
Title interface{} // 称号
Avatar interface{} // 头像
AvatarFrame interface{} // 头像框
Popularity interface{} // 人气度
Charm interface{} // 魅力值
Gift interface{} // 礼物值
}

View File

@@ -0,0 +1,15 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
)
// SystemCron is the golang structure of table shiningu_system_cron for DAO operations like Where/Data.
type SystemCron struct {
g.Meta `orm:"table:shiningu_system_cron, do:true"`
Id interface{} // 编号
}

View File

@@ -0,0 +1,21 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// SystemLog is the golang structure of table shiningu_system_log for DAO operations like Where/Data.
type SystemLog struct {
g.Meta `orm:"table:shiningu_system_log, do:true"`
Id interface{} // 主键
Uid interface{} // 操作的用户
Url interface{} // 当前访问的url
Data interface{} // 操作数据
CreatedAt *gtime.Time // 创建时间
Ip interface{} // 当前ip地址
}

View File

@@ -0,0 +1,23 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
)
// SystemReport is the golang structure of table shiningu_system_report for DAO operations like Where/Data.
type SystemReport struct {
g.Meta `orm:"table:shiningu_system_report, do:true"`
Id interface{} //
Rid interface{} // 举报id
Uid interface{} // 举报人编号
Type interface{} // 举报类型
Desc interface{} // 举报正文
CreatedAt *gtime.Time // 举报时间
DeletedAt *gtime.Time // 删除时间
Status interface{} // 处理状态
}

View File

@@ -0,0 +1,17 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
)
// SystemSetting is the golang structure of table shiningu_system_setting for DAO operations like Where/Data.
type SystemSetting struct {
g.Meta `orm:"table:shiningu_system_setting, do:true"`
Name interface{} // 配置名称
Value interface{} // 配置详情
Type interface{} // 类型
}

View File

@@ -0,0 +1,18 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package do
import (
"github.com/gogf/gf/v2/frame/g"
)
// SystemStatistics is the golang structure of table shiningu_system_statistics for DAO operations like Where/Data.
type SystemStatistics struct {
g.Meta `orm:"table:shiningu_system_statistics, do:true"`
Id interface{} // 流水号
AppId interface{} // 应用编号
Key interface{} // 唯一缓存key
Data interface{} // 数据
}

View File

@@ -0,0 +1,16 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// CommunityFans is the golang structure for table community_fans.
type CommunityFans struct {
Uid int64 `json:"uid" orm:"uid" description:"用户编号"` // 用户编号
Fans int64 `json:"fans" orm:"fans" description:"粉丝编号"` // 粉丝编号
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"关注时间"` // 关注时间
}

View File

@@ -0,0 +1,17 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// CommunityFeeds is the golang structure for table community_feeds.
type CommunityFeeds struct {
Id int `json:"id" orm:"id" description:"流水"` // 流水
Uid int64 `json:"uid" orm:"uid" description:""` //
PostId int `json:"post_id" orm:"post_id" description:"帖子编号"` // 帖子编号
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
}

View File

@@ -0,0 +1,21 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// CommunityGift is the golang structure for table community_gift.
type CommunityGift struct {
Id int `json:"id" orm:"id" description:""` //
Uid int64 `json:"uid" orm:"uid" description:"收礼玩家编号"` // 收礼玩家编号
FromUid int64 `json:"from_uid" orm:"fromUid" description:"送礼玩家编号"` // 送礼玩家编号
Type int `json:"type" orm:"type" description:"送礼类型"` // 送礼类型
Pid int `json:"pid" orm:"pid" description:"帖子编号"` // 帖子编号
ItemId int64 `json:"item_id" orm:"itemId" description:"礼物编号"` // 礼物编号
Count int `json:"count" orm:"count" description:"礼物数量"` // 礼物数量
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
}

View File

@@ -0,0 +1,11 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
// CommunityMenu is the golang structure for table community_menu.
type CommunityMenu struct {
Id int `json:"id" orm:"id" description:""` //
Name string `json:"name" orm:"name" description:"栏目名称"` // 栏目名称
}

View File

@@ -0,0 +1,23 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// CommunityNotice is the golang structure for table community_notice.
type CommunityNotice struct {
Id int `json:"id" orm:"id" description:""` //
Uid int64 `json:"uid" orm:"uid" description:"用户编号"` // 用户编号
FromUid int64 `json:"from_uid" orm:"from_uid" description:"对方用户编号"` // 对方用户编号
Type int `json:"type" orm:"type" description:"类型"` // 类型
Sid int `json:"sid" orm:"sid" description:"来源编号"` // 来源编号
Content string `json:"content" orm:"content" description:"正文"` // 正文
Extend string `json:"extend" orm:"extend" description:"附加属性"` // 附加属性
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
UpdatedAt *gtime.Time `json:"updated_at" orm:"updated_at" description:"更新时间"` // 更新时间
Status int `json:"status" orm:"status" description:"通知状态"` // 通知状态
}

View File

@@ -0,0 +1,36 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// CommunityPosts is the golang structure for table community_posts.
type CommunityPosts struct {
Id int `json:"id" orm:"id" description:"帖子编号"` // 帖子编号
Tid int `json:"tid" orm:"tid" description:"帖子栏目"` // 帖子栏目
Uid int64 `json:"uid" orm:"uid" description:"发布者"` // 发布者
Click int64 `json:"click" orm:"click" description:"点击数"` // 点击数
LikeCount int `json:"like_count" orm:"like_count" description:"点赞数量"` // 点赞数量
CollectCount int `json:"collect_count" orm:"collect_count" description:"收藏数量"` // 收藏数量
Popularity int `json:"popularity" orm:"popularity" description:"人气度热度"` // 人气度热度
Charm int `json:"charm" orm:"charm" description:"魅力值"` // 魅力值
Language string `json:"language" orm:"language" description:"语言"` // 语言
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
UpdatedAt *gtime.Time `json:"updated_at" orm:"updated_at" description:"更新时间"` // 更新时间
DeletedAt *gtime.Time `json:"deleted_at" orm:"deleted_at" description:"删除时间"` // 删除时间
Topic1 int `json:"topic_1" orm:"topic1" description:"话题1"` // 话题1
Topic2 int `json:"topic_2" orm:"topic2" description:"话题2"` // 话题2
Status int `json:"status" orm:"status" description:"帖子状态 -1限流 0 正常"` // 帖子状态 -1限流 0 正常
Recommend int `json:"recommend" orm:"recommend" description:"小编推荐"` // 小编推荐
Extend string `json:"extend" orm:"extend" description:"附加信息"` // 附加信息
At string `json:"at" orm:"at" description:"用户的at功能"` // 用户的at功能
Period int `json:"period" orm:"period" description:"最新期数"` // 最新期数
Price int `json:"price" orm:"price" description:"当前价格"` // 当前价格
Index int `json:"index" orm:"index" description:"索引编号"` // 索引编号
Gesture int `json:"gesture" orm:"gesture" description:"手势"` // 手势
CharacterNum int `json:"character_num" orm:"character_num" description:"角色数量"` // 角色数量
}

View File

@@ -0,0 +1,23 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
// CommunityPosts0 is the golang structure for table community_posts_0.
type CommunityPosts0 struct {
Id int `json:"id" orm:"id" description:"帖子编号"` // 帖子编号
Title string `json:"title" orm:"title" description:"标题"` // 标题
Content string `json:"content" orm:"content" description:"帖子正文"` // 帖子正文
Images string `json:"images" orm:"images" description:"帖子图片批量"` // 帖子图片批量
Image string `json:"image" orm:"image" description:"图片"` // 图片
ImagesRatio string `json:"images_ratio" orm:"images_ratio" description:"图片长宽比"` // 图片长宽比
Like string `json:"like" orm:"like" description:"点赞"` // 点赞
Collect string `json:"collect" orm:"collect" description:"收藏"` // 收藏
Extend string `json:"extend" orm:"extend" description:"附加信息"` // 附加信息
At string `json:"at" orm:"at" description:"at"` // at
Data string `json:"data" orm:"data" description:"内容属性"` // 内容属性
UseIds string `json:"use_ids" orm:"use_ids" description:"最新期数"` // 最新期数
Share string `json:"share" orm:"share" description:"分享帖子"` // 分享帖子
AiScore int `json:"ai_score" orm:"ai_score" description:""` //
}

View File

@@ -0,0 +1,23 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
// CommunityPosts1 is the golang structure for table community_posts_1.
type CommunityPosts1 struct {
Id int `json:"id" orm:"id" description:"帖子编号"` // 帖子编号
Title string `json:"title" orm:"title" description:"标题"` // 标题
Content string `json:"content" orm:"content" description:"帖子正文"` // 帖子正文
Images string `json:"images" orm:"images" description:"帖子图片批量"` // 帖子图片批量
Image string `json:"image" orm:"image" description:"图片"` // 图片
ImagesRatio string `json:"images_ratio" orm:"images_ratio" description:"图片长宽比"` // 图片长宽比
Like string `json:"like" orm:"like" description:"点赞"` // 点赞
Collect string `json:"collect" orm:"collect" description:"收藏"` // 收藏
Extend string `json:"extend" orm:"extend" description:"附加信息"` // 附加信息
At string `json:"at" orm:"at" description:"at"` // at
Data string `json:"data" orm:"data" description:"内容属性"` // 内容属性
UseIds string `json:"use_ids" orm:"use_ids" description:"最新期数"` // 最新期数
Share string `json:"share" orm:"share" description:"分享帖子"` // 分享帖子
AiScore int `json:"ai_score" orm:"ai_score" description:""` //
}

View File

@@ -0,0 +1,12 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
// CommunityPostsDetails is the golang structure for table community_posts_details.
type CommunityPostsDetails struct {
Id int `json:"id" orm:"id" description:""` //
Attachment string `json:"attachment" orm:"attachment" description:"帖子附件"` // 帖子附件
SlotsImg string `json:"slots_img" orm:"slots_img" description:"槽位图片"` // 槽位图片
}

View File

@@ -0,0 +1,15 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// CommunityPostsHotDel is the golang structure for table community_posts_hot_del.
type CommunityPostsHotDel struct {
Id int `json:"id" orm:"id" description:"帖子编号"` // 帖子编号
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
}

View File

@@ -0,0 +1,17 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// CommunityPostsRecommend is the golang structure for table community_posts_recommend.
type CommunityPostsRecommend struct {
Pid int `json:"pid" orm:"pid" description:"帖子编号"` // 帖子编号
Type int `json:"type" orm:"type" description:"推荐类型"` // 推荐类型
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
EndTime *gtime.Time `json:"end_time" orm:"end_time" description:"结束时间"` // 结束时间
}

View File

@@ -0,0 +1,26 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// CommunityPostsReply is the golang structure for table community_posts_reply.
type CommunityPostsReply struct {
Id int `json:"id" orm:"id" description:"唯一id"` // 唯一id
Pid int `json:"pid" orm:"pid" description:"主贴id"` // 主贴id
Uid int64 `json:"uid" orm:"uid" description:""` //
Uid2 int64 `json:"uid_2" orm:"uid2" description:"被回复者的uid"` // 被回复者的uid
Content string `json:"content" orm:"content" description:"正文"` // 正文
Extend string `json:"extend" orm:"extend" description:"附加数据"` // 附加数据
TopId int `json:"top_id" orm:"top_id" description:"上级id"` // 上级id
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
Sort int `json:"sort" orm:"sort" description:"跟帖顺序"` // 跟帖顺序
AiScore float64 `json:"ai_score" orm:"ai_score" description:"机器评分"` // 机器评分
Status int `json:"status" orm:"status" description:"状态"` // 状态
At string `json:"at" orm:"at" description:"用户的at功能"` // 用户的at功能
Like string `json:"like" orm:"like" description:"回复点赞"` // 回复点赞
}

View File

@@ -0,0 +1,17 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
// CommunityUser is the golang structure for table community_user.
type CommunityUser struct {
Uid int64 `json:"uid" orm:"uid" description:""` //
Like string `json:"like" orm:"like" description:"点赞"` // 点赞
Like2 string `json:"like_2" orm:"like2" description:"帖子回复点赞"` // 帖子回复点赞
Collect string `json:"collect" orm:"collect" description:"收藏"` // 收藏
FollowNum int `json:"follow_num" orm:"follow_num" description:"关注数量"` // 关注数量
FansNum int `json:"fans_num" orm:"fans_num" description:"粉丝数量"` // 粉丝数量
Gift int `json:"gift" orm:"gift" description:"礼物值"` // 礼物值
Blacklist string `json:"blacklist" orm:"blacklist" description:"黑名单"` // 黑名单
}

View File

@@ -0,0 +1,23 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// ConfigAct is the golang structure for table config_act.
type ConfigAct struct {
Id int `json:"id" orm:"id" description:"流水编号"` // 流水编号
Type int `json:"type" orm:"type" description:"活动类型"` // 活动类型
Actid int `json:"actid" orm:"actid" description:"活动编号"` // 活动编号
Name string `json:"name" orm:"name" description:"活动名称"` // 活动名称
Hid string `json:"hid" orm:"hid" description:"活动标识"` // 活动标识
Data string `json:"data" orm:"data" description:"活动数据"` // 活动数据
StartTime *gtime.Time `json:"start_time" orm:"start_time" description:"开始时间"` // 开始时间
EndTime *gtime.Time `json:"end_time" orm:"end_time" description:"结束时间"` // 结束时间
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
UpdatedAt *gtime.Time `json:"updated_at" orm:"updated_at" description:"更新时间"` // 更新时间
}

View File

@@ -0,0 +1,30 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// ConfigModalBox is the golang structure for table config_modal_box.
type ConfigModalBox struct {
Id int `json:"id" orm:"id" description:"主键"` // 主键
ModalBoxId int `json:"modal_box_id" orm:"modal_box_id" description:"弹框id"` // 弹框id
UserType string `json:"user_type" orm:"user_type" description:"特定用户"` // 特定用户
Tips string `json:"tips" orm:"tips" description:"弹框tips选项"` // 弹框tips选项
Name string `json:"name" orm:"name" description:"名称"` // 名称
Title string `json:"title" orm:"title" description:"标题"` // 标题
Content string `json:"content" orm:"content" description:"正文"` // 正文
Type int `json:"type" orm:"type" description:"类型"` // 类型
Style string `json:"style" orm:"style" description:"样式"` // 样式
Weight int `json:"weight" orm:"weight" description:"权重"` // 权重
Attachments string `json:"attachments" orm:"attachments" description:"附件"` // 附件
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
UpdatedAt *gtime.Time `json:"updated_at" orm:"updated_at" description:"更新时间"` // 更新时间
Status int `json:"status" orm:"status" description:"状态 1开始 0关闭"` // 状态 1开始 0关闭
Notes string `json:"notes" orm:"notes" description:"备注"` // 备注
StartTime *gtime.Time `json:"start_time" orm:"start_time" description:"开始时间"` // 开始时间
EndTime *gtime.Time `json:"end_time" orm:"end_time" description:"结束时间"` // 结束时间
}

View File

@@ -0,0 +1,17 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// GameAct is the golang structure for table game_act.
type GameAct struct {
Uid int64 `json:"uid" orm:"uid" description:"玩家编号"` // 玩家编号
ActId int `json:"act_id" orm:"act_id" description:"活动编号"` // 活动编号
Action string `json:"action" orm:"action" description:"活动配置"` // 活动配置
UpdatedAt *gtime.Time `json:"updated_at" orm:"updated_at" description:"更新时间"` // 更新时间
}

View File

@@ -0,0 +1,13 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
// GameBag is the golang structure for table game_bag.
type GameBag struct {
Uid int64 `json:"uid" orm:"uid" description:"用户标识"` // 用户标识
List string `json:"list" orm:"list" description:"道具数据"` // 道具数据
Book string `json:"book" orm:"book" description:"图鉴"` // 图鉴
Hand string `json:"hand" orm:"hand" description:"手势"` // 手势
}

View File

@@ -0,0 +1,17 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// GameConfig is the golang structure for table game_config.
type GameConfig struct {
Name string `json:"name" orm:"name" description:"配置名称"` // 配置名称
Data string `json:"data" orm:"data" description:"配置内容"` // 配置内容
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
UpdatedAt *gtime.Time `json:"updated_at" orm:"updated_at" description:"更新时间"` // 更新时间
}

View File

@@ -0,0 +1,16 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// GameKv is the golang structure for table game_kv.
type GameKv struct {
Uid int `json:"uid" orm:"uid" description:"用户"` // 用户
Kv string `json:"kv" orm:"kv" description:"变量"` // 变量
UpdatedAt *gtime.Time `json:"updated_at" orm:"updated_at" description:"更新时间"` // 更新时间
}

View File

@@ -0,0 +1,25 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// GameMail is the golang structure for table game_mail.
type GameMail struct {
Id int64 `json:"id" orm:"id" description:"流水"` // 流水
Uid int64 `json:"uid" orm:"uid" description:"用户标识"` // 用户标识
Type int `json:"type" orm:"type" description:"类型"` // 类型
Title string `json:"title" orm:"title" description:"标题"` // 标题
Content string `json:"content" orm:"content" description:"正文"` // 正文
Items string `json:"items" orm:"items" description:"奖励道具"` // 奖励道具
HaveItems bool `json:"have_items" orm:"have_items" description:"是否有附件"` // 是否有附件
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
Sign string `json:"sign" orm:"sign" description:"署名"` // 署名
EndTime *gtime.Time `json:"end_time" orm:"end_time" description:"结束时间"` // 结束时间
Extend string `json:"extend" orm:"extend" description:"附加参数"` // 附加参数
Status int `json:"status" orm:"status" description:"状态"` // 状态
}

View File

@@ -0,0 +1,21 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// GameMailMass is the golang structure for table game_mail_mass.
type GameMailMass struct {
Id int `json:"id" orm:"id" description:"主键"` // 主键
Title string `json:"title" orm:"title" description:"标题"` // 标题
Type int `json:"type" orm:"type" description:"类型"` // 类型
Content string `json:"content" orm:"content" description:"正文"` // 正文
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
Items string `json:"items" orm:"items" description:"奖励"` // 奖励
Sign string `json:"sign" orm:"sign" description:"署名"` // 署名
EndTime *gtime.Time `json:"end_time" orm:"end_time" description:"结束时间"` // 结束时间
}

View File

@@ -0,0 +1,11 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
// GameMailUser is the golang structure for table game_mail_user.
type GameMailUser struct {
Uid int64 `json:"uid" orm:"uid" description:""` //
Mass string `json:"mass" orm:"mass" description:"群发邮件领取列表"` // 群发邮件领取列表
}

View File

@@ -0,0 +1,27 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// GamePay is the golang structure for table game_pay.
type GamePay struct {
OrderId string `json:"order_id" orm:"order_id" description:"订单编号"` // 订单编号
Uid int64 `json:"uid" orm:"uid" description:""` //
TerraceOrderId string `json:"terrace_order_id" orm:"terrace_order_id" description:"平台订单id"` // 平台订单id
Device string `json:"device" orm:"device" description:"设备名称"` // 设备名称
Channel string `json:"channel" orm:"channel" description:"支付渠道"` // 支付渠道
ShopId int64 `json:"shop_id" orm:"shop_id" description:"商品id"` // 商品id
Cent int `json:"cent" orm:"cent" description:"美分(不要使用小数点)"` // 美分(不要使用小数点)
PackageName string `json:"package_name" orm:"package_name" description:"包名"` // 包名
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
UpdatedAt *gtime.Time `json:"updated_at" orm:"updated_at" description:"更新时间"` // 更新时间
PayTime *gtime.Time `json:"pay_time" orm:"pay_time" description:"支付时间"` // 支付时间
Status int `json:"status" orm:"status" description:"状态"` // 状态
Token string `json:"token" orm:"token" description:"支付标识"` // 支付标识
Ip string `json:"ip" orm:"ip" description:"ip地址"` // ip地址
}

View File

@@ -0,0 +1,23 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// GameRank is the golang structure for table game_rank.
type GameRank struct {
Key int `json:"key" orm:"key" description:""` //
RankId int `json:"rank_id" orm:"rank_id" description:"排行榜编号"` // 排行榜编号
Type int `json:"type" orm:"type" description:"排行榜类型"` // 排行榜类型
Data string `json:"data" orm:"data" description:"数据"` // 数据
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"排行榜创建时间"` // 排行榜创建时间
StartTime *gtime.Time `json:"start_time" orm:"start_time" description:"榜单开始时间"` // 榜单开始时间
EndTime *gtime.Time `json:"end_time" orm:"end_time" description:"榜单结束时间"` // 榜单结束时间
Status int `json:"status" orm:"status" description:""` //
Image string `json:"image" orm:"image" description:"结算封面"` // 结算封面
FirstUid int64 `json:"first_uid" orm:"first_uid" description:"第一名的用户id"` // 第一名的用户id
}

View File

@@ -0,0 +1,15 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
// GameStage is the golang structure for table game_stage.
type GameStage struct {
Uid int64 `json:"uid" orm:"uid" description:"用户标识"` // 用户标识
Chapter int `json:"chapter" orm:"chapter" description:"章节"` // 章节
WinData string `json:"win_data" orm:"win_data" description:"通关过的数据"` // 通关过的数据
StageData string `json:"stage_data" orm:"stage_data" description:"关卡数据"` // 关卡数据
Star int `json:"star" orm:"star" description:"章节获得的总星"` // 章节获得的总星
RwdData string `json:"rwd_data" orm:"rwd_data" description:"通关奖励领取"` // 通关奖励领取
}

View File

@@ -0,0 +1,19 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// MemberAuthorize is the golang structure for table member_authorize.
type MemberAuthorize struct {
Code string `json:"code" orm:"code" description:"授权码"` // 授权码
Uid int64 `json:"uid" orm:"uid" description:"用户标识"` // 用户标识
Type string `json:"type" orm:"type" description:"认证方式"` // 认证方式
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
UpdatedAt *gtime.Time `json:"updated_at" orm:"updated_at" description:"更新时间"` // 更新时间
CreateIp string `json:"create_ip" orm:"create_ip" description:"创建ip"` // 创建ip
}

View File

@@ -0,0 +1,16 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// MemberBan is the golang structure for table member_ban.
type MemberBan struct {
Uid int64 `json:"uid" orm:"uid" description:"用户编号"` // 用户编号
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"禁用时间"` // 禁用时间
Type int `json:"type" orm:"type" description:"禁用类型"` // 禁用类型
}

View File

@@ -0,0 +1,16 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// MemberFriend is the golang structure for table member_friend.
type MemberFriend struct {
Uid int64 `json:"uid" orm:"uid" description:"当前用户"` // 当前用户
Uid2 int64 `json:"uid_2" orm:"uid2" description:"对方编号"` // 对方编号
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
}

View File

@@ -0,0 +1,16 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// MemberLimit is the golang structure for table member_limit.
type MemberLimit struct {
Uid int64 `json:"uid" orm:"uid" description:"用户uid"` // 用户uid
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
Data string `json:"data" orm:"data" description:"玩家权限"` // 玩家权限
}

View File

@@ -0,0 +1,22 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// MemberSave is the golang structure for table member_save.
type MemberSave struct {
Uid int64 `json:"uid" orm:"uid" description:"用户编号"` // 用户编号
Type int `json:"type" orm:"type" description:"存档类型"` // 存档类型
Slot int `json:"slot" orm:"slot" description:"存档槽位"` // 存档槽位
Data string `json:"data" orm:"data" description:"存档内容"` // 存档内容
S3 string `json:"s_3" orm:"s3" description:"s3地址"` // s3地址
UpdatedAt *gtime.Time `json:"updated_at" orm:"updated_at" description:"更新时间"` // 更新时间
Name string `json:"name" orm:"name" description:"自定义名字"` // 自定义名字
Image string `json:"image" orm:"image" description:"上传图片"` // 上传图片
UseIds string `json:"use_ids" orm:"use_ids" description:"使用的道具id"` // 使用的道具id
}

View File

@@ -0,0 +1,40 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// MemberUser is the golang structure for table member_user.
type MemberUser struct {
Uid int64 `json:"uid" orm:"uid" description:"用户标识"` // 用户标识
Guid string `json:"guid" orm:"guid" description:"用户本次登录标识"` // 用户本次登录标识
Gid int `json:"gid" orm:"gid" description:"用户组编号"` // 用户组编号
AccountLogin string `json:"account_login" orm:"account_login" description:"社交账号登录"` // 社交账号登录
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
UpdatedAt *gtime.Time `json:"updated_at" orm:"updated_at" description:"更新时间"` // 更新时间
DeletedAt *gtime.Time `json:"deleted_at" orm:"deleted_at" description:"删除时间"` // 删除时间
Nickname string `json:"nickname" orm:"nickname" description:"昵称"` // 昵称
Phone string `json:"phone" orm:"phone" description:"绑定手机"` // 绑定手机
Email string `json:"email" orm:"email" description:"绑定邮箱"` // 绑定邮箱
Money int64 `json:"money" orm:"money" description:"充值货币"` // 充值货币
Save string `json:"save" orm:"save" description:"储存路径"` // 储存路径
Slots string `json:"slots" orm:"slots" description:"槽位数量"` // 槽位数量
OnlineDuration int64 `json:"online_duration" orm:"online_duration" description:"在线时长"` // 在线时长
OnlineStatus int `json:"online_status" orm:"online_status" description:"在线状态"` // 在线状态
OnlineTime *gtime.Time `json:"online_time" orm:"online_time" description:"上线时间"` // 上线时间
OfflineTime *gtime.Time `json:"offline_time" orm:"offline_time" description:"离线时间"` // 离线时间
CreateIp string `json:"create_ip" orm:"create_ip" description:"创号ip地址"` // 创号ip地址
UpdateIp string `json:"update_ip" orm:"update_ip" description:"更新IP地址"` // 更新IP地址
Level int `json:"level" orm:"level" description:"等级"` // 等级
Exp int64 `json:"exp" orm:"exp" description:"经验"` // 经验
Title string `json:"title" orm:"title" description:"称号"` // 称号
Avatar string `json:"avatar" orm:"avatar" description:"头像"` // 头像
AvatarFrame int `json:"avatar_frame" orm:"avatar_frame" description:"头像框"` // 头像框
Popularity int `json:"popularity" orm:"popularity" description:"人气度"` // 人气度
Charm int `json:"charm" orm:"charm" description:"魅力值"` // 魅力值
Gift int `json:"gift" orm:"gift" description:"礼物值"` // 礼物值
}

View File

@@ -0,0 +1,10 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
// SystemCron is the golang structure for table system_cron.
type SystemCron struct {
Id int `json:"id" orm:"id" description:"编号"` // 编号
}

View File

@@ -0,0 +1,19 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// SystemLog is the golang structure for table system_log.
type SystemLog struct {
Id int `json:"id" orm:"id" description:"主键"` // 主键
Uid int `json:"uid" orm:"uid" description:"操作的用户"` // 操作的用户
Url string `json:"url" orm:"url" description:"当前访问的url"` // 当前访问的url
Data string `json:"data" orm:"data" description:"操作数据"` // 操作数据
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"创建时间"` // 创建时间
Ip string `json:"ip" orm:"ip" description:"当前ip地址"` // 当前ip地址
}

View File

@@ -0,0 +1,21 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
import (
"github.com/gogf/gf/v2/os/gtime"
)
// SystemReport is the golang structure for table system_report.
type SystemReport struct {
Id int `json:"id" orm:"id" description:""` //
Rid int `json:"rid" orm:"rid" description:"举报id"` // 举报id
Uid int `json:"uid" orm:"uid" description:"举报人编号"` // 举报人编号
Type int `json:"type" orm:"type" description:"举报类型"` // 举报类型
Desc string `json:"desc" orm:"desc" description:"举报正文"` // 举报正文
CreatedAt *gtime.Time `json:"created_at" orm:"created_at" description:"举报时间"` // 举报时间
DeletedAt *gtime.Time `json:"deleted_at" orm:"deleted_at" description:"删除时间"` // 删除时间
Status int `json:"status" orm:"status" description:"处理状态"` // 处理状态
}

View File

@@ -0,0 +1,12 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
// SystemSetting is the golang structure for table system_setting.
type SystemSetting struct {
Name string `json:"name" orm:"name" description:"配置名称"` // 配置名称
Value string `json:"value" orm:"value" description:"配置详情"` // 配置详情
Type int `json:"type" orm:"type" description:"类型"` // 类型
}

View File

@@ -0,0 +1,13 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package entity
// SystemStatistics is the golang structure for table system_statistics.
type SystemStatistics struct {
Id int `json:"id" orm:"id" description:"流水号"` // 流水号
AppId int `json:"app_id" orm:"app_id" description:"应用编号"` // 应用编号
Key string `json:"key" orm:"key" description:"唯一缓存key"` // 唯一缓存key
Data string `json:"data" orm:"data" description:"数据"` // 数据
}

View File

@@ -0,0 +1,25 @@
syntax = "proto3";
package system;
option go_package = "github.com/ayflying/utility_go/api/system/v1";
// 定义 CronType 计划任务 枚举
enum CronType {
UNKNOWN = 0; // 未知类型
SECOND = 1; // 每秒触发一次
MINUTE = 2; // 每分钟触发一次
HOUR = 3; // 每小时触发一次
DAILY = 4; // 每天触发一次
WEEK = 5; // 每周触发一次
MONTH = 6; // 每月触发一次
YEAR = 7; // 每年触发一次
MONDAY = 8; // 每周一触发一次
TUESDAY = 9; // 每周二触发一次
WEDNESDAY = 10; // 每周三触发一次
THURSDAY = 11; // 每周四触发一次
FRIDAY = 12; // 每周五触发一次
SATURDAY = 13; // 每周六触发一次
SUNDAY = 14; // 每周日触发一次
}

42
pay/alipay.go Normal file
View File

@@ -0,0 +1,42 @@
package pay
import (
"github.com/go-pay/gopay"
"github.com/go-pay/gopay/alipay"
"github.com/gogf/gf/v2/frame/g"
)
type AliPay struct {
Client *alipay.Client
}
func Alipay() *AliPay {
var pay = &AliPay{}
var err error
cfg, err := g.Cfg().Get(ctx, "pay.alipay")
cfgMap := cfg.MapStrStr()
appId := cfgMap["appid"]
privateKey := cfgMap["privateKey"]
isProd, _ := g.Cfg().Get(ctx, "pay.alipay.isProd")
// 初始化支付宝客户端
// appid应用ID
// privateKey应用私钥支持PKCS1和PKCS8
// isProd是否是正式环境沙箱环境请选择新版沙箱应用。
pay.Client, err = alipay.NewClient(appId, privateKey, isProd.Bool())
if err != nil {
g.Log().Error(ctx, err)
return nil
}
// 自定义配置http请求接收返回结果body大小默认 10MB
//pay.Client.SetBodySize() // 没有特殊需求,可忽略此配置
// 打开Debug开关输出日志默认关闭
pay.Client.DebugSwitch = gopay.DebugOn
pay.Client.SetCharset(alipay.UTF8). // 设置字符编码,不设置默认 utf-8
SetSignType(alipay.RSA2) // 设置签名类型,不设置默认 RSA2
return pay
}

156
pay/apple.go Normal file
View File

@@ -0,0 +1,156 @@
package pay
import (
"context"
"github.com/go-pay/gopay/apple"
"github.com/gogf/gf/v2/errors/gerror"
"strings"
"sync"
"time"
)
// ApplePay 苹果支付
// 这是一个用于处理苹果支付的结构体。
type ApplePay struct {
pass string // pass 是用于苹果支付过程中的密钥。
lock sync.RWMutex // lock 用于确保在并发访问或修改 pass 时的安全性。
}
// Init 是ApplePay类型的初始化函数。
//
// @Description: 对ApplePay对象进行初始化将传入的数据存储到对象中。
// @receiver p: ApplePay对象的指针用于接收初始化操作。
// @param data: 一个字节切片,包含需要初始化的数据。
func (p *ApplePay) Init(data []byte) {
p.lock.Lock() // 加锁以保证在多线程环境下的线程安全
defer p.lock.Unlock() // 确保在函数执行完毕退出时自动解锁,避免死锁
p.pass = string(data) // 将传入的字节切片数据转换为字符串并赋值给pass字段
}
// VerifyPay 验证苹果支付
//
// @Description: 验证苹果支付的收据信息,以确认支付的有效性。
// @receiver p *ApplePay: ApplePay对象用于执行验证支付的操作。
// @param userId uint64: 用户ID。
// @param OrderId string: 订单ID。
// @param package1 string: 付费产品的包装名称。
// @param subscriptionID string: 订阅ID。
// @param purchaseToken string: 购买令牌,用于苹果服务器的收据验证。
// @param isDebug bool: 是否为调试模式决定使用哪个验证URL。
// @param cb func(string) error: 回调函数用于处理验证成功后的产品ID。
// @return error: 返回错误信息,如果验证过程中出现错误,则返回相应的错误信息。
func (p *ApplePay) VerifyPay(userId uint64, OrderId, package1, subscriptionID, purchaseToken string, isDebug bool, cb func(string) error) error {
p.lock.RLock() // 加读锁,保证并发安全
defer p.lock.RUnlock() // 解读锁,确保函数执行完毕后释放锁
// 根据是否为调试模式选择验证URL
url := apple.UrlProd
if isDebug {
url = apple.UrlSandbox
}
// 向苹果服务器验证收据
info, err := apple.VerifyReceipt(context.Background(), url, p.pass, purchaseToken)
if err != nil {
// 如果验证失败,则返回错误
return err
}
// 检查收据验证的状态
if info.Status == 0 {
// 检查收据中是否包含内购信息
if len(info.Receipt.InApp) <= 0 {
return gerror.Wrap(err, "info.Receipt.InApp = 0")
}
// 调用回调函数处理商品ID
if err := cb(info.Receipt.InApp[0].ProductId); err != nil {
// 如果回调处理失败,则返回错误
return err
}
} else {
// 如果收据验证状态异常,则返回状态错误信息
return gerror.Wrapf(err, "status err = %v", info.Status)
}
return nil
}
// VerifyPayV1 验证苹果支付的交易
//
// @Description:
// @receiver p
// @param purchaseToken
// @param isDebug
// @param cb
// @return error
func (p *ApplePay) VerifyPayV1(purchaseToken string, isDebug bool, cb func(string, string) error) error {
p.lock.RLock() // 加读锁,确保并发安全
defer p.lock.RUnlock() // 结束时自动释放读锁
// 根据调试模式选择验证服务的URL
url := apple.UrlProd
if isDebug {
url = apple.UrlSandbox
}
// 向苹果服务器验证收据
info, err := apple.VerifyReceipt(context.Background(), url, p.pass, purchaseToken)
if err != nil {
// 验证失败,返回错误
return err
}
// 检查验证结果状态
if info.Status == 0 {
// 验证成功,检查收据中是否有内购信息
if len(info.Receipt.InApp) <= 0 {
// 收据中无内购信息,返回错误
return gerror.Wrap(err, "info.Receipt.InApp = 0")
}
// 调用回调函数,处理内购产品信息
if err := cb(info.Receipt.InApp[0].ProductId, info.Receipt.InApp[0].OriginalTransactionId); err != nil {
// 回调函数执行失败,返回错误
return gerror.Wrap(err, "回调函数执行失败")
}
} else {
// 验证结果状态异常,返回错误
return gerror.Wrapf(err, "status err = %v", info.Status)
}
// 验证成功返回nil
return nil
}
// VerifyPayTest 用于验证苹果支付的测试购买。
//
// @Description:
// @receiver p
// @param purchaseToken
// @return interface{}
// @return error
func (p *ApplePay) VerifyPayTest(purchaseToken string) (interface{}, error) {
// 使用沙箱环境的URL进行验证
url := apple.UrlSandbox
// 调用apple.VerifyReceipt进行收据验证
return apple.VerifyReceipt(context.Background(), url, p.pass, purchaseToken)
}
// GetTime 根据提供的 timer 字符串解析时间,格式为 "YYYY-MM-DD HH:MM:SS ZZZ",若解析失败则返回当前时间
//
// @Description: 根据指定格式解析时间字符串,如果解析失败或者格式不正确,则返回当前时间。
// @param timer 时间字符串,格式为 "YYYY-MM-DD HH:MM:SS ZZZ",其中 ZZZ 为时区标识。
// @return time.Time 解析得到的时间,若失败则返回当前时间。
func GetTime(timer string) time.Time {
// 将 timer 字符串按空格分割为年月日和时分秒两部分
ts := strings.Split(timer, "")
// 如果分割后的数组长度不为3则说明格式不正确返回当前时间
if len(ts) != 3 {
return time.Now()
}
// 尝试加载指定时区信息
location, err := time.LoadLocation(ts[2])
// 如果加载时区失败,则返回当前时间
if err != nil {
return time.Now()
}
// 使用指定时区解析时间字符串
t, err := time.ParseInLocation("2006-01-02 15:04:05 MST", ts[0]+" "+ts[1], location)
// 如果解析失败,则返回当前时间
if err != nil {
return time.Now()
}
// 将解析得到的时间转换为本地时间并返回
return t.In(time.Local)
}

668
pay/apple/apple.go Normal file
View File

@@ -0,0 +1,668 @@
package apple
import (
"bytes"
"context"
"crypto/tls"
"encoding/json"
"encoding/xml"
"errors"
"fmt"
"io"
"mime/multipart"
"net/http"
"net/url"
"sort"
"strings"
"time"
)
var (
MarshalErr = errors.New("marshal error")
UnmarshalErr = errors.New("unmarshal error")
)
const (
// is the URL when testing your app in the sandbox and while your application is in review
UrlSandbox = "https://sandbox.itunes.apple.com/verifyReceipt"
// is the URL when your app is live in the App Store
UrlProd = "https://buy.itunes.apple.com/verifyReceipt"
)
type RequestType string
const (
GET = "GET"
POST = "POST"
PUT = "PUT"
DELETE = "DELETE"
PATCH = "PATCH"
TypeJSON RequestType = "json"
TypeXML RequestType = "xml"
TypeUrlencoded RequestType = "urlencoded"
TypeForm RequestType = "form"
TypeFormData RequestType = "form-data"
TypeMultipartFormData RequestType = "multipart-form-data"
)
var types = map[RequestType]string{
TypeJSON: "application/json",
TypeXML: "application/xml",
TypeUrlencoded: "application/x-www-form-urlencoded",
TypeForm: "application/x-www-form-urlencoded",
TypeFormData: "application/x-www-form-urlencoded",
TypeMultipartFormData: "multipart/form-data",
}
type File struct {
Name string `json:"name"`
Content []byte `json:"content"`
}
type Client struct {
HttpClient *http.Client
Transport *http.Transport
Header http.Header
Timeout time.Duration
Host string
bodySize int // body size limit(MB), default is 10MB
url string
method string
requestType RequestType
FormString string
ContentType string
unmarshalType string
multipartBodyMap map[string]any
jsonByte []byte
err error
}
// VerifyRequest 校验请求体
// https://developer.apple.com/documentation/appstorereceipts/requestbody
type VerifyRequest struct {
// Receipt app解析出的票据信息
Receipt string `json:"receipt-data"`
// Password App的秘钥
Password string `json:"password"`
// ExcludeOldTranscations Set this value to true for the response to include only the latest renewal transaction for any subscriptions. Use this field only for app receipts that contain auto-renewable subscriptions.
ExcludeOldTranscations bool `json:"exclude-old-transactions"`
}
// VerifyResponse 校验响应体
// https://developer.apple.com/documentation/appstorereceipts/responsebody
type VerifyResponse struct {
// Environment is which the receipt was generated. Possible values: Sandbox, Production
Environment string `json:"environment"`
// IsRetryable is an indicator that an error occurred during the request. A value of 1 indicates a temporary issue; retry validation for this receipt at a later time. A value of 0 indicates an unresolvable issue; do not retry validation for this receipt. Only applicable to status codes 21100-21199.
IsRetryable bool `json:"is-retryable"`
// LatestReceipt The latest Base64 encoded app receipt. Only returned for receipts that contain auto-renewable subscriptions
LatestReceipt string `json:"latest_receipt,omitempty"`
// LatestReceiptInfo is an array that contains all in-app purchase transactions. This excludes transactions for consumable products that have been marked as finished by your app. Only returned for receipts that contain auto-renewable subscriptions.
LatestReceiptInfo []*LatestReceiptInfo `json:"latest_receipt_info,omitempty"`
// PendingRenewalInfo ,in the JSON file, an array where each element contains the pending renewal information for each auto-renewable subscription identified by the product_id. Only returned for app receipts that contain auto-renewable subscriptions.
PendingRenewalInfo []*PendingRenewalInfo `json:"pending_renewal_info,omitempty"`
// Receipt is a JSON representation of the receipt that was sent for verification.
Receipt *Receipt `json:"receipt,omitempty"`
// Status either 0 if the receipt is valid, or a status code if there is an error. The status code reflects the status of the app receipt as a whole. See status for possible status codes and descriptions.
// =0时就表示校验成功
Status int `json:"status"`
}
// LatestReceiptInfo
// https://developer.apple.com/documentation/appstorereceipts/responsebody/latest_receipt_info
type LatestReceiptInfo struct {
// The time Apple customer support canceled a transaction, in a date-time format similar to the ISO 8601. This field is only present for refunded transactions.
CancellationDate string `json:"cancellation_date"`
// The time Apple customer support canceled a transaction, or the time an auto-renewable subscription plan was upgraded, in UNIX epoch time format, in milliseconds. This field is only present for refunded transactions. Use this time format for processing dates.
// https://developer.apple.com/documentation/appstorereceipts/cancellation_date_ms
CancellationDateTimestamp string `json:"cancellation_date_ms"`
// The time Apple customer support canceled a transaction, in the Pacific Time zone. This field is only present for refunded transactions.
CancellationDatePST string `json:"cancellation_date_pst"`
// The reason for a refunded transaction. When a customer cancels a transaction, the App Store gives them a refund and provides a value for this key. A value of “1” indicates that the customer canceled their transaction due to an actual or perceived issue within your app. A value of “0” indicates that the transaction was canceled for another reason; for example, if the customer made the purchase accidentally.
// Possible values: 1, 0
CancellationReason string `json:"cancellation_reason"`
// The time a subscription expires or when it will renew, in a date-time format similar to the ISO 8601.
ExpiresDate string `json:"expires_date"`
// The time a subscription expires or when it will renew, in UNIX epoch time format, in milliseconds. Use this time format for processing dates.
// https://developer.apple.com/documentation/appstorereceipts/expires_date_ms
ExpiresDateTimestamp string `json:"expires_date_ms"`
// The time a subscription expires or when it will renew, in the Pacific Time zone.
ExpiresDatePST string `json:"expires_date_pst"`
// A value that indicates whether the user is the purchaser of the product, or is a family member with access to the product through Family Sharing.
// https://developer.apple.com/documentation/appstorereceipts/in_app_ownership_type
InAppOwnershipType string `json:"in_app_ownership_type"`
// An indicator of whether an auto-renewable subscription is in the introductory price period.
// Possible values: true, false
IsInIntroOfferPeriod string `json:"is_in_intro_offer_period"`
// An indicator of whether a subscription is in the free trial period.
// https://developer.apple.com/documentation/appstorereceipts/is_trial_period
IsTrialPeriod string `json:"is_trial_period"`
// An indicator that a subscription has been canceled due to an upgrade. This field is only present for upgrade transactions.
// Value: true
IsUpgraded string `json:"is_upgraded"`
// The reference name of a subscription offer that you configured in App Store Connect. This field is present when a customer redeemed a subscription offer code. For more information about offer codes
// https://help.apple.com/app-store-connect/#/dev6a098e4b1
// https://developer.apple.com/documentation/storekit/original_api_for_in-app_purchase/subscriptions_and_offers/implementing_offer_codes_in_your_app
OfferCodeRefName string `json:"offer_code_ref_name"`
// The time of the original app purchase, in a date-time format similar to ISO 8601.
OriginalPurchaseDate string `json:"original_purchase_date"`
// The time of the original app purchase, in UNIX epoch time format, in milliseconds. Use this time format for processing dates. For an auto-renewable subscription, this value indicates the date of the subscriptions initial purchase. The original purchase date applies to all product types and remains the same in all transactions for the same product ID. This value corresponds to the original transactions transactionDate property in StoreKit.
OriginalPurchaseDateTimestamp string `json:"original_purchase_date_ms"`
// The time of the original app purchase, in the Pacific Time zone.
OriginalPurchaseDatePST string `json:"original_purchase_date_pst"`
// The transaction identifier of the original purchase.
// https://developer.apple.com/documentation/appstorereceipts/original_transaction_id
OriginalTransactionId string `json:"original_transaction_id"`
// The unique identifier of the product purchased. You provide this value when creating the product in App Store Connect, and it corresponds to the productIdentifier property of the SKPayment object stored in the transactions payment property.
ProductId string `json:"product_id"`
// The identifier of the subscription offer redeemed by the user.
// https://developer.apple.com/documentation/appstorereceipts/promotional_offer_id
PromotionalOfferId string `json:"promotional_offer_id"`
// The time the App Store charged the users account for a purchased or restored product, or the time the App Store charged the users account for a subscription purchase or renewal after a lapse, in a date-time format similar to ISO 8601.
PurchaseDate string `json:"purchase_date"`
// For consumable, non-consumable, and non-renewing subscription products, the time the App Store charged the users account for a purchased or restored product, in the UNIX epoch time format, in milliseconds. For auto-renewable subscriptions, the time the App Store charged the users account for a subscription purchase or renewal after a lapse, in the UNIX epoch time format, in milliseconds. Use this time format for processing dates.
PurchaseDateTimestamp string `json:"purchase_date_ms"`
// The time the App Store charged the users account for a purchased or restored product, or the time the App Store charged the users account for a subscription purchase or renewal after a lapse, in the Pacific Time zone.
PurchaseDatePST string `json:"purchase_date_pst"`
// The number of consumable products purchased. This value corresponds to the quantity property of the SKPayment object stored in the transactions payment property. The value is usually “1” unless modified with a mutable payment. The maximum value is 10.
Quantity string `json:"quantity"`
// The identifier of the subscription group to which the subscription belongs. The value for this field is identical to the subscriptionGroupIdentifier property in SKProduct.
// https://developer.apple.com/documentation/storekit/skproduct/2981047-subscriptiongroupidentifier
SubscriptionGroupIdentifier string `json:"subscription_group_identifier"`
// A unique identifier for purchase events across devices, including subscription-renewal events. This value is the primary key for identifying subscription purchases.
WebOrderLineItemId string `json:"web_order_line_item_id"`
// A unique identifier for a transaction such as a purchase, restore, or renewal
TransactionId string `json:"transaction_id"`
// https://developer.apple.com/documentation/appstorereceipts/app_account_token
AppAccountToken string `json:"app_account_token"`
}
// PendingRenewalInfo
// https://developer.apple.com/documentation/appstorereceipts/responsebody/pending_renewal_info
type PendingRenewalInfo struct {
// The value for this key corresponds to the productIdentifier property of the product that the customers subscription renews.
AutoRenewProductId string `json:"auto_renew_product_id"`
// The current renewal status for the auto-renewable subscription.
// https://developer.apple.com/documentation/appstorereceipts/auto_renew_status
AutoRenewStatus string `json:"auto_renew_status"`
// The reason a subscription expired. This field is only present for a receipt that contains an expired auto-renewable subscription.
// https://developer.apple.com/documentation/appstorereceipts/expiration_intent
ExpirationIntent string `json:"expiration_intent"`
// The time at which the grace period for subscription renewals expires, in a date-time format similar to the ISO 8601.
GracePeriodExpiresDate string `json:"grace_period_expires_date"`
// The time at which the grace period for subscription renewals expires, in UNIX epoch time format, in milliseconds. This key is only present for apps that have Billing Grace Period enabled and when the user experiences a billing error at the time of renewal. Use this time format for processing dates.
GracePeriodExpiresDateTimestamp string `json:"grace_period_expires_date_ms"`
// The time at which the grace period for subscription renewals expires, in the Pacific Time zone.
GracePeriodExpiresDatePST string `json:"grace_period_expires_date_pst"`
// A flag that indicates Apple is attempting to renew an expired subscription automatically. This field is only present if an auto-renewable subscription is in the billing retry state.
// https://developer.apple.com/documentation/appstorereceipts/is_in_billing_retry_period
IsInBillingRetryPeriod string `json:"is_in_billing_retry_period"`
// The reference name of a subscription offer that you configured in App Store Connect. This field is present when a customer redeemed a subscription offer code
// https://developer.apple.com/documentation/appstorereceipts/offer_code_ref_name
OfferCodeRefName string `json:"offer_code_ref_name"`
// The transaction identifier of the original purchase.
OriginalTransactionId string `json:"original_transaction_id"`
// The price consent status for a subscription price increase. This field is only present if the customer was notified of the price increase. The default value is "0" and changes to "1" if the customer consents.
// Possible values: 1, 0
PriceConsentStatus string `json:"price_consent_status"`
// The unique identifier of the product purchased. You provide this value when creating the product in App Store Connect, and it corresponds to the productIdentifier property of the SKPayment object stored in the transaction's payment property.
// https://developer.apple.com/documentation/storekit/skpayment
ProductId string `json:"product_id"`
// The identifier of the promotional offer for an auto-renewable subscription that the user redeemed. You provide this value in the Promotional Offer Identifier field when you create the promotional offer in App Store Connect.
// https://developer.apple.com/documentation/appstorereceipts/promotional_offer_id
Promotionalofferid string `json:"promotional_offer_id"`
}
// Receipt is the decoded version of the encoded receipt data sent with the request to the App Store
// https://developer.apple.com/documentation/appstorereceipts/responsebody/receipt
type Receipt struct {
// See app_item_id.
AdamId int64 `json:"adam_id"`
// Generated by App Store Connect and used by the App Store to uniquely identify the app purchased. Apps are assigned this identifier only in production. Treat this value as a 64-bit long integer.
AppItemId int64 `json:"app_item_id"`
// The apps version number. The app's version number corresponds to the value of CFBundleVersion (in iOS) or CFBundleShortVersionString (in macOS) in the Info.plist. In production, this value is the current version of the app on the device based on the receipt_creation_date_ms. In the sandbox, the value is always "1.0".
ApplicationVersion string `json:"application_version"`
// The bundle identifier for the app to which the receipt belongs. You provide this string on App Store Connect. This corresponds to the value of CFBundleIdentifier in the Info.plist file of the app.
BundleId string `json:"bundle_id"`
// A unique identifier for the app download transaction.
DownloadId int64 `json:"download_id"`
// The time the receipt expires for apps purchased through the Volume Purchase Program, in a date-time format similar to the ISO 8601.
ExpirationDate string `json:"expiration_date"`
// The time the receipt expires for apps purchased through the Volume Purchase Program, in UNIX epoch time format, in milliseconds. If this key is not present for apps purchased through the Volume Purchase Program, the receipt does not expire. Use this time format for processing dates.
ExpirationDateTimestamp string `json:"expiration_date_ms"`
// The time the receipt expires for apps purchased through the Volume Purchase Program, in the Pacific Time zone.
ExpirationDatePST string `json:"expiration_date_pst"`
// An array that contains the in-app purchase receipt fields for all in-app purchase transactions.
InApp []*InApp `json:"in_app,omitempty"`
// The version of the app that the user originally purchased. This value does not change, and corresponds to the value of CFBundleVersion (in iOS) or CFBundleShortVersionString (in macOS) in the Info.plist file of the original purchase. In the sandbox environment, the value is always "1.0".
OriginalApplicationVersion string `json:"original_application_version"`
// The time of the original app purchase, in a date-time format similar to ISO 8601.
OriginalPurchaseDate string `json:"original_purchase_date"`
// The time of the original app purchase, in UNIX epoch time format, in milliseconds. Use this time format for processing dates.
OriginalPurchaseDateTimestamp string `json:"original_purchase_date_ms"`
// The time of the original app purchase, in the Pacific Time zone.
OriginalPurchaseDatePST string `json:"original_purchase_date_pst"`
// The time the user ordered the app available for pre-order, in a date-time format similar to ISO 8601.
PreorderDate string `json:"preorder_date"`
// The time the user ordered the app available for pre-order, in UNIX epoch time format, in milliseconds. This field is only present if the user pre-orders the app. Use this time format for processing dates.
PreorderDateTimestamp string `json:"preorder_date_ms"`
// The time the user ordered the app available for pre-order, in the Pacific Time zone.
PreorderDatePST string `json:"preorder_date_pst"`
// The time the App Store generated the receipt, in a date-time format similar to ISO 8601.
ReceiptCreationDate string `json:"receipt_creation_date"`
// The time the App Store generated the receipt, in UNIX epoch time format, in milliseconds. Use this time format for processing dates. This value does not change.
ReceiptCreationDateTimestamp string `json:"receipt_creation_date_ms"`
// The time the App Store generated the receipt, in the Pacific Time zone.
ReceiptCreationDatePST string `json:"receipt_creation_date_pst"`
// The type of receipt generated. The value corresponds to the environment in which the app or VPP purchase was made.
// Possible values: Production, ProductionVPP, ProductionSandbox, ProductionVPPSandbox
ReceiptType string `json:"receipt_type"`
// The time the request to the verifyReceipt endpoint was processed and the response was generated, in a date-time format similar to ISO 8601.
RequestDate string `json:"request_date"`
// The time the request to the verifyReceipt endpoint was processed and the response was generated, in UNIX epoch time format, in milliseconds. Use this time format for processing dates.
RequestDateTimestamp string `json:"request_date_ms"`
// The time the request to the verifyReceipt endpoint was processed and the response was generated, in the Pacific Time zone.
RequestDatePST string `json:"request_date_pst"`
// An arbitrary number that identifies a revision of your app. In the sandbox, this key's value is 0.
VersionExternalIdentifier int64 `json:"version_external_identifier"`
}
// InApp is the in-app purchase receipt fields for all in-app purchase transactions.
// https://developer.apple.com/documentation/appstorereceipts/responsebody/receipt/in_app
type InApp struct {
// The time the App Store refunded a transaction or revoked it from family sharing, in a date-time format similar to the ISO 8601. This field is present only for refunded or revoked transactions.
CancellationDate string `json:"cancellation_date"`
// The time the App Store refunded a transaction or revoked it from family sharing, in UNIX epoch time format, in milliseconds. This field is present only for refunded or revoked transactions. Use this time format for processing dates. The time the App Store refunded a transaction or revoked it from family sharing, in UNIX epoch time format, in milliseconds. This field is present only for refunded or revoked transactions. Use this time format for processing dates.
// https://developer.apple.com/documentation/appstorereceipts/cancellation_date_ms
CancellationDateTimestamp string `json:"cancellation_date_ms"`
// The time Apple customer support canceled a transaction, in the Pacific Time zone. This field is only present for refunded transactions.
CancellationDatePST string `json:"cancellation_date_pst"`
// The reason for a refunded transaction. When a customer cancels a transaction, the App Store gives them a refund and provides a value for this key. A value of “1” indicates that the customer canceled their transaction due to an actual or perceived issue within your app. A value of “0” indicates that the transaction was canceled for another reason; for example, if the customer made the purchase accidentally.
// Possible values: 1, 0
CancellationReason string `json:"cancellation_reason"`
// The time a subscription expires or when it will renew, in a date-time format similar to the ISO 8601.
ExpiresDate string `json:"expires_date"`
// The time a subscription expires or when it will renew, in UNIX epoch time format, in milliseconds. Use this time format for processing dates.
// https://developer.apple.com/documentation/appstorereceipts/expires_date_ms
ExpiresDateTimestamp string `json:"expires_date_ms"`
// The time a subscription expires or when it will renew, in the Pacific Time zone.
ExpiresDatePST string `json:"expires_date_pst"`
// An indicator of whether an auto-renewable subscription is in the introductory price period.
// https://developer.apple.com/documentation/appstorereceipts/is_in_intro_offer_period
IsInIntroOfferPeriod string `json:"is_in_intro_offer_period"`
// An indication of whether a subscription is in the free trial period.
// https://developer.apple.com/documentation/appstorereceipts/is_trial_period
IsTrialPeriod string `json:"is_trial_period"`
// The time of the original in-app purchase, in a date-time format similar to ISO 8601.
OriginalPurchaseDate string `json:"original_purchase_date"`
// The time of the original in-app purchase, in UNIX epoch time format, in milliseconds. For an auto-renewable subscription, this value indicates the date of the subscription's initial purchase. The original purchase date applies to all product types and remains the same in all transactions for the same product ID. This value corresponds to the original transactions transactionDate property in StoreKit. Use this time format for processing dates.
OriginalPurchaseDateTimestamp string `json:"original_purchase_date_ms"`
// The time of the original in-app purchase, in the Pacific Time zone.
OriginalPurchaseDatePST string `json:"original_purchase_date_pst"`
// The transaction identifier of the original purchase.
// https://developer.apple.com/documentation/appstorereceipts/original_transaction_id
OriginalTransactionId string `json:"original_transaction_id"`
// The unique identifier of the product purchased. You provide this value when creating the product in App Store Connect, and it corresponds to the productIdentifier property of the SKPayment object stored in the transaction's payment property.
ProductId string `json:"product_id"`
// The identifier of the subscription offer redeemed by the user.
// https://developer.apple.com/documentation/appstorereceipts/promotional_offer_id
PromotionalOfferId string `json:"promotional_offer_id"`
// The time the App Store charged the user's account for a purchased or restored product, or the time the App Store charged the users account for a subscription purchase or renewal after a lapse, in a date-time format similar to ISO 8601.
PurchaseDate string `json:"purchase_date"`
// For consumable, non-consumable, and non-renewing subscription products, the time the App Store charged the user's account for a purchased or restored product, in the UNIX epoch time format, in milliseconds. For auto-renewable subscriptions, the time the App Store charged the users account for a subscription purchase or renewal after a lapse, in the UNIX epoch time format, in milliseconds. Use this time format for processing dates.
PurchaseDateTimestamp string `json:"purchase_date_ms"`
// The time the App Store charged the user's account for a purchased or restored product, or the time the App Store charged the users account for a subscription purchase or renewal after a lapse, in the Pacific Time zone.
PurchaseDatePST string `json:"purchase_date_pst"`
// The number of consumable products purchased. This value corresponds to the quantity property of the SKPayment object stored in the transaction's payment property. The value is usually “1” unless modified with a mutable payment. The maximum value is 10.
Quantity string `json:"quantity"`
// A unique identifier for a transaction such as a purchase, restore, or renewal. See transaction_id for more information.
TransactionId string `json:"transaction_id"`
// A unique identifier for purchase events across devices, including subscription-renewal events. This value is the primary key for identifying subscription purchases.
WebOrderLineItemId string `json:"web_order_line_item_id"`
}
// VerifyReceipt 请求APP Store 校验支付请求,实际测试时发现这个文档介绍的返回信息只有那个status==0表示成功可以用其他的返回信息跟文档对不上
// url取 UrlProd 或 UrlSandbox
// pwd苹果APP秘钥https://help.apple.com/app-store-connect/#/devf341c0f01
// 文档https://developer.apple.com/documentation/appstorereceipts/verifyreceipt
func VerifyReceipt(ctx context.Context, url, pwd, receipt string) (rsp *VerifyResponse, err error) {
req := &VerifyRequest{Receipt: receipt, Password: pwd}
rsp = new(VerifyResponse)
_, err = NewClient().Type(TypeJSON).Post(url).SendStruct(req).EndStruct(ctx, rsp)
if err != nil {
return nil, err
}
return rsp, nil
}
// NewClient , default tls.Config{InsecureSkipVerify: true}
func NewClient() (client *Client) {
client = &Client{
HttpClient: &http.Client{
Timeout: 60 * time.Second,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
DisableKeepAlives: true,
Proxy: http.ProxyFromEnvironment,
},
},
Transport: nil,
Header: make(http.Header),
bodySize: 10, // default is 10MB
requestType: TypeJSON,
unmarshalType: string(TypeJSON),
}
return client
}
func (c *Client) Type(typeStr RequestType) (client *Client) {
if _, ok := types[typeStr]; ok {
c.requestType = typeStr
}
return c
}
func (c *Client) Post(url string) (client *Client) {
c.method = POST
c.url = url
return c
}
func (c *Client) SendStruct(v any) (client *Client) {
if v == nil {
return c
}
bs, err := json.Marshal(v)
if err != nil {
c.err = fmt.Errorf("[%w]: %v, value: %v", MarshalErr, err, v)
return c
}
switch c.requestType {
case TypeJSON:
c.jsonByte = bs
case TypeXML, TypeUrlencoded, TypeForm, TypeFormData:
body := make(map[string]any)
if err = json.Unmarshal(bs, &body); err != nil {
c.err = fmt.Errorf("[%w]: %v, bytes: %s", UnmarshalErr, err, string(bs))
return c
}
c.FormString = FormatURLParam(body)
}
return c
}
func FormatURLParam(body map[string]any) (urlParam string) {
var (
buf strings.Builder
keys []string
)
for k := range body {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
v, ok := body[k].(string)
if !ok {
v = convertToString(body[k])
}
if v != "" {
buf.WriteString(url.QueryEscape(k))
buf.WriteByte('=')
buf.WriteString(url.QueryEscape(v))
buf.WriteByte('&')
}
}
if buf.Len() <= 0 {
return ""
}
return buf.String()[:buf.Len()-1]
}
func convertToString(v any) (str string) {
if v == nil {
return ""
}
var (
bs []byte
err error
)
if bs, err = json.Marshal(v); err != nil {
return ""
}
str = string(bs)
return
}
func (c *Client) EndStruct(ctx context.Context, v any) (res *http.Response, err error) {
res, bs, err := c.EndBytes(ctx)
if err != nil {
return nil, err
}
if res.StatusCode != http.StatusOK {
return res, fmt.Errorf("StatusCode(%d) != 200", res.StatusCode)
}
switch c.unmarshalType {
case string(TypeJSON):
err = json.Unmarshal(bs, &v)
if err != nil {
return nil, fmt.Errorf("[%w]: %v, bytes: %s", UnmarshalErr, err, string(bs))
}
return res, nil
case string(TypeXML):
err = xml.Unmarshal(bs, &v)
if err != nil {
return nil, fmt.Errorf("[%w]: %v, bytes: %s", UnmarshalErr, err, string(bs))
}
return res, nil
default:
return nil, errors.New("unmarshalType Type Wrong")
}
}
func (c *Client) EndBytes(ctx context.Context) (res *http.Response, bs []byte, err error) {
if c.err != nil {
return nil, nil, c.err
}
var (
body io.Reader
bw *multipart.Writer
)
// multipart-form-data
if c.requestType == TypeMultipartFormData {
body = &bytes.Buffer{}
bw = multipart.NewWriter(body.(io.Writer))
}
reqFunc := func() (err error) {
switch c.method {
case GET:
switch c.requestType {
case TypeJSON:
c.ContentType = types[TypeJSON]
case TypeForm, TypeFormData, TypeUrlencoded:
c.ContentType = types[TypeForm]
case TypeMultipartFormData:
c.ContentType = bw.FormDataContentType()
case TypeXML:
c.ContentType = types[TypeXML]
c.unmarshalType = string(TypeXML)
default:
return errors.New("Request type Error ")
}
case POST, PUT, DELETE, PATCH:
switch c.requestType {
case TypeJSON:
if c.jsonByte != nil {
body = strings.NewReader(string(c.jsonByte))
}
c.ContentType = types[TypeJSON]
case TypeForm, TypeFormData, TypeUrlencoded:
body = strings.NewReader(c.FormString)
c.ContentType = types[TypeForm]
case TypeMultipartFormData:
for k, v := range c.multipartBodyMap {
// file 参数
if file, ok := v.(*File); ok {
fw, err := bw.CreateFormFile(k, file.Name)
if err != nil {
return err
}
_, _ = fw.Write(file.Content)
continue
}
// text 参数
vs, ok2 := v.(string)
if ok2 {
_ = bw.WriteField(k, vs)
} else if ss := ConvertToString(v); ss != "" {
_ = bw.WriteField(k, ss)
}
}
_ = bw.Close()
c.ContentType = bw.FormDataContentType()
case TypeXML:
body = strings.NewReader(c.FormString)
c.ContentType = types[TypeXML]
c.unmarshalType = string(TypeXML)
default:
return errors.New("Request type Error ")
}
default:
return errors.New("Only support GET and POST and PUT and DELETE ")
}
req, err := http.NewRequestWithContext(ctx, c.method, c.url, body)
if err != nil {
return err
}
req.Header = c.Header
req.Header.Set("Content-Type", c.ContentType)
if c.Transport != nil {
c.HttpClient.Transport = c.Transport
}
if c.Host != "" {
req.Host = c.Host
}
if c.Timeout > 0 {
c.HttpClient.Timeout = c.Timeout
}
res, err = c.HttpClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
bs, err = io.ReadAll(io.LimitReader(res.Body, int64(c.bodySize<<20))) // default 10MB change the size you want
if err != nil {
return err
}
return nil
}
if err = reqFunc(); err != nil {
return nil, nil, err
}
return res, bs, nil
}
func ConvertToString(v any) (str string) {
if v == nil {
return ""
}
var (
bs []byte
err error
)
if bs, err = json.Marshal(v); err != nil {
return ""
}
str = string(bs)
return
}

191
pay/google.go Normal file
View File

@@ -0,0 +1,191 @@
package pay
import (
"context"
playstore2 "github.com/ayflying/utility_go/pay/playstore"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
"google.golang.org/api/androidpublisher/v3"
)
var (
ctx = gctx.New()
)
// GooglePay 是一个处理Google支付的结构体。
type GooglePay struct {
c *playstore2.Client
}
// Init 初始化GooglePay客户端。
// data: 初始化客户端所需的配置数据。
func (p *GooglePay) Init(data []byte) {
var err error
p.c, err = playstore2.New(data)
if err != nil {
panic(err) // 如果初始化失败则panic。
}
}
// VerifyPay 验证用户的支付。
// userId: 用户ID。
// OrderId: 订单ID。
// package1: 应用包名。
// subscriptionID: 订阅ID。
// purchaseToken: 购买凭证。
// cb: 验证结果的回调函数,如果验证成功,会调用此函数。
// 返回值: 执行错误。
func (p *GooglePay) VerifyPay(userId int64, OrderId, package1, subscriptionID, purchaseToken string, cb func(string, string) error) error {
info, err := p.c.VerifyProduct(context.Background(), package1, subscriptionID, purchaseToken)
if err != nil {
return gerror.Cause(err) // 验证产品失败,返回错误。
}
if info.PurchaseState == 0 {
if err := cb(subscriptionID, info.OrderId); err != nil {
return gerror.Cause(err) // 调用回调函数失败,返回错误。
}
} else {
return nil // 验证结果不为购买状态直接返回nil。
}
return nil
}
// VerifyPayV1 是VerifyPay的另一个版本用于验证订阅支付。
// package1: 应用包名。
// subscriptionID: 订阅ID。
// purchaseToken: 购买凭证。
// cb: 验证结果的回调函数。
// 返回值: 执行错误。
func (p *GooglePay) VerifyPayV1(package1, subscriptionID, purchaseToken string, cb func(string, string) error) error {
//g.Log().Infof(ctx, "VerifyPayV1: package = %v subscriptionID = %v, purchaseToken = %v", package1, subscriptionID, purchaseToken)
info, err := p.c.VerifyProduct(context.Background(), package1, subscriptionID, purchaseToken)
if err != nil {
return gerror.Cause(err) // 验证产品失败,返回错误。
}
if info.PurchaseState == 0 {
if err := cb(subscriptionID, info.OrderId); err != nil {
return gerror.Cause(err) // 调用回调函数失败,返回错误。
}
} else {
return nil // 验证结果不为购买状态直接返回nil。
}
return nil
}
// VerifyPayV2 是VerifyPay的另一个版本支持不同类型产品的验证。
// types: 验证的产品类型。
// package1: 应用包名。
// subscriptionID: 订阅ID。
// purchaseToken: 购买凭证。
// cb: 验证结果的回调函数。
// 返回值: 执行错误。
func (p *GooglePay) VerifyPayV2(types int32, package1, subscriptionID, purchaseToken string, cb func(string, string) error) error {
//g.Log().Infof(ctx, "VerifyPayV1: package = %v subscriptionID = %v, purchaseToken = %v", package1, subscriptionID, purchaseToken)
switch types {
case 0:
info, err := p.c.VerifyProduct(context.Background(), package1, subscriptionID, purchaseToken)
if err != nil {
return gerror.Cause(err) // 验证产品失败,返回错误。
}
if info.PurchaseState == 0 {
if err := cb(subscriptionID, info.OrderId); err != nil {
return gerror.Cause(err) // 调用回调函数失败,返回错误。
}
}
case 1:
info, err := p.c.VerifySubscription(context.Background(), package1, subscriptionID, purchaseToken)
if err != nil {
return gerror.Cause(err) // 验证订阅失败,返回错误。
}
if len(info.OrderId) != 0 {
if err := cb(subscriptionID, info.OrderId); err != nil {
return gerror.Cause(err) // 调用回调函数失败,返回错误。
}
}
}
return nil
}
//func (p *GooglePay) VerifyPayTest(package1, subscriptionID, purchaseToken string) (*androidpublisher.ProductPurchase, error) {
// return p.c.VerifyProduct(context.Background(), package1, subscriptionID, purchaseToken)
//}
func (p *GooglePay) VerifySubscriptionTest(package1, subscriptionID, purchaseToken string) (interface{}, error) {
return p.c.VerifySubscription(context.Background(), package1, subscriptionID, purchaseToken)
}
// VerifySubSciption google 检查订阅是否有效
func (p *GooglePay) VerifySubSciption(package1, subscriptionID, purchaseToken string) (string, error) {
info, err := p.c.VerifySubscription(context.Background(), package1, subscriptionID, purchaseToken)
if err != nil {
return "", gerror.Cause(err)
}
if len(info.OrderId) != 0 {
return info.OrderId, nil
}
return "", nil
}
// 获取已撤销的购买列表
func (p *GooglePay) GetRevokedPurchaseList(package1 string) (res *androidpublisher.VoidedPurchasesListResponse, err error) {
res, err = p.c.Voidedpurchases(package1)
//return p.c.GetRevokedPurchaseList(context.Background(), package1)
return
}
// Acknowledge 确认购买应用内商品。
// Method: purchases.products.acknowledge y
func (p *GooglePay) Acknowledge(ctx context.Context, packageName, productID, token, developerPayload string) (err error) {
err = p.c.AcknowledgeProduct(ctx, packageName, productID, token, developerPayload)
return
}
// Consume 消费购买应用内商品。
func (p *GooglePay) Consume(ctx context.Context, packageName, productID, token string) (err error) {
err = p.c.ConsumeProduct(ctx, packageName, productID, token)
return
}
// 谷歌支付支付凭证校验V1
func (s *GooglePay) GooglePayTokenV1(token string) (err error) {
type PayOrderType struct {
Payload string `json:"Payload"`
Store string `json:"Store"`
TransactionID string `json:"TransactionID"`
}
type PayloadType struct {
Json string `json:"json"`
Signature string `json:"signature"`
SkuDetails []string `json:"skuDetails"`
}
type PayJson struct {
PackageName string `json:"packageName"`
ProductId string `json:"productId"`
PurchaseTime int64 `json:"purchaseTime"`
PurchaseState int `json:"purchaseState"`
PurchaseToken string `json:"purchaseToken"`
Quantity int `json:"quantity"`
Acknowledged bool `json:"acknowledged"`
OrderId string `json:"orderId"`
}
var data PayOrderType
gconv.Struct(token, &data)
var payload PayloadType
gconv.Struct(data.Payload, &payload)
var payJson PayJson
gconv.Struct(payload.Json, &payJson)
if gstr.Pos(payJson.OrderId, "GPA.") < 0 {
err = gerror.New("GPA验证失败")
return
}
if payJson.Quantity != 1 {
err = gerror.New("Quantity验证失败")
return
}
return
}

Some files were not shown because too many files have changed in this diff Show More