This commit is contained in:
pengyinjie 2025-10-22 18:01:11 +08:00
parent a0bbbc2a24
commit 8ebb876bc5
241 changed files with 37442 additions and 9 deletions

32
.gitignore vendored
View File

@ -1,7 +1,4 @@
# ---> Go
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Reference https://github.com/github/gitignore/blob/master/Go.gitignore
# Binaries for programs and plugins
*.exe
*.exe~
@ -16,8 +13,29 @@
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
vendor/
# Go workspace file
go.work
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# OS General
Thumbs.db
.DS_Store
# project
*.cert
*.key
*.log
bin/
# Develop tools
.vscode/
.idea/
*.swp
config.yaml
config.yaml.live
*.bat
/json

8
.tmpl/cookiecutter.json Normal file
View File

@ -0,0 +1,8 @@
{
"app_name": "example",
"go_module": "tools",
"db_driver": "mysql",
"_extensions": [
"jinja2_strcase.StrcaseExtension"
]
}

View File

@ -0,0 +1,31 @@
syntax = "proto3";
package {{cookiecutter.app_name}}.v1;
import "google/api/annotations.proto";
import "validate/validate.proto";
option go_package = "{{cookiecutter.go_module}}/api/{{cookiecutter.app_name}}/v1;v1";
option java_multiple_files = true;
option java_package = "dev.kratos.api.{{cookiecutter.app_name}}.v1";
option java_outer_classname = "{{cookiecutter.app_name|to_camel}}ProtoV1";
// The greeting service definition.
service {{cookiecutter.app_name|to_camel}} {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {
option (google.api.http) = {
get: "/{{cookiecutter.app_name}}/{name}"
};
}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}

View File

@ -0,0 +1,16 @@
syntax = "proto3";
package api.{{cookiecutter.app_name}}.v1;
import "errors/errors.proto";
option go_package = "{{cookiecutter.go_module}}/api/{{cookiecutter.app_name}}/v1;v1";
option java_multiple_files = true;
option java_package = "{{cookiecutter.app_name}}.v1.errors";
option objc_class_prefix = "API{{cookiecutter.app_name|to_camel}}Errors";
enum {{cookiecutter.app_name|to_camel}}Error {
option (errors.default_code) = 500;
USER_NOT_FOUND = 0 [(errors.code) = 404];
CONTENT_MISSING = 1 [(errors.code) = 400];
}

View File

@ -0,0 +1 @@
include ../../app_makefile

View File

@ -0,0 +1,110 @@
package main
import (
"flag"
zaplogger "github.com/go-kratos/kratos/contrib/log/zap/v2"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/config"
"github.com/go-kratos/kratos/v2/config/file"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/middleware/tracing"
"github.com/go-kratos/kratos/v2/registry"
"github.com/go-kratos/kratos/v2/transport/grpc"
"github.com/go-kratos/kratos/v2/transport/http"
"github.com/tx7do/kratos-transport/transport/kafka"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/jaeger"
"go.opentelemetry.io/otel/sdk/resource"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/conf"
)
// go build -ldflags "-X main.Version=x.y.z"
var (
// Name is the name of the compiled software.
Name = "{{cookiecutter.app_name}}.rpc"
// Version is the version of the compiled software.
Version = "0.1.0"
// flagconf is the config flag.
flagconf string
id, _ = os.Hostname()
)
func init() {
flag.StringVar(&flagconf, "conf", "configs/config.yaml", "config path, eg: -conf config.yaml")
}
func newApp(logger log.Logger, conf *conf.Server, hs *http.Server, gs *grpc.Server, ks *kafka.Server, rr registry.Registrar) *kratos.App {
return kratos.New(
kratos.ID(id),
kratos.Name(Name),
kratos.Version(Version),
kratos.Metadata(map[string]string{}),
kratos.Logger(logger),
kratos.Server(
hs,
gs,
ks,
),
kratos.Registrar(rr),
)
}
func main() {
flag.Parse()
encoderCfg := zapcore.EncoderConfig{
LevelKey: "level",
EncodeLevel: zapcore.LowercaseLevelEncoder,
}
out := zapcore.AddSync(os.Stdout) // replace real writer
core := zapcore.NewCore(zapcore.NewJSONEncoder(encoderCfg), out, zap.DebugLevel)
zlogger := zap.New(core).WithOptions()
logger := log.With(zaplogger.NewLogger(zlogger),
"ts", log.DefaultTimestamp,
"caller", log.DefaultCaller,
"service.id", id,
"service.name", Name,
"service.version", Version,
"trace_id", tracing.TraceID(),
"span_id", tracing.SpanID(),
)
c := config.New(
config.WithSource(
file.NewSource(flagconf),
),
)
if err := c.Load(); err != nil {
panic(err)
}
var bc conf.Bootstrap
if err := c.Scan(&bc); err != nil {
panic(err)
}
exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(bc.Server.TraceEndpoint)))
if err != nil {
panic(err)
}
tp := tracesdk.NewTracerProvider(
tracesdk.WithBatcher(exp),
tracesdk.WithResource(resource.NewSchemaless(
semconv.ServiceNameKey.String(Name),
)),
)
otel.SetTracerProvider(tp)
app, cleanup, err := initApp(bc.Server, bc.Data, bc.Queue, logger)
if err != nil {
panic(err)
}
defer cleanup()
// start and wait for stop signal
if err := app.Run(); err != nil {
panic(err)
}
}

View File

@ -0,0 +1,22 @@
//go:build wireinject
// +build wireinject
// The build tag makes sure the stub is not built in the final build.
package main
import (
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/log"
"github.com/google/wire"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/biz"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/conf"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/data"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/server"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/service"
)
// initApp init kratos application.
func initApp(*conf.Server, *conf.Data, *conf.Queue, log.Logger) (*kratos.App, func(), error) {
panic(wire.Build(server.ProviderSet, data.ProviderSet, biz.ProviderSet, service.ProviderSet, newApp))
}

View File

@ -0,0 +1,44 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
import (
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/log"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/biz"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/conf"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/data"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/server"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/service"
)
// Injectors from wire.go:
// initApp init kratos application.
func initApp(confServer *conf.Server, confData *conf.Data, confQueue *conf.Queue, logger log.Logger) (*kratos.App, func(), error) {
broker := data.NewKafkaBroker(confQueue)
client := data.NewAsynqClient(confQueue)
discovery := server.NewDiscovery(confServer)
{{cookiecutter.app_name}}Client := data.New{{cookiecutter.app_name|to_camel}}Client(discovery)
dataData, cleanup, err := data.NewData(confData, broker, client, {{cookiecutter.app_name}}Client, logger)
if err != nil {
return nil, nil, err
}
{{cookiecutter.app_name|to_lower_camel}}Repo := data.New{{cookiecutter.app_name|to_camel}}Repo(dataData, logger)
transaction := data.NewTransaction(dataData)
cache := data.NewCache(dataData)
{{cookiecutter.app_name|to_lower_camel}}Usecase := biz.New{{cookiecutter.app_name|to_camel}}Usecase({{cookiecutter.app_name|to_lower_camel}}Repo, cache, transaction, logger)
{{cookiecutter.app_name|to_lower_camel}}Service := service.New{{cookiecutter.app_name|to_camel}}Service({{cookiecutter.app_name|to_lower_camel}}Usecase, logger)
httpServer := server.NewHTTPServer(confServer, {{cookiecutter.app_name|to_lower_camel}}Service, logger)
grpcServer := server.NewGRPCServer(confServer, {{cookiecutter.app_name|to_lower_camel}}Service, logger)
kafkaServer := server.NewKafkaServer(confQueue, {{cookiecutter.app_name|to_lower_camel}}Usecase, logger)
registrar := server.NewRegistrar(confServer)
app := newApp(logger, confServer, httpServer, grpcServer, kafkaServer, registrar)
return app, func() {
cleanup()
}, nil
}

View File

@ -0,0 +1,86 @@
package main
import (
"flag"
zaplogger "github.com/go-kratos/kratos/contrib/log/zap/v2"
"github.com/go-kratos/kratos/v2/config"
"github.com/go-kratos/kratos/v2/config/file"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/middleware/tracing"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/jaeger"
"go.opentelemetry.io/otel/sdk/resource"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/conf"
)
// go build -ldflags "-X main.Version=x.y.z"
var (
// Name is the name of the compiled software.
Name = "{{cookiecutter.app_name|lower}}.async"
// Version is the version of the compiled software.
Version = "0.1.0"
// flagconf is the config flag.
flagconf string
id, _ = os.Hostname()
)
func init() {
flag.StringVar(&flagconf, "conf", "configs/config.yaml", "config path, eg: -conf config.yaml")
}
func main() {
flag.Parse()
encoderCfg := zapcore.EncoderConfig{
LevelKey: "level",
EncodeLevel: zapcore.LowercaseLevelEncoder,
}
out := zapcore.AddSync(os.Stdout) // replace real writer
core := zapcore.NewCore(zapcore.NewJSONEncoder(encoderCfg), out, zap.DebugLevel)
zlogger := zap.New(core).WithOptions()
logger := log.With(zaplogger.NewLogger(zlogger),
"ts", log.DefaultTimestamp,
"caller", log.DefaultCaller,
"service.id", id,
"service.name", Name,
"service.version", Version,
"trace_id", tracing.TraceID(),
"span_id", tracing.SpanID(),
)
c := config.New(
config.WithSource(
file.NewSource(flagconf),
),
)
if err := c.Load(); err != nil {
panic(err)
}
var bc conf.Bootstrap
if err := c.Scan(&bc); err != nil {
panic(err)
}
exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(bc.Server.TraceEndpoint)))
if err != nil {
panic(err)
}
tp := tracesdk.NewTracerProvider(
tracesdk.WithBatcher(exp),
tracesdk.WithResource(resource.NewSchemaless(
semconv.ServiceNameKey.String(Name),
)),
)
otel.SetTracerProvider(tp)
job, cleanup, err := initApp(bc.Data, bc.Server, bc.Queue, logger)
if err != nil {
panic(err)
}
defer cleanup()
if err := job.Run(); err != nil {
panic(err)
}
}

View File

@ -0,0 +1,20 @@
//go:build wireinject
// +build wireinject
// The build tag makes sure the stub is not built in the final build.
package main
import (
"github.com/go-kratos/kratos/v2/log"
"github.com/google/wire"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/biz"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/conf"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/data"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/server"
)
// initApp init application.
func initApp(*conf.Data, *conf.Server, *conf.Queue, log.Logger) (*server.AsynqServer, func(), error) {
panic(wire.Build(data.ProviderSet, server.ProviderSet, biz.ProviderSet))
}

View File

@ -0,0 +1,37 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
import (
"github.com/go-kratos/kratos/v2/log"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/biz"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/conf"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/data"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/server"
)
// Injectors from wire.go:
// initApp init application.
func initApp(confData *conf.Data, confServer *conf.Server, confQueue *conf.Queue, logger log.Logger) (*server.AsynqServer, func(), error) {
broker := data.NewKafkaBroker(confQueue)
client := data.NewAsynqClient(confQueue)
discovery := server.NewDiscovery(confServer)
{{cookiecutter.app_name}}Client := data.New{{cookiecutter.app_name|to_camel}}Client(discovery)
dataData, cleanup, err := data.NewData(confData, broker, client, {{cookiecutter.app_name}}Client, logger)
if err != nil {
return nil, nil, err
}
{{cookiecutter.app_name|to_lower_camel}}Repo := data.New{{cookiecutter.app_name|capitalize}}Repo(dataData, logger)
transaction := data.NewTransaction(dataData)
cache := data.NewCache(dataData)
{{cookiecutter.app_name|to_lower_camel}}Usecase := biz.New{{cookiecutter.app_name|capitalize}}Usecase({{cookiecutter.app_name|to_lower_camel}}Repo, cache, transaction, logger)
asynqServer := server.NewAsynqServer(confQueue, {{cookiecutter.app_name|to_lower_camel}}Usecase)
return asynqServer, func() {
cleanup()
}, nil
}

View File

@ -0,0 +1,39 @@
server:
http:
addr: 0.0.0.0:8001
timeout: 1s
grpc:
addr: 0.0.0.0:9001
timeout: 1s
etcd:
addr:
- 127.0.0.1:2379
trace_endpoint: http://127.0.0.1:14268/api/traces
jwt_token: "L9Irpo8hdCaidG1tsEiW1pJuL9DsHU0vj"
env: "qa"
data:
database:
{% if cookiecutter.db_driver == 'mysql' -%}
driver: mysql
source: root:@tcp(127.0.0.1:3306)/{{cookiecutter.app_name}}?charset=utf8mb4&parseTime=True&loc=UTC
{%- elif cookiecutter.db_driver == 'postgres' -%}
driver: postgres
source: host=localhost port=5432 user=postgres dbname=example sslmode=disable
{%- endif %}
redis:
addr: 127.0.0.1:6379
read_timeout: 0.2s
write_timeout: 0.2s
queue:
kafka:
addrs:
- 127.0.0.1:9092
topic: example
group: example
asynq:
addr: 127.0.0.1:6379
read_timeout: 0.2s
write_timeout: 0.2s
concurrency: 10

View File

@ -0,0 +1,3 @@
package {{cookiecutter.app_name}}
//go:generate kratos proto client api

View File

@ -0,0 +1,22 @@
package biz
import (
"context"
"github.com/google/wire"
"gorm.io/gorm"
)
// ProviderSet is biz providers.
var ProviderSet = wire.NewSet(New{{cookiecutter.app_name|to_camel}}Usecase)
type Cache interface {
GetValue(ctx context.Context, key string) (string, error)
DelValue(ctx context.Context, keys ...string) error
WriteValue(ctx context.Context, key string, value interface{}, timeout int32) error
Remember(ctx context.Context, key string, secone int32, fn func(ctx context.Context) (interface{}, error)) ([]byte, error)
}
type Transaction interface {
InTx(context.Context, func(ctx context.Context) error) error
DB(ctx context.Context) *gorm.DB
}

View File

@ -0,0 +1,34 @@
package biz
import (
"context"
"fmt"
"github.com/tx7do/kratos-transport/broker"
)
type ExampleStruct struct {
Name string `json:"name"`
ID int `json:"id"`
}
func ExampleCreator() broker.Any { return &ExampleStruct{} }
type ExmapleHandler func(_ context.Context, topic string, headers broker.Headers, msg *ExampleStruct) error
func RegisterExampleHandler(fnc ExmapleHandler) broker.Handler {
return func(ctx context.Context, event broker.Event) error {
if event.Error() != nil {
return event.Error()
}
msg, ok := event.Message().Body.(*ExampleStruct)
if !ok {
return fmt.Errorf("[Kafka] unsupported type: %T", event.Message().Body)
}
if err := fnc(ctx, event.Topic(), event.Message().Headers, msg); err != nil {
return err
}
return nil
}
}

View File

@ -0,0 +1,56 @@
package biz
import (
"context"
"github.com/go-kratos/kratos/v2/log"
"github.com/hibiken/asynq"
"github.com/tx7do/kratos-transport/broker"
)
type {{cookiecutter.app_name|to_camel}} struct {
Hello string
}
type {{cookiecutter.app_name|to_camel}}Repo interface {
Create{{cookiecutter.app_name|to_camel}}(context.Context, *{{cookiecutter.app_name|to_camel}}) error
Update{{cookiecutter.app_name|to_camel}}(context.Context, *{{cookiecutter.app_name|to_camel}}) error
}
type {{cookiecutter.app_name|to_camel}}Usecase struct {
repo {{cookiecutter.app_name|to_camel}}Repo
cache Cache
log *log.Helper
tx Transaction
}
func New{{cookiecutter.app_name|to_camel}}Usecase(repo {{cookiecutter.app_name|to_camel}}Repo, cache Cache, tx Transaction, logger log.Logger) *{{cookiecutter.app_name|to_camel}}Usecase {
return &{{cookiecutter.app_name|to_camel}}Usecase{
repo: repo,
cache: cache,
tx: tx,
log: log.NewHelper(logger),
}
}
func (uc *{{cookiecutter.app_name|to_camel}}Usecase) Create(ctx context.Context, g *{{cookiecutter.app_name|to_camel}}) error {
return uc.repo.Create{{cookiecutter.app_name|to_camel}}(ctx, g)
}
func (uc *{{cookiecutter.app_name|to_camel}}Usecase) Update(ctx context.Context, g *{{cookiecutter.app_name|to_camel}}) error {
return uc.repo.Update{{cookiecutter.app_name|to_camel}}(ctx, g)
}
func (uc *{{cookiecutter.app_name|to_camel}}Usecase) KakfaExampleConsumer(_ context.Context, topic string, headers broker.Headers, msg *ExampleStruct) error {
log.Infof("Topic %s, Headers: %+v, Payload: %+v\n", topic, headers, msg)
return nil
}
const {{cookiecutter.app_name|to_camel}}TaskName = "{{cookiecutter.app_name}}:task"
// Asynq{{cookiecutter.app_name|to_camel}}TaskHandler Asynq handler task
func (uc *{{cookiecutter.app_name|to_camel}}Usecase) Asynq{{cookiecutter.app_name|to_camel}}TaskHandler(ctx context.Context, t *asynq.Task) error {
// do something
// do some else logging
log.Info("Asynq{{cookiecutter.app_name|to_camel}}TaskHandle: ", string(t.Payload()))
return nil
}

View File

@ -0,0 +1,76 @@
syntax = "proto3";
package kratos.api;
option go_package = "{{cookiecutter.go_module}}/app/{{cookiecutter.app_name|to_lower_camel}}/internal/conf;conf";
import "google/protobuf/duration.proto";
message Bootstrap {
Server server = 1;
Data data = 2;
Queue queue = 3;
}
message Server {
message HTTP {
string network = 1;
string addr = 2;
google.protobuf.Duration timeout = 3;
}
message GRPC {
string network = 1;
string addr = 2;
google.protobuf.Duration timeout = 3;
}
message ETCD {
repeated string addr = 1;
string username = 2;
string password = 3;
}
HTTP http = 1;
GRPC grpc = 2;
ETCD etcd = 3;
string trace_endpoint = 4;
string jwt_token = 5;
string env = 6;
}
message Data {
message Database {
string driver = 1;
string source = 2;
}
message Redis {
string network = 1;
string addr = 2;
int32 db = 3;
string password = 4;
int32 pool = 5;
google.protobuf.Duration read_timeout = 6;
google.protobuf.Duration write_timeout = 7;
}
Database database = 1;
Redis redis = 2;
}
message Queue {
message Kafka {
repeated string addrs = 1;
string topic = 2;
string group = 3;
string username = 4;
string password = 5;
}
message Asynq {
string network = 1;
string addr = 2;
int32 db = 3;
string password = 4;
int32 pool = 5;
google.protobuf.Duration read_timeout = 6;
google.protobuf.Duration write_timeout = 7;
int32 concurrency = 8;
}
Kafka kafka = 1;
Asynq asynq = 2;
}

View File

@ -0,0 +1,250 @@
package data
import (
"context"
"github.com/go-kratos/kratos/v2/log"
"encoding/json"
"fmt"
"github.com/go-kratos/kratos/v2/middleware/recovery"
"github.com/go-kratos/kratos/v2/middleware/tracing"
"github.com/go-kratos/kratos/v2/registry"
"github.com/go-kratos/kratos/v2/transport/grpc"
"github.com/go-redis/redis/extra/redisotel/v8"
"github.com/go-redis/redis/v8"
"github.com/google/wire"
"github.com/hibiken/asynq"
"github.com/tx7do/kratos-transport/broker"
"github.com/tx7do/kratos-transport/broker/kafka"
"github.com/uptrace/opentelemetry-go-extra/otelgorm"
semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
ggrpc "google.golang.org/grpc"
{% if cookiecutter.db_driver == 'mysql' -%}
driver "gorm.io/driver/mysql"
{%- elif cookiecutter.db_driver == 'postgres' -%}
driver "gorm.io/driver/postgres"
{%- endif %}
"gorm.io/gorm"
v1 "{{cookiecutter.go_module}}/api/{{cookiecutter.app_name}}/v1"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/biz"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/conf"
"{{cookiecutter.go_module}}/pkg/utils/snowflake"
)
// ProviderSet is data providers.
var ProviderSet = wire.NewSet(
NewData,
NewTransaction,
New{{cookiecutter.app_name|to_camel}}Repo,
NewCache,
NewKafkaBroker,
NewAsynqClient,
New{{cookiecutter.app_name|to_camel}}Client,
)
// Data .
type Data struct {
log *log.Helper
redis *redis.Client
db *gorm.DB
snowflake *snowflake.Node
kbroker broker.Broker
asynqCli *asynq.Client
// TODO just for example, don't use dispatch self in production
ec v1.{{cookiecutter.app_name|to_camel}}Client
}
type contextTxKey struct{}
func (d *Data) InTx(ctx context.Context, fn func(ctx context.Context) error) error {
return d.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
ctx = context.WithValue(ctx, contextTxKey{}, tx)
return fn(ctx)
})
}
func (d *Data) DB(ctx context.Context) *gorm.DB {
tx, ok := ctx.Value(contextTxKey{}).(*gorm.DB)
if ok {
return tx
}
return d.db
}
// NewAsynqTask new asynq task
func (d *Data) NewAsynqTask(taskName string, payload []byte) error {
_, err := d.asynqCli.Enqueue(asynq.NewTask(taskName, payload))
return err
}
// NewTransaction .
func NewTransaction(d *Data) biz.Transaction {
return d
}
// NewData .
func NewData(c *conf.Data, kbroker broker.Broker, asynqCli *asynq.Client, ec v1.{{cookiecutter.app_name|to_camel}}Client, logger log.Logger) (*Data, func(), error) {
db := newDB(c.Database.Source)
rdb := newRedis(c.Redis)
cleanup := func() {
log.NewHelper(logger).Info("closing the data resources")
_ = rdb.Close()
sqlDB, _ := db.DB()
_ = sqlDB.Close()
}
data := &Data{
log: log.NewHelper(logger),
redis: rdb,
db: db,
snowflake: snowflake.GetSnowflakeNode(rdb),
kbroker: kbroker,
asynqCli: asynqCli,
ec: ec,
}
return data, cleanup, nil
}
func newRedis(c *conf.Data_Redis) *redis.Client {
rdb := redis.NewClient(&redis.Options{
Network: c.Network,
Addr: c.Addr,
Password: c.Password,
DB: int(c.Db),
PoolSize: int(c.Pool),
})
rdb.AddHook(redisotel.NewTracingHook(redisotel.WithAttributes(semconv.NetPeerNameKey.String(c.Addr))))
return rdb
}
func newDB(dsn string) *gorm.DB {
if dsn == "" {
{% if cookiecutter.db_driver == 'mysql' -%}
dsn = "root:@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=UTC"
{%- elif cookiecutter.db_driver == 'postgres' -%}
dsn = "host=localhost port=5432 user=postgres dbname=example sslmode=disable"
{%- endif %}
}
db, err := gorm.Open(driver.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatal("connection database failed: ", err)
}
_ = db.Use(otelgorm.NewPlugin(otelgorm.WithoutQueryVariables()))
return db
}
// NewCache .
func NewCache(d *Data) biz.Cache {
return d
}
func (r *Data) Remember(ctx context.Context, key string, second int32, fn func(ctx context.Context) (interface{}, error)) ([]byte, error) {
str, err := r.GetValue(ctx, key)
if err != nil {
value, err := fn(ctx)
if err != nil {
return nil, err
}
mByte, err := json.Marshal(value)
if err != nil {
return nil, fmt.Errorf("json Marshal cache failed, err: %w ", err)
}
return mByte, nil
}
if str == "" {
value, err := fn(ctx)
if err != nil {
return nil, err
}
var mByte []byte
if str, ok := value.(string); ok {
mByte = []byte(str)
} else {
mByte, err = json.Marshal(value)
}
if err != nil {
return nil, fmt.Errorf("json Marshal cache null, err: %w ", err)
}
r.WriteValue(ctx, key, mByte, second)
return mByte, nil
}
return []byte(str), nil
}
func (r *Data) GetValue(ctx context.Context, key string) (string, error) {
v, err := r.redis.Get(ctx, key).Result()
if err == redis.Nil {
return v, nil
} else if err != nil {
return v, err
} else {
return v, nil
}
}
func (r *Data) WriteValue(ctx context.Context, key string, value interface{}, timeout int32) error {
return r.redis.Set(ctx, key, value, time.Duration(timeout)*time.Second).Err()
}
func (r *Data) DelValue(ctx context.Context, keys ...string) error {
return r.redis.Del(ctx, keys...).Err()
}
// New{{cookiecutter.app_name|to_camel}}Client new {{cookiecutter.app_name}} rpc client
func New{{cookiecutter.app_name|to_camel}}Client(r registry.Discovery) v1.{{cookiecutter.app_name|to_camel}}Client {
return NewRPCClient[v1.{{cookiecutter.app_name|to_camel}}Client](r, "{{cookiecutter.app_name}}.rpc", v1.New{{cookiecutter.app_name|to_camel}}Client)
}
// NewRPCClient new one rpc client by discovery.
func NewRPCClient[T any](r registry.Discovery, rpcName string, fn func(cc ggrpc.ClientConnInterface) T) T {
conn, err := grpc.DialInsecure(
context.Background(),
grpc.WithEndpoint("discovery:///"+rpcName),
grpc.WithDiscovery(r),
grpc.WithMiddleware(
tracing.Client(),
recovery.Recovery(),
),
)
if err != nil {
log.Fatal(err)
}
return fn(conn)
}
// NewKafkaBroker new kafka broker.
func NewKafkaBroker(confQueue *conf.Queue) broker.Broker {
opts := []broker.Option{
broker.WithAddress(confQueue.Kafka.Addrs...),
broker.WithCodec("json"),
broker.WithGlobalTracerProvider(),
}
if confQueue.Kafka.Username != "" && confQueue.Kafka.Password != "" {
opts = append(opts, kafka.WithPlainMechanism(confQueue.Kafka.Username, confQueue.Kafka.Password))
}
kafkaBroker := kafka.NewBroker(opts...)
_ = kafkaBroker.Init()
return kafkaBroker
}
// NewAsynqClient new asynq client.
func NewAsynqClient(confQueue *conf.Queue) *asynq.Client {
return asynq.NewClient(asynq.RedisClientOpt{
Addr: confQueue.Asynq.Addr,
DB: int(confQueue.Asynq.Db),
Password: confQueue.Asynq.Password,
ReadTimeout: confQueue.Asynq.ReadTimeout.AsDuration(),
WriteTimeout: confQueue.Asynq.WriteTimeout.AsDuration(),
PoolSize: int(confQueue.Asynq.Pool),
})
}

View File

@ -0,0 +1,28 @@
package data
import (
"context"
"github.com/go-kratos/kratos/v2/log"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/biz"
)
type {{cookiecutter.app_name|to_lower_camel}}Repo struct {
data *Data
log *log.Helper
}
// New{{cookiecutter.app_name|to_camel}}Repo .
func New{{cookiecutter.app_name|to_camel}}Repo(data *Data, logger log.Logger) biz.{{cookiecutter.app_name|to_camel}}Repo {
return &{{cookiecutter.app_name|to_lower_camel}}Repo{
data: data,
log: log.NewHelper(logger),
}
}
func (r *{{cookiecutter.app_name|to_lower_camel}}Repo) Create{{cookiecutter.app_name|to_camel}}(ctx context.Context, g *biz.{{cookiecutter.app_name|to_camel}}) error {
return nil
}
func (r *{{cookiecutter.app_name|to_lower_camel}}Repo) Update{{cookiecutter.app_name|to_camel}}(ctx context.Context, g *biz.{{cookiecutter.app_name|to_camel}}) error {
return nil
}

View File

@ -0,0 +1,66 @@
package server
import (
"fmt"
"github.com/hibiken/asynq"
"golang.org/x/sync/errgroup"
"log"
"os"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/biz"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/conf"
)
type AsynqServer struct {
srv *asynq.Server
mux *asynq.ServeMux
scheduler *asynq.Scheduler
entryID string
}
func (j *AsynqServer) Run() error {
eg := errgroup.Group{}
eg.Go(func() error {
log.Println("schedule start", j.entryID)
return j.scheduler.Run()
})
eg.Go(func() error {
return j.srv.Run(j.mux)
})
return eg.Wait()
}
func NewAsynqServer(conf *conf.Queue, uc *biz.{{cookiecutter.app_name|to_camel}}Usecase) *AsynqServer {
asynqConf := conf.Asynq
redisOpt := asynq.RedisClientOpt{
Addr: asynqConf.Addr,
Password: asynqConf.Password,
DB: int(asynqConf.Db),
PoolSize: int(asynqConf.Pool),
ReadTimeout: asynqConf.ReadTimeout.AsDuration(),
WriteTimeout: asynqConf.WriteTimeout.AsDuration(),
}
srv := asynq.NewServer(
redisOpt,
asynq.Config{
Concurrency: int(asynqConf.Concurrency),
Queues: map[string]int{
"critical": 6,
"default": 3,
"low": 1,
},
})
mux := asynq.NewServeMux()
mux.HandleFunc(biz.{{cookiecutter.app_name|to_camel}}TaskName, uc.Asynq{{cookiecutter.app_name|to_camel}}TaskHandler)
scheduler := asynq.NewScheduler(redisOpt, &asynq.SchedulerOpts{})
task := asynq.NewTask(biz.{{cookiecutter.app_name|to_camel}}TaskName, nil)
entryID, err := scheduler.Register("*/15 * * * *", task, asynq.TaskID(biz.{{cookiecutter.app_name|to_camel}}TaskName))
checkError(err)
return &AsynqServer{srv: srv, mux: mux, scheduler: scheduler, entryID: entryID}
}
func checkError(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
os.Exit(1)
}
}

View File

@ -0,0 +1,41 @@
package server
import (
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/middleware/logging"
"github.com/go-kratos/kratos/v2/middleware/metadata"
"github.com/go-kratos/kratos/v2/middleware/metrics"
"github.com/go-kratos/kratos/v2/middleware/recovery"
"github.com/go-kratos/kratos/v2/middleware/tracing"
"github.com/go-kratos/kratos/v2/middleware/validate"
"github.com/go-kratos/kratos/v2/transport/grpc"
v1 "{{cookiecutter.go_module}}/api/{{cookiecutter.app_name}}/v1"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/conf"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/service"
)
// NewGRPCServer new a gRPC server.
func NewGRPCServer(c *conf.Server, {{cookiecutter.app_name|to_lower_camel}} *service.{{cookiecutter.app_name|to_camel}}Service, logger log.Logger) *grpc.Server {
var opts = []grpc.ServerOption{
grpc.Middleware(
recovery.Recovery(),
tracing.Server(),
logging.Server(logger),
metrics.Server(),
validate.Validator(),
metadata.Server(metadata.WithPropagatedPrefix("")),
),
}
if c.Grpc.Network != "" {
opts = append(opts, grpc.Network(c.Grpc.Network))
}
if c.Grpc.Addr != "" {
opts = append(opts, grpc.Address(c.Grpc.Addr))
}
if c.Grpc.Timeout != nil {
opts = append(opts, grpc.Timeout(c.Grpc.Timeout.AsDuration()))
}
srv := grpc.NewServer(opts...)
v1.Register{{cookiecutter.app_name|to_camel}}Server(srv, {{cookiecutter.app_name|to_lower_camel}})
return srv
}

View File

@ -0,0 +1,44 @@
package server
import (
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/middleware/logging"
"github.com/go-kratos/kratos/v2/middleware/metadata"
"github.com/go-kratos/kratos/v2/middleware/metrics"
"github.com/go-kratos/kratos/v2/middleware/recovery"
"github.com/go-kratos/kratos/v2/middleware/tracing"
"github.com/go-kratos/kratos/v2/middleware/validate"
"github.com/go-kratos/kratos/v2/transport/http"
"github.com/go-kratos/swagger-api/openapiv2"
v1 "{{cookiecutter.go_module}}/api/{{cookiecutter.app_name}}/v1"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/conf"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/service"
)
// NewHTTPServer new a HTTP server.
func NewHTTPServer(c *conf.Server, {{cookiecutter.app_name|to_lower_camel}} *service.{{cookiecutter.app_name|to_camel}}Service, logger log.Logger) *http.Server {
var opts = []http.ServerOption{
http.Middleware(
recovery.Recovery(),
tracing.Server(),
logging.Server(logger),
metrics.Server(),
validate.Validator(),
metadata.Server(metadata.WithPropagatedPrefix("")),
),
}
if c.Http.Network != "" {
opts = append(opts, http.Network(c.Http.Network))
}
if c.Http.Addr != "" {
opts = append(opts, http.Address(c.Http.Addr))
}
if c.Http.Timeout != nil {
opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))
}
srv := http.NewServer(opts...)
openAPIhandler := openapiv2.NewHandler()
srv.HandlePrefix("/q/", openAPIhandler)
v1.Register{{cookiecutter.app_name|to_camel}}HTTPServer(srv, {{cookiecutter.app_name|to_lower_camel}})
return srv
}

View File

@ -0,0 +1,31 @@
package server
import (
"context"
"github.com/go-kratos/kratos/v2/log"
"github.com/tx7do/kratos-transport/transport/kafka"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/biz"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/conf"
)
// NewKafkaServer new a kafka server.
func NewKafkaServer(c *conf.Queue, uc *biz.{{cookiecutter.app_name|to_camel}}Usecase, logger log.Logger) *kafka.Server {
opts := []kafka.ServerOption{
kafka.WithAddress(c.Kafka.Addrs),
kafka.WithCodec("json"),
kafka.WithGlobalTracerProvider(),
}
if c.Kafka.Username != "" && c.Kafka.Password != "" {
opts = append(opts, kafka.WithPlainMechanism(c.Kafka.Username, c.Kafka.Password))
}
kafkaSrv := kafka.NewServer(opts...)
err := kafkaSrv.RegisterSubscriber(
context.Background(), c.Kafka.Topic, c.Kafka.Group, false,
biz.RegisterExampleHandler(uc.KakfaExampleConsumer),
biz.ExampleCreator,
)
if err != nil {
log.Fatal(err)
}
return kafkaSrv
}

View File

@ -0,0 +1,30 @@
package server
import (
"github.com/go-kratos/kratos/contrib/registry/etcd/v2"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/registry"
etcdclient "go.etcd.io/etcd/client/v3"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/conf"
)
func newEtcd(conf *conf.Server) *etcd.Registry {
client, err := etcdclient.New(etcdclient.Config{
Endpoints: conf.Etcd.Addr,
Username: conf.Etcd.Username,
Password: conf.Etcd.Password,
})
if err != nil {
log.Fatal(err)
}
r := etcd.New(client)
return r
}
func NewDiscovery(conf *conf.Server) registry.Discovery {
return newEtcd(conf)
}
func NewRegistrar(conf *conf.Server) registry.Registrar {
return newEtcd(conf)
}

View File

@ -0,0 +1,6 @@
package server
import "github.com/google/wire"
// ProviderSet is server providers.
var ProviderSet = wire.NewSet(NewHTTPServer, NewGRPCServer, NewRegistrar, NewDiscovery, NewAsynqServer, NewKafkaServer)

View File

@ -0,0 +1,6 @@
package service
import "github.com/google/wire"
// ProviderSet is service providers.
var ProviderSet = wire.NewSet(New{{cookiecutter.app_name|to_camel}}Service)

View File

@ -0,0 +1,31 @@
package service
import (
"context"
"github.com/go-kratos/kratos/v2/log"
v1 "{{cookiecutter.go_module}}/api/{{cookiecutter.app_name}}/v1"
"{{cookiecutter.go_module}}/app/{{cookiecutter.app_name}}/internal/biz"
)
// {{cookiecutter.app_name|to_camel}}Service is a {{cookiecutter.app_name}} service.
type {{cookiecutter.app_name|to_camel}}Service struct {
v1.Unimplemented{{cookiecutter.app_name|to_camel}}Server
uc *biz.{{cookiecutter.app_name|to_camel}}Usecase
log *log.Helper
}
// New{{cookiecutter.app_name|to_camel}}Service new a greeter service.
func New{{cookiecutter.app_name|to_camel}}Service(uc *biz.{{cookiecutter.app_name|to_camel}}Usecase, logger log.Logger) *{{cookiecutter.app_name|to_camel}}Service {
return &{{cookiecutter.app_name|to_camel}}Service{uc: uc, log: log.NewHelper(logger)}
}
// SayHello implements helloworld.{{cookiecutter.app_name|to_camel}}Server
func (s *{{cookiecutter.app_name|to_camel}}Service) SayHello(ctx context.Context, in *v1.HelloRequest) (*v1.HelloReply, error) {
s.log.WithContext(ctx).Infof("SayHello Received: %v", in.GetName())
if in.GetName() == "error" {
return nil, v1.ErrorUserNotFound("user not found: %s", in.GetName())
}
return &v1.HelloReply{Message: "Hello " + in.GetName()}, nil
}

View File

@ -0,0 +1,23 @@
FROM golang:1.17 AS builder
COPY . /src
WORKDIR /src/app/{{cookiecutter.app_name}}
RUN GOPROXY=https://goproxy.cn,direct make build
FROM debian:stable-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
netbase \
&& rm -rf /var/lib/apt/lists/ \
&& apt-get autoremove -y && apt-get autoclean -y
COPY --from=builder /src/app/{{cookiecutter.app_name}}/bin /app
WORKDIR /app
EXPOSE 8001
EXPOSE 9001
VOLUME /data/conf
CMD ["./server", "-conf", "/data/conf"]

View File

@ -0,0 +1,31 @@
apiVersion: v1
data:
conf.yaml: |
server:
http:
addr: 0.0.0.0:8001
timeout: 1s
grpc:
addr: 0.0.0.0:9001
timeout: 1s
etcd:
addr:
- 127.0.0.1:2379
trace_endpoint: http://127.0.0.1:14268/api/traces
data:
database:
{% if cookiecutter.db_driver == 'mysql' -%}
driver: mysql
source: root:@tcp(127.0.0.1:3306)/{{cookiecutter.app_name}}?charset=utf8mb4&parseTime=True&loc=UTC
{%- elif cookiecutter.db_driver == 'postgres' -%}
driver: postgres
source: host=localhost port=5432 user=postgres dbname=example sslmode=disable
{%- endif %}
redis:
addr: 127.0.0.1:6379
read_timeout: 0.2s
write_timeout: 0.2s
kind: ConfigMap
metadata:
name: {{cookiecutter.app_name|to_lower_camel}}-conf
namespace: default

View File

@ -0,0 +1,75 @@
apiVersion: apps/v1 # for versions before 1.8.0 use apps/v1beta1
kind: Deployment
metadata:
name: {{cookiecutter.app_name|to_lower_camel}}-deployment
labels:
app: {{cookiecutter.app_name|to_lower_camel}}
spec:
replicas: 2
selector:
matchLabels:
app: {{cookiecutter.app_name|to_lower_camel}}
template:
metadata:
labels:
app: {{cookiecutter.app_name|to_lower_camel}}
spec:
containers:
- name: {{cookiecutter.app_name|to_lower_camel}}
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
resources:
requests:
memory: "128Mi"
cpu: "128m"
limits:
memory: "256Mi"
cpu: "256m"
volumeMounts:
- mountPath: /data/conf
name: {{cookiecutter.app_name|to_lower_camel}}-conf
volumes:
- configMap:
defaultMode: 420
name: {{cookiecutter.app_name|to_lower_camel}}-conf
name: {{cookiecutter.app_name|to_lower_camel}}-conf
---
apiVersion: apps/v1 # for versions before 1.8.0 use apps/v1beta1
kind: Deployment
metadata:
name: {{cookiecutter.app_name|to_lower_camel}}-worker-deployment
labels:
app: {{cookiecutter.app_name|to_lower_camel}}-worker
spec:
replicas: 2
selector:
matchLabels:
app: {{cookiecutter.app_name|to_lower_camel}}-worker
template:
metadata:
labels:
app: {{cookiecutter.app_name|to_lower_camel}}-worker
spec:
containers:
- name: {{cookiecutter.app_name|to_lower_camel}}-worker
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
resources:
requests:
memory: "128Mi"
cpu: "128m"
limits:
memory: "256Mi"
cpu: "256m"
volumeMounts:
- mountPath: /data/conf
name: {{cookiecutter.app_name|to_lower_camel}}-conf
volumes:
- configMap:
defaultMode: 420
name: {{cookiecutter.app_name|to_lower_camel}}-conf
name: {{cookiecutter.app_name|to_lower_camel}}-conf

View File

@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
name: {{cookiecutter.app_name|to_lower_camel}}-grpc-ingress
namespace: default
spec:
ingressClassName: nginx
tls:
- hosts:
- {{cookiecutter.app_name|to_lower_camel}}.example.com
secretName: {{cookiecutter.app_name|to_lower_camel}}-tls
rules:
- host: {{cookiecutter.app_name|to_lower_camel}}.example.com
http:
paths:
- path: /{{cookiecutter.app_name|to_lower_camel}}.
pathType: Prefix
backend:
service:
name: {{cookiecutter.app_name|to_lower_camel}}-svc
port:
number: 9001

View File

@ -0,0 +1,25 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
name: {{cookiecutter.app_name|to_lower_camel}}-ingress
namespace: default
spec:
ingressClassName: nginx
tls:
- hosts:
- {{cookiecutter.app_name|to_lower_camel}}.example.com
secretName: {{cookiecutter.app_name|to_lower_camel}}-tls
rules:
- host: {{cookiecutter.app_name|to_lower_camel}}.example.com
http:
paths:
- path: /{{cookiecutter.app_name|to_lower_camel}}
pathType: Prefix
backend:
service:
name: {{cookiecutter.app_name|to_lower_camel}}-svc
port:
number: 8001

View File

@ -0,0 +1,25 @@
apiVersion: v1
kind: Service
metadata:
name: {{cookiecutter.app_name|to_lower_camel}}-svc
namespace: default
spec:
clusterIP: None
clusterIPs:
- None
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ports:
- name: http8001
port: 8001
protocol: TCP
targetPort: 8001
- name: grpc9001
port: 9001
protocol: TCP
targetPort: 9001
selector:
app: {{cookiecutter.app_name|to_lower_camel}}
sessionAffinity: None
type: ClusterIP

28
Dockerfile Normal file
View File

@ -0,0 +1,28 @@
FROM golang:1.15 AS builder
ARG APP_RELATIVE_PATH
COPY . /src
WORKDIR /src/app/${APP_RELATIVE_PATH}
RUN GOPROXY=https://goproxy.cn make build
FROM debian:stable-slim
ARG APP_RELATIVE_PATH
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
netbase \
&& rm -rf /var/lib/apt/lists/ \
&& apt-get autoremove -y && apt-get autoclean -y
COPY --from=builder /src/app/${APP_RELATIVE_PATH}/bin /app
WORKDIR /app
EXPOSE 8000
EXPOSE 9000
VOLUME /data/conf
CMD ["./server", "-conf", "/data/conf"]

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 go-kratos
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

22
Makefile Normal file
View File

@ -0,0 +1,22 @@
.PHONY: api
# generate api
api:
find app -type d -depth 1 -print | xargs -L 1 bash -c 'cd "$$0" && pwd && $(MAKE) api'
.PHONY: wire
# generate wire
wire:
find app -type d -depth 1 -print | xargs -L 1 bash -c 'cd "$$0" && pwd && $(MAKE) wire'
# generate wire
build:
find app -type d -depth 1 -print | xargs -L 1 bash -c 'cd "$$0" && pwd && $(MAKE) build'
# build qa for linux
build-linux:
find app -type d -depth 1 -print | xargs -L 1 bash -c 'cd "$$0" && pwd && $(MAKE) build-linux'
.PHONY: proto
# generate proto
proto:
find app -type d -depth 1 -print | xargs -L 1 bash -c 'cd "$$0" && pwd && $(MAKE) proto'

View File

@ -1,3 +1,61 @@
# tkcashgame_v4
# Kratos Project Template
## Install Kratos
```
go get -u github.com/go-kratos/kratos/cmd/kratos/v2@latest
```
## Install deps
```
make init
```
## Create app
```
./create_app.sh
```
## Create a service
```
# Create a template project
kratos new server
cd server
# Add a proto template
kratos proto add api/server/server.proto
# Generate the proto code
kratos proto client api/server/server.proto
# Generate the source code of service by proto file
kratos proto server api/server/server.proto -t internal/service
go generate ./...
go build -o ./bin/ ./...
./bin/server -conf ./configs
```
## Generate other auxiliary files by Makefile
```
# Download and update dependencies
make init
# Generate API swagger json files by proto file
make swagger
# Generate API files (include: pb.go, http, grpc, validate, swagger) by proto file
make api
# Generate all files
make all
```
## Automated Initialization (wire)
```
# install wire
go get github.com/google/wire/cmd/wire
# generate wire
cd cmd/server
wire
```
## Docker
```bash
# build
docker build -t <your-docker-image-name> .
# run
docker run --rm -p 8000:8000 -p 9000:9000 -v </path/to/your/configs>:/data/conf <your-docker-image-name>
```
tk cash game v4

67
Supfile Normal file
View File

@ -0,0 +1,67 @@
# Supfile for engine service
---
version: 0.4
# Global environment variables
env:
DEPLOY_TO: /data/sandc
networks:
staging:
hosts:
- www@127.0.0.1:22
prod:
hosts:
- www@127.0.0.1:22
commands:
ping:
desc: Print OS name and current date/time
run: echo pong `hostname` deploy to ${DEPLOY_TO}/app/${NAME}
compile:
desc: compile service file
local: |
cd app/${NAME}
make linux_build
upload:
desc: Upload service file to server
upload:
- src: ./app/${NAME}/bin/
dst: /tmp/
script: ./deploy_link.sh
restart:
desc: Restart engine service
run: |
sudo supervisorctl restart ${NAME}_server
sudo supervisorctl restart ${NAME}_worker
start:
desc: Start engine service
run: |
sudo supervisorctl start ${NAME}_server
sudo supervisorctl start ${NAME}_worker
stop:
desc: Stop engine service
run: |
sudo supervisorctl stop ${NAME}_server
sudo supervisorctl stop ${NAME}_worker
status:
desc: Return engine current status
run: |
sudo supervisorctl status ${NAME}_server
sudo supervisorctl status ${NAME}_worker
targets:
deploy:
- ping
- compile
- upload
- restart

288
api/eonline/openapi.yaml Normal file
View File

@ -0,0 +1,288 @@
# Generated with protoc-gen-openapi
# https://github.com/google/gnostic/tree/master/cmd/protoc-gen-openapi
openapi: 3.0.3
info:
title: Eonline API
description: The greeting service definition.
version: 0.0.1
paths:
/eonline/pay/init:
post:
tags:
- Eonline
description: PayInit
operationId: Eonline_PayInit
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PayInitReq'
required: true
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/PayInitReply'
default:
description: Default error response
content:
application/json:
schema:
$ref: '#/components/schemas/Status'
/eonline/payout:
post:
tags:
- Eonline
description: Payout
operationId: Eonline_Payout
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PayoutReq'
required: true
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/PayoutReply'
default:
description: Default error response
content:
application/json:
schema:
$ref: '#/components/schemas/Status'
/eonline/payout/callback:
post:
tags:
- Eonline
description: PayoutCallback
operationId: Eonline_PayoutCallback
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PayoutCallbackReq'
required: true
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/PayoutCallbackReply'
default:
description: Default error response
content:
application/json:
schema:
$ref: '#/components/schemas/Status'
/eonline/payout/check:
post:
tags:
- Eonline
description: PayoutCheck
operationId: Eonline_PayoutCheck
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PayoutCheckReq'
required: true
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/PayoutCheckReply'
default:
description: Default error response
content:
application/json:
schema:
$ref: '#/components/schemas/Status'
/eonline/{name}:
get:
tags:
- Eonline
description: Sends a greeting
operationId: Eonline_SayHello
parameters:
- name: name
in: path
required: true
schema:
type: string
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/HelloReply'
default:
description: Default error response
content:
application/json:
schema:
$ref: '#/components/schemas/Status'
components:
schemas:
GoogleProtobufAny:
type: object
properties:
'@type':
type: string
description: The type of the serialized message.
additionalProperties: true
description: Contains an arbitrary serialized message along with a @type that describes the type of the serialized message.
HelloReply:
type: object
properties:
message:
type: string
description: The response message containing the greetings
PayInitReply:
type: object
properties:
uuid:
type: string
items:
type: array
items:
$ref: '#/components/schemas/PayInitReply_Item'
description: PayInitReply init reply
PayInitReply_Item:
type: object
properties:
id:
type: integer
format: int32
amount:
type: number
format: double
status:
type: integer
format: int32
PayInitReq:
type: object
properties:
platform:
type: string
deviceid:
type: string
version:
type: string
ts:
type: string
sign:
type: string
ip:
type: string
description: PayInitReq init request
PayoutCallbackReply:
type: object
properties:
message:
type: string
description: PayoutCallbackReply 赔付回调响应
PayoutCallbackReq:
type: object
properties:
payoutId:
type: string
customCode:
type: string
status:
type: string
msg:
type: string
timestamp:
type: integer
format: int64
description: PayoutCallbackReq 赔付回调请求
PayoutCheckReply:
type: object
properties:
status:
type: integer
format: int32
description: PayoutCheckReply 赔付查询响应
PayoutCheckReq:
type: object
properties:
platform:
type: string
deviceid:
type: string
version:
type: string
ts:
type: string
sign:
type: string
ip:
type: string
recordNo:
type: string
description: PayoutCheckReq 赔付查询请求
PayoutReply:
type: object
properties:
id:
type: string
recordNo:
type: string
description: PayoutReply 赔付响应
PayoutReq:
type: object
properties:
platform:
type: string
deviceid:
type: string
version:
type: string
ts:
type: string
sign:
type: string
account:
type: string
itemId:
type: integer
format: int32
amount:
type: number
format: double
additionalRemark:
type: string
uuid:
type: string
ip:
type: string
description: PayoutReq 赔付请求
Status:
type: object
properties:
code:
type: integer
description: The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].
format: int32
message:
type: string
description: A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.
details:
type: array
items:
$ref: '#/components/schemas/GoogleProtobufAny'
description: A list of messages that carry the error details. There is a common set of message types for APIs to use.
description: 'The `Status` type defines a logical error model that is suitable for different programming environments, including REST APIs and RPC APIs. It is used by [gRPC](https://github.com/grpc). Each `Status` message contains three pieces of data: error code, error message, and error details. You can find out more about this error model and how to work with it in the [API Design Guide](https://cloud.google.com/apis/design/errors).'
tags:
- name: Eonline

View File

@ -0,0 +1,344 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.31.0
// protoc v3.20.3
// source: api/eonline/v1/eonline.proto
package v1
import (
_ "google.golang.org/genproto/googleapis/api/annotations"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
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)
)
// The request message containing the user's name.
type HelloRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}
func (x *HelloRequest) Reset() {
*x = HelloRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_api_eonline_v1_eonline_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *HelloRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HelloRequest) ProtoMessage() {}
func (x *HelloRequest) ProtoReflect() protoreflect.Message {
mi := &file_api_eonline_v1_eonline_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use HelloRequest.ProtoReflect.Descriptor instead.
func (*HelloRequest) Descriptor() ([]byte, []int) {
return file_api_eonline_v1_eonline_proto_rawDescGZIP(), []int{0}
}
func (x *HelloRequest) GetName() string {
if x != nil {
return x.Name
}
return ""
}
// The response message containing the greetings
type HelloReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
}
func (x *HelloReply) Reset() {
*x = HelloReply{}
if protoimpl.UnsafeEnabled {
mi := &file_api_eonline_v1_eonline_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *HelloReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HelloReply) ProtoMessage() {}
func (x *HelloReply) ProtoReflect() protoreflect.Message {
mi := &file_api_eonline_v1_eonline_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use HelloReply.ProtoReflect.Descriptor instead.
func (*HelloReply) Descriptor() ([]byte, []int) {
return file_api_eonline_v1_eonline_proto_rawDescGZIP(), []int{1}
}
func (x *HelloReply) GetMessage() string {
if x != nil {
return x.Message
}
return ""
}
var File_api_eonline_v1_eonline_proto protoreflect.FileDescriptor
var file_api_eonline_v1_eonline_proto_rawDesc = []byte{
0x0a, 0x1c, 0x61, 0x70, 0x69, 0x2f, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2f, 0x76, 0x31,
0x2f, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e,
0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1c,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x61, 0x70,
0x69, 0x2f, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x67,
0x73, 0x6d, 0x69, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x22, 0x0a, 0x0c, 0x48,
0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22,
0x26, 0x0a, 0x0a, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a,
0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0xad, 0x0a, 0x0a, 0x07, 0x45, 0x6f, 0x6e, 0x6c,
0x69, 0x6e, 0x65, 0x12, 0x5e, 0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12,
0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48,
0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x12, 0x12, 0x10, 0x2f, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x34, 0x2f, 0x7b, 0x6e, 0x61,
0x6d, 0x65, 0x7d, 0x12, 0x62, 0x0a, 0x07, 0x50, 0x61, 0x79, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x1a,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x50, 0x61, 0x79, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x79, 0x49,
0x6e, 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17,
0x3a, 0x01, 0x2a, 0x22, 0x12, 0x2f, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x34, 0x2f, 0x70,
0x61, 0x79, 0x2f, 0x69, 0x6e, 0x69, 0x74, 0x12, 0x5d, 0x0a, 0x06, 0x50, 0x61, 0x79, 0x6f, 0x75,
0x74, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x50, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61,
0x79, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x34, 0x2f,
0x70, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x12, 0x69, 0x0a, 0x0c, 0x50, 0x61, 0x79, 0x6f, 0x75, 0x74,
0x42, 0x72, 0x61, 0x7a, 0x69, 0x6c, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e,
0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x52, 0x65,
0x71, 0x1a, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x50, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x21,
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x3a, 0x01, 0x2a, 0x22, 0x16, 0x2f, 0x65, 0x6f, 0x6e, 0x6c,
0x69, 0x6e, 0x65, 0x34, 0x2f, 0x70, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x42, 0x72, 0x61, 0x7a, 0x69,
0x6c, 0x12, 0x7e, 0x0a, 0x0e, 0x50, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x43, 0x61, 0x6c, 0x6c, 0x62,
0x61, 0x63, 0x6b, 0x12, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x43, 0x61, 0x6c, 0x6c, 0x62,
0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x1a, 0x23, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e,
0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x43, 0x61,
0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x24, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65,
0x34, 0x2f, 0x70, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2f, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63,
0x6b, 0x12, 0x72, 0x0a, 0x0b, 0x50, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b,
0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76,
0x31, 0x2e, 0x50, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71,
0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76,
0x31, 0x2e, 0x50, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x70,
0x6c, 0x79, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x3a, 0x01, 0x2a, 0x22, 0x16, 0x2f,
0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x34, 0x2f, 0x70, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2f,
0x63, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x7f, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6f,
0x75, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x73, 0x74, 0x12, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x79, 0x6f, 0x75,
0x74, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x22, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x79,
0x6f, 0x75, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22,
0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x65, 0x6f, 0x6e,
0x6c, 0x69, 0x6e, 0x65, 0x34, 0x2f, 0x67, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x55,
0x73, 0x65, 0x72, 0x4c, 0x73, 0x74, 0x12, 0x7b, 0x0a, 0x0f, 0x53, 0x65, 0x74, 0x50, 0x61, 0x79,
0x6f, 0x75, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x79, 0x6f, 0x75,
0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x1a, 0x21, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x79, 0x6f,
0x75, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x24, 0x82,
0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, 0x65, 0x6f, 0x6e, 0x6c, 0x69,
0x6e, 0x65, 0x34, 0x2f, 0x73, 0x65, 0x74, 0x50, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x61,
0x74, 0x75, 0x73, 0x12, 0x71, 0x0a, 0x0b, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x43, 0x68, 0x65,
0x63, 0x6b, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52,
0x65, 0x71, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52,
0x65, 0x70, 0x6c, 0x79, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x3a, 0x01, 0x2a, 0x22,
0x15, 0x2f, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x34, 0x2f, 0x73, 0x75, 0x62, 0x6d, 0x69,
0x74, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x69, 0x0a, 0x09, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49,
0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65,
0x71, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x70, 0x6c,
0x79, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x65,
0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x34, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x69, 0x6e, 0x66,
0x6f, 0x12, 0x61, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x43, 0x68, 0x61, 0x74, 0x12, 0x1a, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64,
0x64, 0x43, 0x68, 0x61, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65,
0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x43, 0x68, 0x61,
0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x3a, 0x01,
0x2a, 0x22, 0x11, 0x2f, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x34, 0x2f, 0x61, 0x64, 0x64,
0x63, 0x68, 0x61, 0x74, 0x12, 0x61, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x74, 0x12,
0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
0x43, 0x68, 0x61, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x16, 0x3a, 0x01, 0x2a, 0x22, 0x11, 0x2f, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x34, 0x2f,
0x67, 0x65, 0x74, 0x63, 0x68, 0x61, 0x74, 0x42, 0x46, 0x0a, 0x19, 0x64, 0x65, 0x76, 0x2e, 0x6b,
0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e,
0x65, 0x2e, 0x76, 0x31, 0x42, 0x0e, 0x45, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x50, 0x72, 0x6f,
0x74, 0x6f, 0x56, 0x31, 0x50, 0x01, 0x5a, 0x17, 0x73, 0x61, 0x6e, 0x64, 0x63, 0x2f, 0x61, 0x70,
0x69, 0x2f, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_api_eonline_v1_eonline_proto_rawDescOnce sync.Once
file_api_eonline_v1_eonline_proto_rawDescData = file_api_eonline_v1_eonline_proto_rawDesc
)
func file_api_eonline_v1_eonline_proto_rawDescGZIP() []byte {
file_api_eonline_v1_eonline_proto_rawDescOnce.Do(func() {
file_api_eonline_v1_eonline_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_eonline_v1_eonline_proto_rawDescData)
})
return file_api_eonline_v1_eonline_proto_rawDescData
}
var file_api_eonline_v1_eonline_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_api_eonline_v1_eonline_proto_goTypes = []interface{}{
(*HelloRequest)(nil), // 0: api.eonline.v1.HelloRequest
(*HelloReply)(nil), // 1: api.eonline.v1.HelloReply
(*PayInitReq)(nil), // 2: api.eonline.v1.PayInitReq
(*PayoutReq)(nil), // 3: api.eonline.v1.PayoutReq
(*PayoutCallbackReq)(nil), // 4: api.eonline.v1.PayoutCallbackReq
(*PayoutCheckReq)(nil), // 5: api.eonline.v1.PayoutCheckReq
(*PayoutUserLstReq)(nil), // 6: api.eonline.v1.PayoutUserLstReq
(*PayoutStatusReq)(nil), // 7: api.eonline.v1.PayoutStatusReq
(*SubmitCheckReq)(nil), // 8: api.eonline.v1.SubmitCheckReq
(*CheckInfoReq)(nil), // 9: api.eonline.v1.CheckInfoReq
(*AddChatReq)(nil), // 10: api.eonline.v1.AddChatReq
(*GetChatReq)(nil), // 11: api.eonline.v1.GetChatReq
(*PayInitReply)(nil), // 12: api.eonline.v1.PayInitReply
(*PayoutReply)(nil), // 13: api.eonline.v1.PayoutReply
(*PayoutCallbackReply)(nil), // 14: api.eonline.v1.PayoutCallbackReply
(*PayoutCheckReply)(nil), // 15: api.eonline.v1.PayoutCheckReply
(*PayoutUserLstReply)(nil), // 16: api.eonline.v1.PayoutUserLstReply
(*PayoutStatusReply)(nil), // 17: api.eonline.v1.PayoutStatusReply
(*SubmitCheckReply)(nil), // 18: api.eonline.v1.SubmitCheckReply
(*CheckInfoReply)(nil), // 19: api.eonline.v1.CheckInfoReply
(*AddChatReply)(nil), // 20: api.eonline.v1.AddChatReply
(*GetChatReply)(nil), // 21: api.eonline.v1.GetChatReply
}
var file_api_eonline_v1_eonline_proto_depIdxs = []int32{
0, // 0: api.eonline.v1.Eonline.SayHello:input_type -> api.eonline.v1.HelloRequest
2, // 1: api.eonline.v1.Eonline.PayInit:input_type -> api.eonline.v1.PayInitReq
3, // 2: api.eonline.v1.Eonline.Payout:input_type -> api.eonline.v1.PayoutReq
3, // 3: api.eonline.v1.Eonline.PayoutBrazil:input_type -> api.eonline.v1.PayoutReq
4, // 4: api.eonline.v1.Eonline.PayoutCallback:input_type -> api.eonline.v1.PayoutCallbackReq
5, // 5: api.eonline.v1.Eonline.PayoutCheck:input_type -> api.eonline.v1.PayoutCheckReq
6, // 6: api.eonline.v1.Eonline.GetPayoutUserLst:input_type -> api.eonline.v1.PayoutUserLstReq
7, // 7: api.eonline.v1.Eonline.SetPayoutStatus:input_type -> api.eonline.v1.PayoutStatusReq
8, // 8: api.eonline.v1.Eonline.SubmitCheck:input_type -> api.eonline.v1.SubmitCheckReq
9, // 9: api.eonline.v1.Eonline.CheckInfo:input_type -> api.eonline.v1.CheckInfoReq
10, // 10: api.eonline.v1.Eonline.AddChat:input_type -> api.eonline.v1.AddChatReq
11, // 11: api.eonline.v1.Eonline.GetChat:input_type -> api.eonline.v1.GetChatReq
1, // 12: api.eonline.v1.Eonline.SayHello:output_type -> api.eonline.v1.HelloReply
12, // 13: api.eonline.v1.Eonline.PayInit:output_type -> api.eonline.v1.PayInitReply
13, // 14: api.eonline.v1.Eonline.Payout:output_type -> api.eonline.v1.PayoutReply
13, // 15: api.eonline.v1.Eonline.PayoutBrazil:output_type -> api.eonline.v1.PayoutReply
14, // 16: api.eonline.v1.Eonline.PayoutCallback:output_type -> api.eonline.v1.PayoutCallbackReply
15, // 17: api.eonline.v1.Eonline.PayoutCheck:output_type -> api.eonline.v1.PayoutCheckReply
16, // 18: api.eonline.v1.Eonline.GetPayoutUserLst:output_type -> api.eonline.v1.PayoutUserLstReply
17, // 19: api.eonline.v1.Eonline.SetPayoutStatus:output_type -> api.eonline.v1.PayoutStatusReply
18, // 20: api.eonline.v1.Eonline.SubmitCheck:output_type -> api.eonline.v1.SubmitCheckReply
19, // 21: api.eonline.v1.Eonline.CheckInfo:output_type -> api.eonline.v1.CheckInfoReply
20, // 22: api.eonline.v1.Eonline.AddChat:output_type -> api.eonline.v1.AddChatReply
21, // 23: api.eonline.v1.Eonline.GetChat:output_type -> api.eonline.v1.GetChatReply
12, // [12:24] is the sub-list for method output_type
0, // [0:12] 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_api_eonline_v1_eonline_proto_init() }
func file_api_eonline_v1_eonline_proto_init() {
if File_api_eonline_v1_eonline_proto != nil {
return
}
file_api_eonline_v1_pagsmile_proto_init()
if !protoimpl.UnsafeEnabled {
file_api_eonline_v1_eonline_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HelloRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_api_eonline_v1_eonline_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HelloReply); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_api_eonline_v1_eonline_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_api_eonline_v1_eonline_proto_goTypes,
DependencyIndexes: file_api_eonline_v1_eonline_proto_depIdxs,
MessageInfos: file_api_eonline_v1_eonline_proto_msgTypes,
}.Build()
File_api_eonline_v1_eonline_proto = out.File
file_api_eonline_v1_eonline_proto_rawDesc = nil
file_api_eonline_v1_eonline_proto_goTypes = nil
file_api_eonline_v1_eonline_proto_depIdxs = nil
}

View File

@ -0,0 +1,119 @@
syntax = "proto3";
package api.eonline.v1;
import "google/api/annotations.proto";
import "api/eonline/v1/pagsmile.proto";
option go_package = "sandc/api/eonline/v1;v1";
option java_multiple_files = true;
option java_package = "dev.kratos.api.eonline.v1";
option java_outer_classname = "EonlineProtoV1";
// The greeting service definition.
service Eonline {
// Sends a greeting
rpc SayHello(HelloRequest) returns (HelloReply) {
option (google.api.http) = {
get: "/eonline4/{name}"
};
}
// PayInit
rpc PayInit(PayInitReq) returns (PayInitReply) {
option (google.api.http) = {
post: "/eonline4/pay/init"
body: "*"
};
}
// Payout
rpc Payout(PayoutReq) returns (PayoutReply) {
option (google.api.http) = {
post: "/eonline4/payout"
body: "*"
};
}
// PayoutBrazil西PIX支付
rpc PayoutBrazil(PayoutReq) returns (PayoutReply) {
option (google.api.http) = {
post: "/eonline4/payoutBrazil"
body: "*"
};
}
// PayoutCallback
rpc PayoutCallback(PayoutCallbackReq) returns (PayoutCallbackReply) {
option (google.api.http) = {
post: "/eonline4/payout/callback"
body: "*"
};
}
// PayoutCheck
rpc PayoutCheck(PayoutCheckReq) returns (PayoutCheckReply) {
option (google.api.http) = {
post: "/eonline4/payout/check"
body: "*"
};
}
//
rpc GetPayoutUserLst(PayoutUserLstReq) returns (PayoutUserLstReply) {
option (google.api.http) = {
post: "/eonline4/getPayoutUserLst"
body: "*"
};
}
//
rpc SetPayoutStatus(PayoutStatusReq) returns (PayoutStatusReply) {
option (google.api.http) = {
post: "/eonline4/setPayoutStatus"
body: "*"
};
}
// SubmitCheck
rpc SubmitCheck(SubmitCheckReq) returns (SubmitCheckReply) {
option (google.api.http) = {
post: "/eonline4/submitcheck"
body: "*"
};
}
// CheckInfo
rpc CheckInfo(CheckInfoReq) returns (CheckInfoReply) {
option (google.api.http) = {
post: "/eonline4/checkinfo"
body: "*"
};
}
//
rpc AddChat(AddChatReq) returns (AddChatReply) {
option (google.api.http) = {
post: "/eonline4/addchat"
body: "*"
};
}
//
rpc GetChat(GetChatReq) returns (GetChatReply) {
option (google.api.http) = {
post: "/eonline4/getchat"
body: "*"
};
}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}

View File

@ -0,0 +1,136 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.30.0
// protoc v3.21.12
// source: v1/eonline_error.proto
package v1
import (
_ "github.com/go-kratos/kratos/v2/errors"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
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)
)
type EonlineError int32
const (
EonlineError_USER_NOT_FOUND EonlineError = 0
EonlineError_CONTENT_MISSING EonlineError = 1
)
// Enum value maps for EonlineError.
var (
EonlineError_name = map[int32]string{
0: "USER_NOT_FOUND",
1: "CONTENT_MISSING",
}
EonlineError_value = map[string]int32{
"USER_NOT_FOUND": 0,
"CONTENT_MISSING": 1,
}
)
func (x EonlineError) Enum() *EonlineError {
p := new(EonlineError)
*p = x
return p
}
func (x EonlineError) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (EonlineError) Descriptor() protoreflect.EnumDescriptor {
return file_v1_eonline_error_proto_enumTypes[0].Descriptor()
}
func (EonlineError) Type() protoreflect.EnumType {
return &file_v1_eonline_error_proto_enumTypes[0]
}
func (x EonlineError) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use EonlineError.Descriptor instead.
func (EonlineError) EnumDescriptor() ([]byte, []int) {
return file_v1_eonline_error_proto_rawDescGZIP(), []int{0}
}
var File_v1_eonline_error_proto protoreflect.FileDescriptor
var file_v1_eonline_error_proto_rawDesc = []byte{
0x0a, 0x16, 0x76, 0x31, 0x2f, 0x65, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x65, 0x72, 0x72,
0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x61, 0x70, 0x69, 0x2e, 0x65, 0x6f,
0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x13, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73,
0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2a, 0x49, 0x0a,
0x0c, 0x45, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x0a,
0x0e, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10,
0x00, 0x1a, 0x04, 0xa8, 0x45, 0x94, 0x03, 0x12, 0x19, 0x0a, 0x0f, 0x43, 0x4f, 0x4e, 0x54, 0x45,
0x4e, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x1a, 0x04, 0xa8, 0x45,
0x90, 0x03, 0x1a, 0x04, 0xa0, 0x45, 0xf4, 0x03, 0x42, 0x41, 0x0a, 0x11, 0x65, 0x6f, 0x6e, 0x6c,
0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x50, 0x01, 0x5a,
0x17, 0x73, 0x61, 0x6e, 0x64, 0x63, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x65, 0x6f, 0x6e, 0x6c, 0x69,
0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0xa2, 0x02, 0x10, 0x41, 0x50, 0x49, 0x45, 0x6f,
0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
}
var (
file_v1_eonline_error_proto_rawDescOnce sync.Once
file_v1_eonline_error_proto_rawDescData = file_v1_eonline_error_proto_rawDesc
)
func file_v1_eonline_error_proto_rawDescGZIP() []byte {
file_v1_eonline_error_proto_rawDescOnce.Do(func() {
file_v1_eonline_error_proto_rawDescData = protoimpl.X.CompressGZIP(file_v1_eonline_error_proto_rawDescData)
})
return file_v1_eonline_error_proto_rawDescData
}
var file_v1_eonline_error_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_v1_eonline_error_proto_goTypes = []interface{}{
(EonlineError)(0), // 0: api.eonline.v1.EonlineError
}
var file_v1_eonline_error_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_v1_eonline_error_proto_init() }
func file_v1_eonline_error_proto_init() {
if File_v1_eonline_error_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_v1_eonline_error_proto_rawDesc,
NumEnums: 1,
NumMessages: 0,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_v1_eonline_error_proto_goTypes,
DependencyIndexes: file_v1_eonline_error_proto_depIdxs,
EnumInfos: file_v1_eonline_error_proto_enumTypes,
}.Build()
File_v1_eonline_error_proto = out.File
file_v1_eonline_error_proto_rawDesc = nil
file_v1_eonline_error_proto_goTypes = nil
file_v1_eonline_error_proto_depIdxs = nil
}

View File

@ -0,0 +1,36 @@
// Code generated by protoc-gen-validate. DO NOT EDIT.
// source: v1/eonline_error.proto
package v1
import (
"bytes"
"errors"
"fmt"
"net"
"net/mail"
"net/url"
"regexp"
"sort"
"strings"
"time"
"unicode/utf8"
"google.golang.org/protobuf/types/known/anypb"
)
// ensure the imports are used
var (
_ = bytes.MinRead
_ = errors.New("")
_ = fmt.Print
_ = utf8.UTFMax
_ = (*regexp.Regexp)(nil)
_ = (*strings.Reader)(nil)
_ = net.IPv4len
_ = time.Duration(0)
_ = (*url.URL)(nil)
_ = (*mail.Address)(nil)
_ = anypb.Any{}
_ = sort.Sort
)

View File

@ -0,0 +1,16 @@
syntax = "proto3";
package api.eonline.v1;
import "errors/errors.proto";
option go_package = "sandc/api/eonline/v1;v1";
option java_multiple_files = true;
option java_package = "eonline.v1.errors";
option objc_class_prefix = "APIEonlineErrors";
enum EonlineError {
option (errors.default_code) = 500;
USER_NOT_FOUND = 0 [(errors.code) = 404];
CONTENT_MISSING = 1 [(errors.code) = 400];
}

View File

@ -0,0 +1,36 @@
// Code generated by protoc-gen-go-errors. DO NOT EDIT.
package v1
import (
fmt "fmt"
errors "github.com/go-kratos/kratos/v2/errors"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the kratos package it is being compiled against.
const _ = errors.SupportPackageIsVersion1
func IsUserNotFound(err error) bool {
if err == nil {
return false
}
e := errors.FromError(err)
return e.Reason == EonlineError_USER_NOT_FOUND.String() && e.Code == 404
}
func ErrorUserNotFound(format string, args ...interface{}) *errors.Error {
return errors.New(404, EonlineError_USER_NOT_FOUND.String(), fmt.Sprintf(format, args...))
}
func IsContentMissing(err error) bool {
if err == nil {
return false
}
e := errors.FromError(err)
return e.Reason == EonlineError_CONTENT_MISSING.String() && e.Code == 400
}
func ErrorContentMissing(format string, args ...interface{}) *errors.Error {
return errors.New(400, EonlineError_CONTENT_MISSING.String(), fmt.Sprintf(format, args...))
}

View File

@ -0,0 +1,540 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc v3.20.3
// source: api/eonline/v1/eonline.proto
package v1
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const (
Eonline_SayHello_FullMethodName = "/api.eonline.v1.Eonline/SayHello"
Eonline_PayInit_FullMethodName = "/api.eonline.v1.Eonline/PayInit"
Eonline_Payout_FullMethodName = "/api.eonline.v1.Eonline/Payout"
Eonline_PayoutBrazil_FullMethodName = "/api.eonline.v1.Eonline/PayoutBrazil"
Eonline_PayoutCallback_FullMethodName = "/api.eonline.v1.Eonline/PayoutCallback"
Eonline_PayoutCheck_FullMethodName = "/api.eonline.v1.Eonline/PayoutCheck"
Eonline_GetPayoutUserLst_FullMethodName = "/api.eonline.v1.Eonline/GetPayoutUserLst"
Eonline_SetPayoutStatus_FullMethodName = "/api.eonline.v1.Eonline/SetPayoutStatus"
Eonline_SubmitCheck_FullMethodName = "/api.eonline.v1.Eonline/SubmitCheck"
Eonline_CheckInfo_FullMethodName = "/api.eonline.v1.Eonline/CheckInfo"
Eonline_AddChat_FullMethodName = "/api.eonline.v1.Eonline/AddChat"
Eonline_GetChat_FullMethodName = "/api.eonline.v1.Eonline/GetChat"
)
// EonlineClient is the client API for Eonline service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type EonlineClient interface {
// Sends a greeting客户端暂未用到
SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
// PayInit
PayInit(ctx context.Context, in *PayInitReq, opts ...grpc.CallOption) (*PayInitReply, error)
// Payout客户端暂未用到
Payout(ctx context.Context, in *PayoutReq, opts ...grpc.CallOption) (*PayoutReply, error)
// PayoutBrazil用于巴西PIX支付
PayoutBrazil(ctx context.Context, in *PayoutReq, opts ...grpc.CallOption) (*PayoutReply, error)
// PayoutCallback客户端暂未用到
PayoutCallback(ctx context.Context, in *PayoutCallbackReq, opts ...grpc.CallOption) (*PayoutCallbackReply, error)
// PayoutCheck
PayoutCheck(ctx context.Context, in *PayoutCheckReq, opts ...grpc.CallOption) (*PayoutCheckReply, error)
// 获取申请提现玩家的列表
GetPayoutUserLst(ctx context.Context, in *PayoutUserLstReq, opts ...grpc.CallOption) (*PayoutUserLstReply, error)
// 设置指定玩家的提现状态
SetPayoutStatus(ctx context.Context, in *PayoutStatusReq, opts ...grpc.CallOption) (*PayoutStatusReply, error)
// SubmitCheck客户端暂未用到
SubmitCheck(ctx context.Context, in *SubmitCheckReq, opts ...grpc.CallOption) (*SubmitCheckReply, error)
// CheckInfo客户端暂未用到
CheckInfo(ctx context.Context, in *CheckInfoReq, opts ...grpc.CallOption) (*CheckInfoReply, error)
// 发送聊天消息,客户端暂未用到
AddChat(ctx context.Context, in *AddChatReq, opts ...grpc.CallOption) (*AddChatReply, error)
// 获取聊天消息列表,客户端暂未用到
GetChat(ctx context.Context, in *GetChatReq, opts ...grpc.CallOption) (*GetChatReply, error)
}
type eonlineClient struct {
cc grpc.ClientConnInterface
}
func NewEonlineClient(cc grpc.ClientConnInterface) EonlineClient {
return &eonlineClient{cc}
}
func (c *eonlineClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) {
out := new(HelloReply)
err := c.cc.Invoke(ctx, Eonline_SayHello_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *eonlineClient) PayInit(ctx context.Context, in *PayInitReq, opts ...grpc.CallOption) (*PayInitReply, error) {
out := new(PayInitReply)
err := c.cc.Invoke(ctx, Eonline_PayInit_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *eonlineClient) Payout(ctx context.Context, in *PayoutReq, opts ...grpc.CallOption) (*PayoutReply, error) {
out := new(PayoutReply)
err := c.cc.Invoke(ctx, Eonline_Payout_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *eonlineClient) PayoutBrazil(ctx context.Context, in *PayoutReq, opts ...grpc.CallOption) (*PayoutReply, error) {
out := new(PayoutReply)
err := c.cc.Invoke(ctx, Eonline_PayoutBrazil_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *eonlineClient) PayoutCallback(ctx context.Context, in *PayoutCallbackReq, opts ...grpc.CallOption) (*PayoutCallbackReply, error) {
out := new(PayoutCallbackReply)
err := c.cc.Invoke(ctx, Eonline_PayoutCallback_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *eonlineClient) PayoutCheck(ctx context.Context, in *PayoutCheckReq, opts ...grpc.CallOption) (*PayoutCheckReply, error) {
out := new(PayoutCheckReply)
err := c.cc.Invoke(ctx, Eonline_PayoutCheck_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *eonlineClient) GetPayoutUserLst(ctx context.Context, in *PayoutUserLstReq, opts ...grpc.CallOption) (*PayoutUserLstReply, error) {
out := new(PayoutUserLstReply)
err := c.cc.Invoke(ctx, Eonline_GetPayoutUserLst_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *eonlineClient) SetPayoutStatus(ctx context.Context, in *PayoutStatusReq, opts ...grpc.CallOption) (*PayoutStatusReply, error) {
out := new(PayoutStatusReply)
err := c.cc.Invoke(ctx, Eonline_SetPayoutStatus_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *eonlineClient) SubmitCheck(ctx context.Context, in *SubmitCheckReq, opts ...grpc.CallOption) (*SubmitCheckReply, error) {
out := new(SubmitCheckReply)
err := c.cc.Invoke(ctx, Eonline_SubmitCheck_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *eonlineClient) CheckInfo(ctx context.Context, in *CheckInfoReq, opts ...grpc.CallOption) (*CheckInfoReply, error) {
out := new(CheckInfoReply)
err := c.cc.Invoke(ctx, Eonline_CheckInfo_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *eonlineClient) AddChat(ctx context.Context, in *AddChatReq, opts ...grpc.CallOption) (*AddChatReply, error) {
out := new(AddChatReply)
err := c.cc.Invoke(ctx, Eonline_AddChat_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *eonlineClient) GetChat(ctx context.Context, in *GetChatReq, opts ...grpc.CallOption) (*GetChatReply, error) {
out := new(GetChatReply)
err := c.cc.Invoke(ctx, Eonline_GetChat_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// EonlineServer is the server API for Eonline service.
// All implementations must embed UnimplementedEonlineServer
// for forward compatibility
type EonlineServer interface {
// Sends a greeting客户端暂未用到
SayHello(context.Context, *HelloRequest) (*HelloReply, error)
// PayInit
PayInit(context.Context, *PayInitReq) (*PayInitReply, error)
// Payout客户端暂未用到
Payout(context.Context, *PayoutReq) (*PayoutReply, error)
// PayoutBrazil用于巴西PIX支付
PayoutBrazil(context.Context, *PayoutReq) (*PayoutReply, error)
// PayoutCallback客户端暂未用到
PayoutCallback(context.Context, *PayoutCallbackReq) (*PayoutCallbackReply, error)
// PayoutCheck
PayoutCheck(context.Context, *PayoutCheckReq) (*PayoutCheckReply, error)
// 获取申请提现玩家的列表
GetPayoutUserLst(context.Context, *PayoutUserLstReq) (*PayoutUserLstReply, error)
// 设置指定玩家的提现状态
SetPayoutStatus(context.Context, *PayoutStatusReq) (*PayoutStatusReply, error)
// SubmitCheck客户端暂未用到
SubmitCheck(context.Context, *SubmitCheckReq) (*SubmitCheckReply, error)
// CheckInfo客户端暂未用到
CheckInfo(context.Context, *CheckInfoReq) (*CheckInfoReply, error)
// 发送聊天消息,客户端暂未用到
AddChat(context.Context, *AddChatReq) (*AddChatReply, error)
// 获取聊天消息列表,客户端暂未用到
GetChat(context.Context, *GetChatReq) (*GetChatReply, error)
mustEmbedUnimplementedEonlineServer()
}
// UnimplementedEonlineServer must be embedded to have forward compatible implementations.
type UnimplementedEonlineServer struct {
}
func (UnimplementedEonlineServer) SayHello(context.Context, *HelloRequest) (*HelloReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented")
}
func (UnimplementedEonlineServer) PayInit(context.Context, *PayInitReq) (*PayInitReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method PayInit not implemented")
}
func (UnimplementedEonlineServer) Payout(context.Context, *PayoutReq) (*PayoutReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Payout not implemented")
}
func (UnimplementedEonlineServer) PayoutBrazil(context.Context, *PayoutReq) (*PayoutReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method PayoutBrazil not implemented")
}
func (UnimplementedEonlineServer) PayoutCallback(context.Context, *PayoutCallbackReq) (*PayoutCallbackReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method PayoutCallback not implemented")
}
func (UnimplementedEonlineServer) PayoutCheck(context.Context, *PayoutCheckReq) (*PayoutCheckReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method PayoutCheck not implemented")
}
func (UnimplementedEonlineServer) GetPayoutUserLst(context.Context, *PayoutUserLstReq) (*PayoutUserLstReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetPayoutUserLst not implemented")
}
func (UnimplementedEonlineServer) SetPayoutStatus(context.Context, *PayoutStatusReq) (*PayoutStatusReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method SetPayoutStatus not implemented")
}
func (UnimplementedEonlineServer) SubmitCheck(context.Context, *SubmitCheckReq) (*SubmitCheckReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method SubmitCheck not implemented")
}
func (UnimplementedEonlineServer) CheckInfo(context.Context, *CheckInfoReq) (*CheckInfoReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method CheckInfo not implemented")
}
func (UnimplementedEonlineServer) AddChat(context.Context, *AddChatReq) (*AddChatReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method AddChat not implemented")
}
func (UnimplementedEonlineServer) GetChat(context.Context, *GetChatReq) (*GetChatReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetChat not implemented")
}
func (UnimplementedEonlineServer) mustEmbedUnimplementedEonlineServer() {}
// UnsafeEonlineServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to EonlineServer will
// result in compilation errors.
type UnsafeEonlineServer interface {
mustEmbedUnimplementedEonlineServer()
}
func RegisterEonlineServer(s grpc.ServiceRegistrar, srv EonlineServer) {
s.RegisterService(&Eonline_ServiceDesc, srv)
}
func _Eonline_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(HelloRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EonlineServer).SayHello(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Eonline_SayHello_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EonlineServer).SayHello(ctx, req.(*HelloRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Eonline_PayInit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PayInitReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EonlineServer).PayInit(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Eonline_PayInit_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EonlineServer).PayInit(ctx, req.(*PayInitReq))
}
return interceptor(ctx, in, info, handler)
}
func _Eonline_Payout_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PayoutReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EonlineServer).Payout(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Eonline_Payout_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EonlineServer).Payout(ctx, req.(*PayoutReq))
}
return interceptor(ctx, in, info, handler)
}
func _Eonline_PayoutBrazil_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PayoutReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EonlineServer).PayoutBrazil(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Eonline_PayoutBrazil_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EonlineServer).PayoutBrazil(ctx, req.(*PayoutReq))
}
return interceptor(ctx, in, info, handler)
}
func _Eonline_PayoutCallback_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PayoutCallbackReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EonlineServer).PayoutCallback(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Eonline_PayoutCallback_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EonlineServer).PayoutCallback(ctx, req.(*PayoutCallbackReq))
}
return interceptor(ctx, in, info, handler)
}
func _Eonline_PayoutCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PayoutCheckReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EonlineServer).PayoutCheck(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Eonline_PayoutCheck_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EonlineServer).PayoutCheck(ctx, req.(*PayoutCheckReq))
}
return interceptor(ctx, in, info, handler)
}
func _Eonline_GetPayoutUserLst_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PayoutUserLstReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EonlineServer).GetPayoutUserLst(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Eonline_GetPayoutUserLst_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EonlineServer).GetPayoutUserLst(ctx, req.(*PayoutUserLstReq))
}
return interceptor(ctx, in, info, handler)
}
func _Eonline_SetPayoutStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(PayoutStatusReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EonlineServer).SetPayoutStatus(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Eonline_SetPayoutStatus_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EonlineServer).SetPayoutStatus(ctx, req.(*PayoutStatusReq))
}
return interceptor(ctx, in, info, handler)
}
func _Eonline_SubmitCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SubmitCheckReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EonlineServer).SubmitCheck(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Eonline_SubmitCheck_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EonlineServer).SubmitCheck(ctx, req.(*SubmitCheckReq))
}
return interceptor(ctx, in, info, handler)
}
func _Eonline_CheckInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CheckInfoReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EonlineServer).CheckInfo(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Eonline_CheckInfo_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EonlineServer).CheckInfo(ctx, req.(*CheckInfoReq))
}
return interceptor(ctx, in, info, handler)
}
func _Eonline_AddChat_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AddChatReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EonlineServer).AddChat(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Eonline_AddChat_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EonlineServer).AddChat(ctx, req.(*AddChatReq))
}
return interceptor(ctx, in, info, handler)
}
func _Eonline_GetChat_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetChatReq)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EonlineServer).GetChat(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Eonline_GetChat_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EonlineServer).GetChat(ctx, req.(*GetChatReq))
}
return interceptor(ctx, in, info, handler)
}
// Eonline_ServiceDesc is the grpc.ServiceDesc for Eonline service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Eonline_ServiceDesc = grpc.ServiceDesc{
ServiceName: "api.eonline.v1.Eonline",
HandlerType: (*EonlineServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "SayHello",
Handler: _Eonline_SayHello_Handler,
},
{
MethodName: "PayInit",
Handler: _Eonline_PayInit_Handler,
},
{
MethodName: "Payout",
Handler: _Eonline_Payout_Handler,
},
{
MethodName: "PayoutBrazil",
Handler: _Eonline_PayoutBrazil_Handler,
},
{
MethodName: "PayoutCallback",
Handler: _Eonline_PayoutCallback_Handler,
},
{
MethodName: "PayoutCheck",
Handler: _Eonline_PayoutCheck_Handler,
},
{
MethodName: "GetPayoutUserLst",
Handler: _Eonline_GetPayoutUserLst_Handler,
},
{
MethodName: "SetPayoutStatus",
Handler: _Eonline_SetPayoutStatus_Handler,
},
{
MethodName: "SubmitCheck",
Handler: _Eonline_SubmitCheck_Handler,
},
{
MethodName: "CheckInfo",
Handler: _Eonline_CheckInfo_Handler,
},
{
MethodName: "AddChat",
Handler: _Eonline_AddChat_Handler,
},
{
MethodName: "GetChat",
Handler: _Eonline_GetChat_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "api/eonline/v1/eonline.proto",
}

View File

@ -0,0 +1,519 @@
// Code generated by protoc-gen-go-http. DO NOT EDIT.
// versions:
// - protoc-gen-go-http v2.7.0
// - protoc v3.20.3
// source: api/eonline/v1/eonline.proto
package v1
import (
context "context"
http "github.com/go-kratos/kratos/v2/transport/http"
binding "github.com/go-kratos/kratos/v2/transport/http/binding"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the kratos package it is being compiled against.
var _ = new(context.Context)
var _ = binding.EncodeURL
const _ = http.SupportPackageIsVersion1
const OperationEonlineAddChat = "/api.eonline.v1.Eonline/AddChat"
const OperationEonlineCheckInfo = "/api.eonline.v1.Eonline/CheckInfo"
const OperationEonlineGetChat = "/api.eonline.v1.Eonline/GetChat"
const OperationEonlineGetPayoutUserLst = "/api.eonline.v1.Eonline/GetPayoutUserLst"
const OperationEonlinePayInit = "/api.eonline.v1.Eonline/PayInit"
const OperationEonlinePayout = "/api.eonline.v1.Eonline/Payout"
const OperationEonlinePayoutBrazil = "/api.eonline.v1.Eonline/PayoutBrazil"
const OperationEonlinePayoutCallback = "/api.eonline.v1.Eonline/PayoutCallback"
const OperationEonlinePayoutCheck = "/api.eonline.v1.Eonline/PayoutCheck"
const OperationEonlineSayHello = "/api.eonline.v1.Eonline/SayHello"
const OperationEonlineSetPayoutStatus = "/api.eonline.v1.Eonline/SetPayoutStatus"
const OperationEonlineSubmitCheck = "/api.eonline.v1.Eonline/SubmitCheck"
type EonlineHTTPServer interface {
// AddChat 发送聊天消息,客户端暂未用到
AddChat(context.Context, *AddChatReq) (*AddChatReply, error)
// CheckInfo CheckInfo客户端暂未用到
CheckInfo(context.Context, *CheckInfoReq) (*CheckInfoReply, error)
// GetChat 获取聊天消息列表,客户端暂未用到
GetChat(context.Context, *GetChatReq) (*GetChatReply, error)
// GetPayoutUserLst 获取申请提现玩家的列表
GetPayoutUserLst(context.Context, *PayoutUserLstReq) (*PayoutUserLstReply, error)
// PayInit PayInit
PayInit(context.Context, *PayInitReq) (*PayInitReply, error)
// Payout Payout客户端暂未用到
Payout(context.Context, *PayoutReq) (*PayoutReply, error)
// PayoutBrazil PayoutBrazil用于巴西PIX支付
PayoutBrazil(context.Context, *PayoutReq) (*PayoutReply, error)
// PayoutCallback PayoutCallback客户端暂未用到
PayoutCallback(context.Context, *PayoutCallbackReq) (*PayoutCallbackReply, error)
// PayoutCheck PayoutCheck
PayoutCheck(context.Context, *PayoutCheckReq) (*PayoutCheckReply, error)
// SayHello Sends a greeting客户端暂未用到
SayHello(context.Context, *HelloRequest) (*HelloReply, error)
// SetPayoutStatus 设置指定玩家的提现状态
SetPayoutStatus(context.Context, *PayoutStatusReq) (*PayoutStatusReply, error)
// SubmitCheck SubmitCheck客户端暂未用到
SubmitCheck(context.Context, *SubmitCheckReq) (*SubmitCheckReply, error)
}
func RegisterEonlineHTTPServer(s *http.Server, srv EonlineHTTPServer) {
r := s.Route("/")
r.GET("/eonline4/{name}", _Eonline_SayHello0_HTTP_Handler(srv))
r.POST("/eonline4/pay/init", _Eonline_PayInit0_HTTP_Handler(srv))
r.POST("/eonline4/payout", _Eonline_Payout0_HTTP_Handler(srv))
r.POST("/eonline4/payoutBrazil", _Eonline_PayoutBrazil0_HTTP_Handler(srv))
r.POST("/eonline4/payout/callback", _Eonline_PayoutCallback0_HTTP_Handler(srv))
r.POST("/eonline4/payout/check", _Eonline_PayoutCheck0_HTTP_Handler(srv))
r.POST("/eonline4/getPayoutUserLst", _Eonline_GetPayoutUserLst0_HTTP_Handler(srv))
r.POST("/eonline4/setPayoutStatus", _Eonline_SetPayoutStatus0_HTTP_Handler(srv))
r.POST("/eonline4/submitcheck", _Eonline_SubmitCheck0_HTTP_Handler(srv))
r.POST("/eonline4/checkinfo", _Eonline_CheckInfo0_HTTP_Handler(srv))
r.POST("/eonline4/addchat", _Eonline_AddChat0_HTTP_Handler(srv))
r.POST("/eonline4/getchat", _Eonline_GetChat0_HTTP_Handler(srv))
}
func _Eonline_SayHello0_HTTP_Handler(srv EonlineHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in HelloRequest
if err := ctx.BindQuery(&in); err != nil {
return err
}
if err := ctx.BindVars(&in); err != nil {
return err
}
http.SetOperation(ctx, OperationEonlineSayHello)
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.SayHello(ctx, req.(*HelloRequest))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*HelloReply)
return ctx.Result(200, reply)
}
}
func _Eonline_PayInit0_HTTP_Handler(srv EonlineHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in PayInitReq
if err := ctx.Bind(&in); err != nil {
return err
}
if err := ctx.BindQuery(&in); err != nil {
return err
}
http.SetOperation(ctx, OperationEonlinePayInit)
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.PayInit(ctx, req.(*PayInitReq))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*PayInitReply)
return ctx.Result(200, reply)
}
}
func _Eonline_Payout0_HTTP_Handler(srv EonlineHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in PayoutReq
if err := ctx.Bind(&in); err != nil {
return err
}
if err := ctx.BindQuery(&in); err != nil {
return err
}
http.SetOperation(ctx, OperationEonlinePayout)
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.Payout(ctx, req.(*PayoutReq))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*PayoutReply)
return ctx.Result(200, reply)
}
}
func _Eonline_PayoutBrazil0_HTTP_Handler(srv EonlineHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in PayoutReq
if err := ctx.Bind(&in); err != nil {
return err
}
if err := ctx.BindQuery(&in); err != nil {
return err
}
http.SetOperation(ctx, OperationEonlinePayoutBrazil)
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.PayoutBrazil(ctx, req.(*PayoutReq))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*PayoutReply)
return ctx.Result(200, reply)
}
}
func _Eonline_PayoutCallback0_HTTP_Handler(srv EonlineHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in PayoutCallbackReq
if err := ctx.Bind(&in); err != nil {
return err
}
if err := ctx.BindQuery(&in); err != nil {
return err
}
http.SetOperation(ctx, OperationEonlinePayoutCallback)
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.PayoutCallback(ctx, req.(*PayoutCallbackReq))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*PayoutCallbackReply)
return ctx.Result(200, reply)
}
}
func _Eonline_PayoutCheck0_HTTP_Handler(srv EonlineHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in PayoutCheckReq
if err := ctx.Bind(&in); err != nil {
return err
}
if err := ctx.BindQuery(&in); err != nil {
return err
}
http.SetOperation(ctx, OperationEonlinePayoutCheck)
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.PayoutCheck(ctx, req.(*PayoutCheckReq))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*PayoutCheckReply)
return ctx.Result(200, reply)
}
}
func _Eonline_GetPayoutUserLst0_HTTP_Handler(srv EonlineHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in PayoutUserLstReq
if err := ctx.Bind(&in); err != nil {
return err
}
if err := ctx.BindQuery(&in); err != nil {
return err
}
http.SetOperation(ctx, OperationEonlineGetPayoutUserLst)
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.GetPayoutUserLst(ctx, req.(*PayoutUserLstReq))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*PayoutUserLstReply)
return ctx.Result(200, reply)
}
}
func _Eonline_SetPayoutStatus0_HTTP_Handler(srv EonlineHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in PayoutStatusReq
if err := ctx.Bind(&in); err != nil {
return err
}
if err := ctx.BindQuery(&in); err != nil {
return err
}
http.SetOperation(ctx, OperationEonlineSetPayoutStatus)
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.SetPayoutStatus(ctx, req.(*PayoutStatusReq))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*PayoutStatusReply)
return ctx.Result(200, reply)
}
}
func _Eonline_SubmitCheck0_HTTP_Handler(srv EonlineHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in SubmitCheckReq
if err := ctx.Bind(&in); err != nil {
return err
}
if err := ctx.BindQuery(&in); err != nil {
return err
}
http.SetOperation(ctx, OperationEonlineSubmitCheck)
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.SubmitCheck(ctx, req.(*SubmitCheckReq))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*SubmitCheckReply)
return ctx.Result(200, reply)
}
}
func _Eonline_CheckInfo0_HTTP_Handler(srv EonlineHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in CheckInfoReq
if err := ctx.Bind(&in); err != nil {
return err
}
if err := ctx.BindQuery(&in); err != nil {
return err
}
http.SetOperation(ctx, OperationEonlineCheckInfo)
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.CheckInfo(ctx, req.(*CheckInfoReq))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*CheckInfoReply)
return ctx.Result(200, reply)
}
}
func _Eonline_AddChat0_HTTP_Handler(srv EonlineHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in AddChatReq
if err := ctx.Bind(&in); err != nil {
return err
}
if err := ctx.BindQuery(&in); err != nil {
return err
}
http.SetOperation(ctx, OperationEonlineAddChat)
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.AddChat(ctx, req.(*AddChatReq))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*AddChatReply)
return ctx.Result(200, reply)
}
}
func _Eonline_GetChat0_HTTP_Handler(srv EonlineHTTPServer) func(ctx http.Context) error {
return func(ctx http.Context) error {
var in GetChatReq
if err := ctx.Bind(&in); err != nil {
return err
}
if err := ctx.BindQuery(&in); err != nil {
return err
}
http.SetOperation(ctx, OperationEonlineGetChat)
h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.GetChat(ctx, req.(*GetChatReq))
})
out, err := h(ctx, &in)
if err != nil {
return err
}
reply := out.(*GetChatReply)
return ctx.Result(200, reply)
}
}
type EonlineHTTPClient interface {
AddChat(ctx context.Context, req *AddChatReq, opts ...http.CallOption) (rsp *AddChatReply, err error)
CheckInfo(ctx context.Context, req *CheckInfoReq, opts ...http.CallOption) (rsp *CheckInfoReply, err error)
GetChat(ctx context.Context, req *GetChatReq, opts ...http.CallOption) (rsp *GetChatReply, err error)
GetPayoutUserLst(ctx context.Context, req *PayoutUserLstReq, opts ...http.CallOption) (rsp *PayoutUserLstReply, err error)
PayInit(ctx context.Context, req *PayInitReq, opts ...http.CallOption) (rsp *PayInitReply, err error)
Payout(ctx context.Context, req *PayoutReq, opts ...http.CallOption) (rsp *PayoutReply, err error)
PayoutBrazil(ctx context.Context, req *PayoutReq, opts ...http.CallOption) (rsp *PayoutReply, err error)
PayoutCallback(ctx context.Context, req *PayoutCallbackReq, opts ...http.CallOption) (rsp *PayoutCallbackReply, err error)
PayoutCheck(ctx context.Context, req *PayoutCheckReq, opts ...http.CallOption) (rsp *PayoutCheckReply, err error)
SayHello(ctx context.Context, req *HelloRequest, opts ...http.CallOption) (rsp *HelloReply, err error)
SetPayoutStatus(ctx context.Context, req *PayoutStatusReq, opts ...http.CallOption) (rsp *PayoutStatusReply, err error)
SubmitCheck(ctx context.Context, req *SubmitCheckReq, opts ...http.CallOption) (rsp *SubmitCheckReply, err error)
}
type EonlineHTTPClientImpl struct {
cc *http.Client
}
func NewEonlineHTTPClient(client *http.Client) EonlineHTTPClient {
return &EonlineHTTPClientImpl{client}
}
func (c *EonlineHTTPClientImpl) AddChat(ctx context.Context, in *AddChatReq, opts ...http.CallOption) (*AddChatReply, error) {
var out AddChatReply
pattern := "/eonline4/addchat"
path := binding.EncodeURL(pattern, in, false)
opts = append(opts, http.Operation(OperationEonlineAddChat))
opts = append(opts, http.PathTemplate(pattern))
err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *EonlineHTTPClientImpl) CheckInfo(ctx context.Context, in *CheckInfoReq, opts ...http.CallOption) (*CheckInfoReply, error) {
var out CheckInfoReply
pattern := "/eonline4/checkinfo"
path := binding.EncodeURL(pattern, in, false)
opts = append(opts, http.Operation(OperationEonlineCheckInfo))
opts = append(opts, http.PathTemplate(pattern))
err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *EonlineHTTPClientImpl) GetChat(ctx context.Context, in *GetChatReq, opts ...http.CallOption) (*GetChatReply, error) {
var out GetChatReply
pattern := "/eonline4/getchat"
path := binding.EncodeURL(pattern, in, false)
opts = append(opts, http.Operation(OperationEonlineGetChat))
opts = append(opts, http.PathTemplate(pattern))
err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *EonlineHTTPClientImpl) GetPayoutUserLst(ctx context.Context, in *PayoutUserLstReq, opts ...http.CallOption) (*PayoutUserLstReply, error) {
var out PayoutUserLstReply
pattern := "/eonline4/getPayoutUserLst"
path := binding.EncodeURL(pattern, in, false)
opts = append(opts, http.Operation(OperationEonlineGetPayoutUserLst))
opts = append(opts, http.PathTemplate(pattern))
err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *EonlineHTTPClientImpl) PayInit(ctx context.Context, in *PayInitReq, opts ...http.CallOption) (*PayInitReply, error) {
var out PayInitReply
pattern := "/eonline4/pay/init"
path := binding.EncodeURL(pattern, in, false)
opts = append(opts, http.Operation(OperationEonlinePayInit))
opts = append(opts, http.PathTemplate(pattern))
err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *EonlineHTTPClientImpl) Payout(ctx context.Context, in *PayoutReq, opts ...http.CallOption) (*PayoutReply, error) {
var out PayoutReply
pattern := "/eonline4/payout"
path := binding.EncodeURL(pattern, in, false)
opts = append(opts, http.Operation(OperationEonlinePayout))
opts = append(opts, http.PathTemplate(pattern))
err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *EonlineHTTPClientImpl) PayoutBrazil(ctx context.Context, in *PayoutReq, opts ...http.CallOption) (*PayoutReply, error) {
var out PayoutReply
pattern := "/eonline4/payoutBrazil"
path := binding.EncodeURL(pattern, in, false)
opts = append(opts, http.Operation(OperationEonlinePayoutBrazil))
opts = append(opts, http.PathTemplate(pattern))
err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *EonlineHTTPClientImpl) PayoutCallback(ctx context.Context, in *PayoutCallbackReq, opts ...http.CallOption) (*PayoutCallbackReply, error) {
var out PayoutCallbackReply
pattern := "/eonline4/payout/callback"
path := binding.EncodeURL(pattern, in, false)
opts = append(opts, http.Operation(OperationEonlinePayoutCallback))
opts = append(opts, http.PathTemplate(pattern))
err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *EonlineHTTPClientImpl) PayoutCheck(ctx context.Context, in *PayoutCheckReq, opts ...http.CallOption) (*PayoutCheckReply, error) {
var out PayoutCheckReply
pattern := "/eonline4/payout/check"
path := binding.EncodeURL(pattern, in, false)
opts = append(opts, http.Operation(OperationEonlinePayoutCheck))
opts = append(opts, http.PathTemplate(pattern))
err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *EonlineHTTPClientImpl) SayHello(ctx context.Context, in *HelloRequest, opts ...http.CallOption) (*HelloReply, error) {
var out HelloReply
pattern := "/eonline4/{name}"
path := binding.EncodeURL(pattern, in, true)
opts = append(opts, http.Operation(OperationEonlineSayHello))
opts = append(opts, http.PathTemplate(pattern))
err := c.cc.Invoke(ctx, "GET", path, nil, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *EonlineHTTPClientImpl) SetPayoutStatus(ctx context.Context, in *PayoutStatusReq, opts ...http.CallOption) (*PayoutStatusReply, error) {
var out PayoutStatusReply
pattern := "/eonline4/setPayoutStatus"
path := binding.EncodeURL(pattern, in, false)
opts = append(opts, http.Operation(OperationEonlineSetPayoutStatus))
opts = append(opts, http.PathTemplate(pattern))
err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}
func (c *EonlineHTTPClientImpl) SubmitCheck(ctx context.Context, in *SubmitCheckReq, opts ...http.CallOption) (*SubmitCheckReply, error) {
var out SubmitCheckReply
pattern := "/eonline4/submitcheck"
path := binding.EncodeURL(pattern, in, false)
opts = append(opts, http.Operation(OperationEonlineSubmitCheck))
opts = append(opts, http.PathTemplate(pattern))
err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...)
if err != nil {
return nil, err
}
return &out, err
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,308 @@
syntax = "proto3";
package api.eonline.v1;
import "validate/validate.proto";
option go_package = "sandc/api/eonline/v1;v1";
// PayInitReq init request
message PayInitReq {
string platform = 1 [(validate.rules).string.min_len = 1];
string deviceid = 2 [(validate.rules).string.min_len = 1];
string version = 3 [(validate.rules).string.min_len = 1]; // 2.0.022299.99
string ip = 4; //
string ts = 5 [(validate.rules).string.min_len = 1]; // utc时间秒ts当成登录时间计算
string sign = 6 [(validate.rules).string.min_len = 1];
}
// PayInitReply init reply
message PayInitReply {
string uuid = 1; //
message Item {
uint32 id = 1; // id
double amount = 2; //
uint32 status = 3; // :1 2: 3:id已提现成功, 4:, 5:
}
uint32 days = 2; // 1
repeated Item items = 3; //
int32 CanCheckSubmit = 4; // 01
int32 CheckSubmit = 5; // 01
int32 CheckResult = 6; // 012
int32 CheckPayout = 7; // 50123
int32 CheckCoin = 8; //
int32 CanCheckPayOut = 9; // 5 012
string CheckResultFailedDesc = 10; // CheckResult==1
int32 error = 11; // 01234 ts长度错误
string clientData = 12; //
}
message PbReportDataAdjust {
string gps_adid = 1; // gaid
string android_id = 2; // ID
string adid = 3; // Adjust
string user_agent = 4; // User-Agent URL
string price = 5; // 0.05
string currency = 6; // USD
}
message PbReportDataShuShu {
string gps_gaid = 1; // gaid
string android_id = 2; // ID
string adid = 3; // Adjust
string user_agent = 4; // User-Agent URL
string price = 5; // 0.05
string currency = 6; // USD
string payment_method = 7; // pix
string payment_type = 8; // cpf/cnpj/evp/email/phone
string payment_number = 9; //
string iap_name = 10; // 0.1br/50br/100br
string gamecoin_number = 11; // 1500
string gamecoin_type = 12; // coin/money
string ss_account_id = 13; // ID ID()
string ss_distinct_id = 14; // 访ID ID()
string ss_super_properties = 15; // json字符串
}
// PayoutReq
message PayoutReq {
string platform = 1 [(validate.rules).string.min_len = 1];
string deviceid = 2 [(validate.rules).string.min_len = 1];
string version = 3 [(validate.rules).string.min_len = 1];
string ts = 4 [(validate.rules).string.min_len = 1]; // utc时间秒
string sign = 5 [(validate.rules).string.min_len = 1];
string account = 6 [(validate.rules).string.min_len = 1]; // PIX: Beneficiary's PIX account paypal账号
uint32 item_id = 7 [(validate.rules).uint32 = { lte: 3, gte: 1 }]; // 10.1213绿14
double amount = 8 [(validate.rules).double = { lte: 50, gte: 0.1 }];
string additional_remark = 9 [(validate.rules).string.min_len = 1];
string uuid = 10 [(validate.rules).string.min_len = 1];
string ip = 11;
string account_type = 12 [(validate.rules).string = { min_len: 0, max_len: 5 }]; // 西PIX支付不填PIX: Beneficiary's PIX account type- One of: CPF, CNPJ, EVP, PHONE, EMAIL
string document_type = 13 [(validate.rules).string = { min_len: 0, max_len: 4 }]; // 西PIX支付不填PIX: Beneficiary's personal identification type - One of: CPF, CNPJ
string document_id = 14 [(validate.rules).string = { min_len: 0, max_len: 100 }]; // 西PIX支付不填PIX: Beneficiary's personal identification number
string name = 15 [(validate.rules).string = { min_len: 0, max_len: 100 }]; // 西PIX支付不填PIX: Beneficiary's name- Length between 5 and 100
PbReportDataAdjust dataAdjust = 16; // adjust
PbReportDataShuShu dataShuShu = 17; //
string clientData = 18; //
string clientName = 19; //
string email = 20 [(validate.rules).string.min_len = 1]; //
}
// PayoutReply
message PayoutReply {
string id = 1;
string record_no = 2;
int32 error = 3; // 01234uuid错误56id7id不对8910111213西 document_type
// 14西 document_id 15 西 AccountType 16 西 Name 17西 Account DocumentId 18西account_type为CPF时 account 19西account_type为CNPJ时 account 20西 account_type
// 21西 document_type 22西account_type为CPF时 document_id 23西account_type为CNPJ时 document_id 24 ts长度错误25 0.1 26 27
}
// PayoutCallbackReq
message PayoutCallbackReq {
string payout_id = 1;
string custom_code = 2;
string status = 3;
string msg = 4;
int64 timestamp = 5;
}
// PayoutCallbackReply
message PayoutCallbackReply {
string message = 1;
}
// PayoutCheckReq
message PayoutCheckReq {
string platform = 1 [(validate.rules).string.min_len = 1];
string deviceid = 2 [(validate.rules).string.min_len = 1];
string version = 3 [(validate.rules).string.min_len = 1];
string ts = 4 [(validate.rules).string.min_len = 1]; // utc时间秒
string sign = 5 [(validate.rules).string.min_len = 1];
string ip = 6;
string record_no = 7 [(validate.rules).string.min_len = 1];
}
// PayoutCheckReply
message PayoutCheckReply {
uint32 status = 1; // 1:,2:,3:
int32 error = 2; // 01234 ts长度错误
}
// GetPayoutUserLst
message PayoutUserLstReq {
string platform = 1 [(validate.rules).string.min_len = 1];
string deviceid = 2 [(validate.rules).string.min_len = 1];
string version = 3 [(validate.rules).string.min_len = 1];
string ts = 4 [(validate.rules).string.min_len = 1]; // utc时间秒
string sign = 5 [(validate.rules).string.min_len = 1]; //
uint32 status = 6 [(validate.rules).uint32 = { lte: 3, gte: 1 }]; // 1:,2:,3:
uint32 pageIndex = 7; // 1
uint32 pageSize = 8; //
}
// GetPayoutUserLst
message PayoutUserLstReply {
repeated PayoutUserOne lst = 1; //
int32 error = 2; // 0123访4 ts长度错误
}
message PayoutUserOne {
string email = 1; //
string recordNo = 2; //
string account = 3; // paypal账号
uint32 status = 4; // 1:,2:,3:
}
// SetPayoutStatus
message PayoutStatusReq {
string platform = 1 [(validate.rules).string.min_len = 1];
string deviceid = 2 [(validate.rules).string.min_len = 1];
string version = 3 [(validate.rules).string.min_len = 1];
string ts = 4 [(validate.rules).string.min_len = 1]; // utc时间秒
string sign = 5 [(validate.rules).string.min_len = 1]; //
string recordNo = 6 [(validate.rules).string.min_len = 1]; // PayoutUserOne recordNo
string fail = 7; //
uint32 status = 8 [(validate.rules).uint32 = { lte: 3, gte: 2 }]; // 2:,3:
}
message PayoutStatusReply {
string recordNo = 1; // PayoutUserOne recordNo
uint32 status = 2;
uint32 error = 3; // 0123访4 ts长度错误5 status值错误
}
//
message SubmitCheckReq {
string account = 1 [(validate.rules).string.min_len = 1]; // paypal账号
string uuid = 2 [(validate.rules).string.min_len = 1];
}
message SubmitCheckReply {
int32 result = 1; // 0123
int32 error = 2; // 01
}
//
message CheckInfoReq {
string platform = 1 [(validate.rules).string.min_len = 1];
string deviceid = 2 [(validate.rules).string.min_len = 1];
string version = 3 [(validate.rules).string.min_len = 1];
string ip = 4;
string ts = 5 [(validate.rules).string.min_len = 1]; // utc时间秒
string sign = 6 [(validate.rules).string.min_len = 1];
string uuid = 7; //
int32 isVerificationShow = 8; // 10
}
message CheckInfoReply {
int32 CanCheckSubmit = 1; // 01
int32 CheckSubmit = 2; // 01
int32 CheckResult = 3; // 012
int32 CheckPayout = 4; // 50123
int32 CheckCoin = 5; //
int32 CanCheckPayOut = 6; // 5 012
string CheckResultFailedDesc = 7; // CheckResult==1
int32 error = 8; // 012 ts长度错误
}
message PbMsgOne {
int64 timeStamp = 1; // utc纳秒
string uuid = 2; //
string name = 3; //
string msg = 4; //
}
//
message AddChatReq {
int64 timeStamp = 1; // PbMsgOne的timeStamp0
string platform = 2 [(validate.rules).string.min_len = 1];
string deviceid = 3 [(validate.rules).string.min_len = 1];
string version = 4 [(validate.rules).string.min_len = 1];
string ip = 5;
string ts = 6 [(validate.rules).string.min_len = 1]; // utc时间秒
string sign = 7 [(validate.rules).string.min_len = 1];
string uuid = 8; //
string msg = 9; //
}
message AddChatReply {
uint32 result = 1; // 012 ts长度错误
string uuid = 2; //
repeated PbMsgOne lst = 3; //
int32 error = 4; // 01
}
//
message GetChatReq {
int64 timeStamp = 1; // PbMsgOne的timeStamp0
string platform = 2 [(validate.rules).string.min_len = 1];
string deviceid = 3 [(validate.rules).string.min_len = 1];
string version = 4 [(validate.rules).string.min_len = 1];
string ip = 5;
string ts = 6 [(validate.rules).string.min_len = 1];
string sign = 7 [(validate.rules).string.min_len = 1];
string uuid = 8; //
}
message GetChatReply {
string uuid = 1; //
repeated PbMsgOne lst = 2; //
int32 error = 3; // 01
}
////////////////////////////////////////////////////////////////
// 使
message PbSvrData {
repeated PbMsgOne lstChat = 1; //
// map<string, PbReportData> mapReportData = 2; // map<TS开头的订单号>
// uint32 rfClearReportData = 3; // utc秒
}
message PbUserData {
}
message PbReportData {
PbAdjustData adjust = 1;
PbShuShuData shuShu = 2;
uint32 rf = 3;
}
message PbAdjustData {
string GpsAdid = 1;
string Adid = 2;
string AndroidId = 3;
string IpAddress = 4;
string CreatedAtUnix = 5;
string Currency = 6;
string Environment = 7;
string UserAgent = 8;
string Price = 9;
string FailReason = 10;
string AppToken = 11;
string EventToken = 12;
string S2s = 13;
string clientName = 14;
}
message PbShuShuData {
string GpsAdid = 1;
string AppToken = 2;
string EventToken = 3;
string S2s = 4;
string AndroidId = 5;
string Adid = 6;
string IpAddress = 7;
string CreatedAtUnix = 8;
string UserAgent = 9;
string Price = 10;
string Currency = 11;
string FailReason = 12;
string PayoutId = 13;
string MerchantReference = 14;
string PaymentMethod = 15;
string PaymentType = 16;
string PaymentNumber = 17;
string IapName = 18;
string GamecoinNumber = 19;
string GamecoinType = 20;
string SsAccountId = 21;
string SsDistinctId = 22;
string SsSuperProperties = 23;
string clientName = 24;
}

1
app/eonline/Makefile Normal file
View File

@ -0,0 +1 @@
include ../../app_makefile

View File

@ -0,0 +1,122 @@
package main
import (
"flag"
"os"
"sandc/app/eonline/internal/conf"
config2 "sandc/app/eonline/internal/config"
"sandc/app/eonline/internal/service"
"sandc/pkg/log/zaplog"
zaplogger "github.com/go-kratos/kratos/contrib/log/zap/v2"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/config"
"github.com/go-kratos/kratos/v2/config/file"
"github.com/go-kratos/kratos/v2/encoding/json"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/middleware/tracing"
"github.com/go-kratos/kratos/v2/transport/http"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/sdk/resource"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
"google.golang.org/protobuf/encoding/protojson"
)
// go build -ldflags "-X main.Version=x.y.z"
var (
// Name is the name of the compiled software.
Name = "eonline.rpc"
// Version is the version of the compiled software.
Version = "0.1.0"
// flagconf is the config flag.
flagconf string
id, _ = os.Hostname()
)
func init() {
flag.StringVar(&flagconf, "conf", "configs/config.yaml", "config path, eg: -conf config.yaml")
json.MarshalOptions = protojson.MarshalOptions{
EmitUnpopulated: true,
UseProtoNames: true,
}
}
// func newApp(logger log.Logger, conf *conf.Server, hs *http.Server, gs *grpc.Server, rr registry.Registrar) *kratos.App {
func newApp(logger log.Logger, conf *conf.Server, hs *http.Server) *kratos.App {
return kratos.New(
kratos.ID(id),
kratos.Name(Name),
kratos.Version(Version),
kratos.Metadata(map[string]string{}),
kratos.Logger(logger),
kratos.Server(
hs,
// gs,
),
// kratos.Registrar(rr),
)
}
func main() {
flag.Parse()
c := config.New(
config.WithSource(
file.NewSource(flagconf),
),
)
if err := c.Load(); err != nil {
panic(err)
}
var bc conf.Bootstrap
if err := c.Scan(&bc); err != nil {
panic(err)
}
zc := zaplog.NewConfig(zaplog.SetLogPrintTag(false))
if err := zaplog.Init(zc); err != nil {
panic(err)
}
logger := log.With(zaplogger.NewLogger(zaplog.Logger),
"ts", log.DefaultTimestamp,
"caller", log.DefaultCaller,
"service.id", id,
"service.name", Name,
"service.version", Version,
"trace_id", tracing.TraceID(),
"span_id", tracing.SpanID(),
)
// exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(bc.Server.TraceEndpoint)))
// if err != nil {
// panic(err)
// }
tp := tracesdk.NewTracerProvider(
// tracesdk.WithBatcher(exp),
tracesdk.WithResource(resource.NewSchemaless(
semconv.ServiceNameKey.String(Name),
)),
)
otel.SetTracerProvider(tp)
config2.ConfigInit(&bc.ConfigFiles.Path, &bc.Server.Env, &bc.Server.VerCheck)
service.InitTimer()
defer func() {
service.OnDestroyTimer()
}()
app, cleanup, err := initApp(bc.Server, &bc, bc.Data, bc.Queue, logger)
if err != nil {
panic(err)
}
defer cleanup()
// start and wait for stop signal
if err := app.Run(); err != nil {
panic(err)
}
}

View File

@ -0,0 +1,22 @@
//go:build wireinject
// +build wireinject
// The build tag makes sure the stub is not built in the final build.
package main
import (
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/log"
"github.com/google/wire"
"sandc/app/eonline/internal/biz"
"sandc/app/eonline/internal/conf"
"sandc/app/eonline/internal/data"
"sandc/app/eonline/internal/server"
"sandc/app/eonline/internal/service"
)
// initApp init kratos application.
func initApp(*conf.Server, *conf.Bootstrap, *conf.Data, *conf.Queue, log.Logger) (*kratos.App, func(), error) {
panic(wire.Build(server.ProviderSet, data.ProviderSet, biz.ProviderSet, service.ProviderSet, newApp))
}

View File

@ -0,0 +1,40 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
import (
"sandc/app/eonline/internal/biz"
"sandc/app/eonline/internal/conf"
"sandc/app/eonline/internal/data"
"sandc/app/eonline/internal/server"
"sandc/app/eonline/internal/service"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/log"
)
// Injectors from wire.go:
// initApp init kratos application.
func initApp(confServer *conf.Server, bootstrap *conf.Bootstrap, confData *conf.Data, queue *conf.Queue, logger log.Logger) (*kratos.App, func(), error) {
client := data.NewAsynqClient(queue)
dataData, cleanup, err := data.NewData(confData, bootstrap, client, logger)
if err != nil {
return nil, nil, err
}
eonlineRepo := data.NewEonlineRepo(dataData, logger)
transaction := data.NewTransaction(dataData)
cache := data.NewCache(dataData)
eonlineUsecase := biz.NewEonlineUsecase(eonlineRepo, bootstrap, transaction, logger, cache)
eonlineService := service.NewEonlineService(eonlineUsecase, logger, bootstrap)
httpServer := server.NewHTTPServer(confServer, eonlineService, logger)
app := newApp(logger, confServer, httpServer)
data.InitData(bootstrap)
return app, func() {
cleanup()
}, nil
}

View File

@ -0,0 +1,87 @@
package main
import (
"flag"
"os"
"sandc/app/eonline/internal/conf"
zaplogger "github.com/go-kratos/kratos/contrib/log/zap/v2"
"github.com/go-kratos/kratos/v2/config"
"github.com/go-kratos/kratos/v2/config/file"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/middleware/tracing"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/jaeger"
"go.opentelemetry.io/otel/sdk/resource"
tracesdk "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
// go build -ldflags "-X main.Version=x.y.z"
var (
// Name is the name of the compiled software.
Name = "eonline.async"
// Version is the version of the compiled software.
Version = "0.1.0"
// flagconf is the config flag.
flagconf string
id, _ = os.Hostname()
)
func init() {
flag.StringVar(&flagconf, "conf", "configs/config.yaml", "config path, eg: -conf config.yaml")
}
func main() {
flag.Parse()
encoderCfg := zapcore.EncoderConfig{
LevelKey: "level",
EncodeLevel: zapcore.LowercaseLevelEncoder,
}
out := zapcore.AddSync(os.Stdout) // replace real writer
core := zapcore.NewCore(zapcore.NewJSONEncoder(encoderCfg), out, zap.DebugLevel)
zlogger := zap.New(core).WithOptions()
logger := log.With(zaplogger.NewLogger(zlogger),
"ts", log.DefaultTimestamp,
"caller", log.DefaultCaller,
"service.id", id,
"service.name", Name,
"service.version", Version,
"trace_id", tracing.TraceID(),
"span_id", tracing.SpanID(),
)
c := config.New(
config.WithSource(
file.NewSource(flagconf),
),
)
if err := c.Load(); err != nil {
panic(err)
}
var bc conf.Bootstrap
if err := c.Scan(&bc); err != nil {
panic(err)
}
exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(bc.Server.TraceEndpoint)))
if err != nil {
panic(err)
}
tp := tracesdk.NewTracerProvider(
tracesdk.WithBatcher(exp),
tracesdk.WithResource(resource.NewSchemaless(
semconv.ServiceNameKey.String(Name),
)),
)
otel.SetTracerProvider(tp)
job, cleanup, err := initApp(bc.Data, &bc, bc.Server, bc.Queue, logger)
if err != nil {
panic(err)
}
defer cleanup()
if err := job.Run(); err != nil {
panic(err)
}
}

View File

@ -0,0 +1,20 @@
//go:build wireinject
// +build wireinject
// The build tag makes sure the stub is not built in the final build.
package main
import (
"github.com/go-kratos/kratos/v2/log"
"github.com/google/wire"
"sandc/app/eonline/internal/biz"
"sandc/app/eonline/internal/conf"
"sandc/app/eonline/internal/data"
"sandc/app/eonline/internal/server"
)
// initApp init application.
func initApp(*conf.Data, *conf.Bootstrap, *conf.Server, *conf.Queue, log.Logger) (*server.AsynqServer, func(), error) {
panic(wire.Build(data.ProviderSet, server.ProviderSet, biz.ProviderSet))
}

View File

@ -0,0 +1,35 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
import (
"sandc/app/eonline/internal/biz"
"sandc/app/eonline/internal/conf"
"sandc/app/eonline/internal/data"
"sandc/app/eonline/internal/server"
"github.com/go-kratos/kratos/v2/log"
)
// Injectors from wire.go:
// initApp init application.
func initApp(confData *conf.Data, bootstrap *conf.Bootstrap, confServer *conf.Server, queue *conf.Queue, logger log.Logger) (*server.AsynqServer, func(), error) {
client := data.NewAsynqClient(queue)
dataData, cleanup, err := data.NewData(confData, bootstrap, client, logger)
if err != nil {
return nil, nil, err
}
eonlineRepo := data.NewEonlineRepo(dataData, logger)
transaction := data.NewTransaction(dataData)
cache := data.NewCache(dataData)
eonlineUsecase := biz.NewEonlineUsecase(eonlineRepo, bootstrap, transaction, logger, cache)
asynqServer := server.NewAsynqServer(queue, eonlineUsecase)
return asynqServer, func() {
cleanup()
}, nil
}

View File

@ -0,0 +1,51 @@
server:
http:
addr: 0.0.0.0:8300
timeout: 60s
grpc:
addr: 0.0.0.0:0
timeout: 30s
etcd:
addr:
- 127.0.0.1:2379
trace_endpoint: http://127.0.0.1:14268/api/traces
env: "qa"
geo_file: "/Users/wangchuan/www/test/geo/GeoIP2-City_20210706/GeoIP2-City.mmdb"
svr_id: 1
first_day: 20230908
ver_check: 2.0.0
data:
database:
driver: mysql
# source: root:a123456@tcp(47.94.97.41:33306)/eonline2?charset=utf8mb4&parseTime=True&loc=UTC
source: root:root@tcp(127.0.0.1:3306)/eonline2?charset=utf8mb4&parseTime=True&loc=UTC
redis:
addr: 127.0.0.1:6379
read_timeout: 0.2s
write_timeout: 0.2s
db: 3
queue:
kafka:
addrs:
- 127.0.0.1:9092
topic: example
group: example
asynq:
addr: 127.0.0.1:6379
read_timeout: 0.2s
write_timeout: 0.2s
concurrency: 10
db: 13
pagsmile:
payout:
app_id: "9B6B388E81E6456B901B61AEFA1F58E4"
app_key: "BO9ImO6KHg"
api_url: "https://sandbox.transfersmile.com"
notify_url: "http://pagsmile.dgtverse.cn/eonline2/payout/callback"
configFiles:
path: "./configs/"

View File

@ -0,0 +1,64 @@
server:
http:
addr: 0.0.0.0:8600
timeout: 60s
grpc:
addr: 0.0.0.0:0
timeout: 30s
etcd:
addr:
- 127.0.0.1:2379
trace_endpoint: http://127.0.0.1:14268/api/traces
env: "qa"
env2: "prod"
geo_file: "D:/work/GeoIP2-City.mmdb"
svr_id: 1
first_day: 20230907
ver_check: 0.0.0
timeoutTimerPer10Second: 3500
data:
database:
driver: mysql
source: root:a123456@tcp(47.94.97.41:33306)/eonline3?charset=utf8mb4&parseTime=True&loc=UTC
# source: root:root@tcp(127.0.0.1:3306)/eonline2?charset=utf8mb4&parseTime=True&loc=UTC
redis:
addr: 47.94.97.41:6666
password: a123456
# addr: 127.0.0.1:6389
read_timeout: 0.2s
write_timeout: 0.2s
db: 2
queue:
kafka:
addrs:
- 127.0.0.1:9092
topic: example
group: example
asynq:
addr: 47.94.97.41:6666
password: a123456
# addr: 127.0.0.1:6389
read_timeout: 0.2s
write_timeout: 0.2s
concurrency: 10
db: 2
pagsmile:
payout:
app_id: "9B6B388E81E6456B901B61AEFA1F58E4"
app_key: "BO9ImO6KHg"
api_url: "https://sandbox.transfersmile.com"
notify_url: "http://pagsmile.dgtverse.cn/eonline3/payout/callback"
configFiles:
path: "./configs/"
appConfig:
adjustAppToken: "5l2aubga4by8"
adjustS2SToken: "7ea35d86e3e6688c2debcadc4efd7230"
adjustEventTokenSuccess: "xlwfxq"
adjustEventTokenFail: "t4c6tj"
ssAppId: "3774fd57014846d99ccd145a76780866"

View File

@ -0,0 +1,64 @@
server:
http:
addr: 0.0.0.0:8600
timeout: 60s
grpc:
addr: 0.0.0.0:0
timeout: 30s
etcd:
addr:
- 127.0.0.1:2379
trace_endpoint: http://127.0.0.1:14268/api/traces
env: "qa"
env2: "prod"
geo_file: "D:/work/GeoIP2-City.mmdb"
svr_id: 1
first_day: 20230907
ver_check: 0.0.0
timeoutTimerPer10Second: 3500
data:
database:
driver: mysql
source: root:a123456@tcp(47.94.97.41:33306)/eonline3?charset=utf8mb4&parseTime=True&loc=UTC
# source: root:root@tcp(127.0.0.1:3306)/eonline2?charset=utf8mb4&parseTime=True&loc=UTC
redis:
addr: 47.94.97.41:6666
password: a123456
# addr: 127.0.0.1:6389
read_timeout: 0.2s
write_timeout: 0.2s
db: 2
queue:
kafka:
addrs:
- 127.0.0.1:9092
topic: example
group: example
asynq:
addr: 47.94.97.41:6666
password: a123456
# addr: 127.0.0.1:6389
read_timeout: 0.2s
write_timeout: 0.2s
concurrency: 10
db: 2
pagsmile:
payout:
app_id: "9B6B388E81E6456B901B61AEFA1F58E4"
app_key: "BO9ImO6KHg"
api_url: "https://sandbox.transfersmile.com"
notify_url: "http://pagsmile.dgtverse.cn/eonline3/payout/callback"
configFiles:
path: "./configs/"
appConfig:
adjustAppToken: "cha3p92jj30g"
adjustS2SToken: "d39f286413fba8bd9b1647b54431fdc6"
adjustEventTokenSuccess: "dmb6de"
adjustEventTokenFail: "cz94hi"
ssAppId: "be320c3e32ef4beb990270dcffde55af"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

3
app/eonline/generate.go Normal file
View File

@ -0,0 +1,3 @@
package eonline
//go:generate kratos proto client api

View File

@ -0,0 +1 @@
# Biz

View File

@ -0,0 +1,163 @@
package biz
import (
"errors"
v1 "sandc/api/eonline/v1"
go_redis_orm "github.com/fananchong/go-redis-orm.v2"
"github.com/gomodule/redigo/redis"
"google.golang.org/protobuf/proto"
)
type ReportData struct {
__key string
data v1.PbReportData
__dirtyData map[string]interface{}
__dirtyDataForStructFiled map[string]interface{}
__isLoad bool
__dbKey string
__dbName string
__expire uint
}
func NewReportData(dbName string, key string) *ReportData {
return &ReportData{
__key: key,
__dbName: dbName,
__dbKey: "ReportData:" + key,
__dirtyData: make(map[string]interface{}),
__dirtyDataForStructFiled: make(map[string]interface{}),
}
}
// 若访问数据库失败返回-1若 key 存在返回 1 ,否则返回 0 。
func (this *ReportData) HasKey() (int, error) {
db := go_redis_orm.GetDB(this.__dbName)
val, err := redis.Int(db.Do("EXISTS", this.__dbKey))
if err != nil {
return -1, err
}
return val, nil
}
func (this *ReportData) Load() error {
if this.__isLoad == true {
return errors.New("already load!")
}
db := go_redis_orm.GetDB(this.__dbName)
val, err := redis.Values(db.Do("HGETALL", this.__dbKey))
if err != nil {
return err
}
if len(val) == 0 {
return go_redis_orm.ERR_ISNOT_EXIST_KEY
}
var data struct {
Data []byte `redis:"data"`
}
if err := redis.ScanStruct(val, &data); err != nil {
return err
}
if err := proto.Unmarshal(data.Data, &this.data); err != nil {
return err
}
this.__isLoad = true
return nil
}
func (this *ReportData) Save() error {
if len(this.__dirtyData) == 0 && len(this.__dirtyDataForStructFiled) == 0 {
return nil
}
for k, _ := range this.__dirtyDataForStructFiled {
_ = k
if k == "data" {
data, err := proto.Marshal(&this.data)
if err != nil {
return err
}
this.__dirtyData["data"] = data
}
}
db := go_redis_orm.GetDB(this.__dbName)
if _, err := db.Do("HMSET", redis.Args{}.Add(this.__dbKey).AddFlat(this.__dirtyData)...); err != nil {
return err
}
if this.__expire != 0 {
if _, err := db.Do("EXPIRE", this.__dbKey, this.__expire); err != nil {
return err
}
}
this.__dirtyData = make(map[string]interface{})
this.__dirtyDataForStructFiled = make(map[string]interface{})
return nil
}
func (this *ReportData) Delete() error {
db := go_redis_orm.GetDB(this.__dbName)
_, err := db.Do("DEL", this.__dbKey)
if err == nil {
this.__isLoad = false
this.__dirtyData = make(map[string]interface{})
this.__dirtyDataForStructFiled = make(map[string]interface{})
}
return err
}
func (this *ReportData) IsLoad() bool {
return this.__isLoad
}
func (this *ReportData) Expire(v uint) {
this.__expire = v
}
func (this *ReportData) GetKey() string {
return this.__key
}
func (this *ReportData) DirtyData() (map[string]interface{}, error) {
for k, _ := range this.__dirtyDataForStructFiled {
_ = k
if k == "data" {
data, err := proto.Marshal(&this.data)
if err != nil {
return nil, err
}
this.__dirtyData["data"] = data
}
}
data := make(map[string]interface{})
for k, v := range this.__dirtyData {
data[k] = v
}
this.__dirtyData = make(map[string]interface{})
this.__dirtyDataForStructFiled = make(map[string]interface{})
return data, nil
}
func (this *ReportData) Save2(dirtyData map[string]interface{}) error {
if len(dirtyData) == 0 {
return nil
}
db := go_redis_orm.GetDB(this.__dbName)
if _, err := db.Do("HMSET", redis.Args{}.Add(this.__dbKey).AddFlat(dirtyData)...); err != nil {
return err
}
if this.__expire != 0 {
if _, err := db.Do("EXPIRE", this.__dbKey, this.__expire); err != nil {
return err
}
}
return nil
}
func (this *ReportData) GetData(mutable bool) *v1.PbReportData {
if mutable {
this.__dirtyDataForStructFiled["data"] = nil
}
return &this.data
}

View File

@ -0,0 +1,163 @@
package biz
import (
"errors"
v1 "sandc/api/eonline/v1"
go_redis_orm "github.com/fananchong/go-redis-orm.v2"
"github.com/gomodule/redigo/redis"
"google.golang.org/protobuf/proto"
)
type UserData struct {
__key string
data v1.PbUserData
__dirtyData map[string]interface{}
__dirtyDataForStructFiled map[string]interface{}
__isLoad bool
__dbKey string
__dbName string
__expire uint
}
func NewUserData(dbName string, key string) *UserData {
return &UserData{
__key: key,
__dbName: dbName,
__dbKey: "UserData:" + key,
__dirtyData: make(map[string]interface{}),
__dirtyDataForStructFiled: make(map[string]interface{}),
}
}
// 若访问数据库失败返回-1若 key 存在返回 1 ,否则返回 0 。
func (this *UserData) HasKey() (int, error) {
db := go_redis_orm.GetDB(this.__dbName)
val, err := redis.Int(db.Do("EXISTS", this.__dbKey))
if err != nil {
return -1, err
}
return val, nil
}
func (this *UserData) Load() error {
if this.__isLoad == true {
return errors.New("already load!")
}
db := go_redis_orm.GetDB(this.__dbName)
val, err := redis.Values(db.Do("HGETALL", this.__dbKey))
if err != nil {
return err
}
if len(val) == 0 {
return go_redis_orm.ERR_ISNOT_EXIST_KEY
}
var data struct {
Data []byte `redis:"data"`
}
if err := redis.ScanStruct(val, &data); err != nil {
return err
}
if err := proto.Unmarshal(data.Data, &this.data); err != nil {
return err
}
this.__isLoad = true
return nil
}
func (this *UserData) Save() error {
if len(this.__dirtyData) == 0 && len(this.__dirtyDataForStructFiled) == 0 {
return nil
}
for k, _ := range this.__dirtyDataForStructFiled {
_ = k
if k == "data" {
data, err := proto.Marshal(&this.data)
if err != nil {
return err
}
this.__dirtyData["data"] = data
}
}
db := go_redis_orm.GetDB(this.__dbName)
if _, err := db.Do("HMSET", redis.Args{}.Add(this.__dbKey).AddFlat(this.__dirtyData)...); err != nil {
return err
}
if this.__expire != 0 {
if _, err := db.Do("EXPIRE", this.__dbKey, this.__expire); err != nil {
return err
}
}
this.__dirtyData = make(map[string]interface{})
this.__dirtyDataForStructFiled = make(map[string]interface{})
return nil
}
func (this *UserData) Delete() error {
db := go_redis_orm.GetDB(this.__dbName)
_, err := db.Do("DEL", this.__dbKey)
if err == nil {
this.__isLoad = false
this.__dirtyData = make(map[string]interface{})
this.__dirtyDataForStructFiled = make(map[string]interface{})
}
return err
}
func (this *UserData) IsLoad() bool {
return this.__isLoad
}
func (this *UserData) Expire(v uint) {
this.__expire = v
}
func (this *UserData) GetKey() string {
return this.__key
}
func (this *UserData) DirtyData() (map[string]interface{}, error) {
for k, _ := range this.__dirtyDataForStructFiled {
_ = k
if k == "data" {
data, err := proto.Marshal(&this.data)
if err != nil {
return nil, err
}
this.__dirtyData["data"] = data
}
}
data := make(map[string]interface{})
for k, v := range this.__dirtyData {
data[k] = v
}
this.__dirtyData = make(map[string]interface{})
this.__dirtyDataForStructFiled = make(map[string]interface{})
return data, nil
}
func (this *UserData) Save2(dirtyData map[string]interface{}) error {
if len(dirtyData) == 0 {
return nil
}
db := go_redis_orm.GetDB(this.__dbName)
if _, err := db.Do("HMSET", redis.Args{}.Add(this.__dbKey).AddFlat(dirtyData)...); err != nil {
return err
}
if this.__expire != 0 {
if _, err := db.Do("EXPIRE", this.__dbKey, this.__expire); err != nil {
return err
}
}
return nil
}
func (this *UserData) GetData(mutable bool) *v1.PbUserData {
if mutable {
this.__dirtyDataForStructFiled["data"] = nil
}
return &this.data
}

View File

@ -0,0 +1,196 @@
package adjust
import (
"context"
"encoding/json"
"fmt"
"strings"
"sandc/pkg/bhttp"
"github.com/go-kratos/kratos/v2/log"
)
// AdjustEventParams 上报事件参数
type AdjustEventParams struct {
GpsAdid string `json:"gps_adid"`
Adid string `json:"adid"`
AndroidId string `json:"android_id"`
IpAddress string `json:"ip_address"`
CreatedAtUnix string `json:"created_at_unix"`
Currency string `json:"currency"`
Environment string `json:"environment"`
UserAgent string `json:"user_agent"`
Price string `json:"price"`
FailReason string `json:"fail_reason"`
AppToken string `json:"app_token"`
EventToken string `json:"event_token"`
S2S string `json:"s2s"`
ClientName string `json:"client_name"` // 客户端包名
// Idfa string `json:"idfa"`
// FireAdid string `json:"fire_adid"`
// Oaid string `json:"oaid"`
// Idfv string `json:"idfv"`
// Revenue string `json:"revenue"`
}
// AdjustClient adjust客户端接口
type AdjustClient interface {
// ReportEvent 上报事件
ReportEvent(ctx context.Context, opts *AdjustEventParams) error
}
// adjustClient adjust客户端
type adjustClient struct {
appToken string
s2sToken string
env string
service *bhttp.BhttpService
}
// NewAdjustClient 创建adjust客户端
func NewAdjustClient(appToken, s2sToken, env string) (AdjustClient, error) {
service, err := bhttp.NewBhttpService(bhttp.WithTimeout(30))
if err != nil {
return nil, err
}
service.Client.SetHeader("Content-Type", "application/x-www-form-urlencoded")
service.Client.SetParam("app_token", appToken)
if s2sToken != "" {
service.Client.SetHeader("Authorization", "Bearer "+s2sToken)
service.Client.SetParam("s2s", "1")
}
return &adjustClient{
appToken: appToken,
s2sToken: s2sToken,
env: env,
service: service,
}, nil
}
type ReportEventRes struct {
Error string `json:"error,omitempty"`
Status string `json:"status,omitempty"`
}
// ReportEvent 上报事件
func (ac *adjustClient) ReportEvent(ctx context.Context, opts *AdjustEventParams) error {
// if opts.Idfa != "" && validateUUID(opts.Idfa) {
// ac.service.Client.SetParam("idfa", opts.Idfa)
// }
if opts.GpsAdid != "" {
// 判断兼容客户端问题
if !validateUUID(opts.GpsAdid) {
// if opts.GpsAdid == opts.Oaid {
// opts.Oaid = ""
// }
opts.GpsAdid = ""
} else {
ac.service.Client.SetParam("gps_adid", opts.GpsAdid)
}
}
// if opts.FireAdid != "" {
// ac.service.Client.SetParam("fire_adid", opts.FireAdid)
// }
// if opts.Oaid != "" {
// ac.service.Client.SetParam("oaid", opts.Oaid)
// }
if opts.Adid != "" {
ac.service.Client.SetParam("adid", opts.Adid)
if opts.GpsAdid == "" {
ac.service.Client.SetParam("gps_adid", opts.Adid)
}
}
// if opts.Idfv != "" {
// ac.service.Client.SetParam("idfv", opts.Idfv)
// } else {
// if opts.Idfa != "" {
// ac.service.Client.SetParam("idfv", opts.Idfa)
// }
// }
if opts.AndroidId != "" {
ac.service.Client.SetParam("android_id", opts.AndroidId)
}
ac.service.Client.SetParam("event_token", opts.EventToken)
ac.service.Client.SetParam("ip_address", opts.IpAddress)
ac.service.Client.SetParam("created_at_unix", opts.CreatedAtUnix)
ac.service.Client.SetParam("user_agent", opts.UserAgent)
ac.service.Client.SetParam("price", opts.Price)
ac.service.Client.SetParam("fail_reason", opts.FailReason)
ac.service.Client.SetParam("client_name", opts.ClientName)
// ac.service.Client.SetParam("revenue", opts.Revenue)
// 兼容之前的数据错误
if strings.Contains(opts.Currency, "CNY") {
opts.Currency = "CNY"
} else if strings.Contains(opts.Currency, "USD") {
opts.Currency = "USD"
}
ac.service.Client.SetParam("currency", opts.Currency)
if opts.Environment == "prod" {
ac.service.Client.SetParam("environment", "production")
} else {
ac.service.Client.SetParam("environment", "sandbox")
}
numMax := 1
for i := 0; i < numMax; i++ {
body, err := ac.service.Client.DoPost("https://s2s.adjust.com/event")
sendData := ac.service.Client.GetReader()
if err != nil {
return fmt.Errorf("adjust server err: %s, reader: %s", err, sendData)
}
// 临时记录请求参数
// utils.PrintLog("adjust-request-params: %s \n", ac.service.Client.GetReader())
// utils.PrintLog("adjust-response-body: %s \n", string(body))
log.Infof("adjust-request-params: i[%d] %s \n", i, sendData)
log.Infof("adjust-response-body: i[%d] %s \n", i, string(body))
var res ReportEventRes
err = json.Unmarshal(body, &res)
if err != nil {
return fmt.Errorf("adjust Unmarshal err: %s, reader: %s", res.Error, sendData)
}
if res.Error != "" {
return fmt.Errorf("adjust res err: %s, reader: %s", res.Error, sendData)
}
if res.Status == "OK" {
log.Infof("adjust send successed: i[%d] reader: %s", i, sendData)
break
} else {
log.Infof("adjust res status error: %s, i[%d] reader: %s", res.Status, i, sendData)
if i+1 >= numMax {
return fmt.Errorf("adjust res status err: %s, reader: %s", res.Status, sendData)
}
}
}
return nil
}
// validateUUID 验证uuid的有效性
func validateUUID(uuid string) bool {
if len(uuid) != 36 {
return false
}
if strings.ToLower(uuid) == "00000000-0000-0000-0000-000000000000" {
return false
}
return true
}

View File

@ -0,0 +1,401 @@
package adjust
import (
"fmt"
"sandc/pkg/utils"
"strings"
"time"
)
type CallbackInfo struct {
ActivityKind string `json:"activity_kind"`
AdgroupName string `json:"adgroup_name"`
Adid string `json:"adid"`
AndroidId string `json:"android_id"`
AndroidIdMd5 string `json:"android_id_md5"`
AppId string `json:"app_id"`
AppName string `json:"app_name"`
AppNameDashboard string `json:"app_name_dashboard"`
AppToken string `json:"app_token"`
AppVersion string `json:"app_version"`
AppVersionRaw string `json:"app_version_raw"`
AppVersionShort string `json:"app_version_short"`
AttStatus string `json:"att_status"`
AttributionExpiresAt int64 `json:"attribution_expires_at"`
CallbackTtl string `json:"callback_ttl"`
CampaignName string `json:"campaign_name"`
City string `json:"city"`
ClickTime string `json:"click_time"`
ClickTimeHour string `json:"click_time_hour"`
ConnectionType string `json:"connection_type"`
ConversionDuration string `json:"conversion_duration"`
Country string `json:"country"`
CountrySubdivision string `json:"country_subdivision"`
CpuType string `json:"cpu_type"`
CreatedAt int64 `json:"created_at"`
CreatedAtHour int64 `json:"created_at_hour"`
CreatedAtMilli int64 `json:"created_at_milli"`
CreativeName string `json:"creative_name"`
Currency string `json:"currency"`
DbmCampaignType string `json:"dbm_campaign_type"`
DbmCreativeId string `json:"dbm_creative_id"`
DbmExchangeId string `json:"dbm_exchange_id"`
DbmExternalCustomerId string `json:"dbm_external_customer_id"`
DbmInsertionOrderId string `json:"dbm_insertion_order_id"`
DbmLineItemId string `json:"dbm_line_item_id"`
DbmLineItemName string `json:"dbm_line_item_name"`
DcmCampaignType string `json:"dcm_campaign_type"`
DcmCreativeId string `json:"dcm_creative_id"`
DcmExternalCustomerId string `json:"dcm_external_customer_id"`
DcmPlacementId string `json:"dcm_placement_id"`
DcmPlacementName string `json:"dcm_placement_name"`
DcmSiteId string `json:"dcm_site_id"`
Deeplink string `json:"deeplink"`
DeviceAtlasId string `json:"device_atlas_id"`
DeviceManufacturer string `json:"device_manufacturer"`
DeviceModel string `json:"device_model"`
DeviceName string `json:"device_name"`
DeviceType string `json:"device_type"`
EngagementTime string `json:"engagement_time"`
EngagementTimeHour string `json:"engagement_time_hour"`
Environment string `json:"environment"`
Event string `json:"event"`
EventCostId string `json:"event_cost_id"`
EventName string `json:"event_name"`
ExternalDeviceIdMd5 string `json:"external_device_id_md5"`
FbDeeplinkAccountId string `json:"fb_deeplink_account_id"`
FbDeeplinkAdId string `json:"fb_deeplink_ad_id"`
FbDeeplinkAdgroupId string `json:"fb_deeplink_adgroup_id"`
FbDeeplinkCampaignGroupId string `json:"fb_deeplink_campaign_group_id"`
FbDeeplinkCampaignId string `json:"fb_deeplink_campaign_id"`
FbInstallReferrer string `json:"fb_install_referrer"`
FbInstallReferrerAccountId string `json:"fb_install_referrer_account_id"`
FbInstallReferrerAdId string `json:"fb_install_referrer_ad_id"`
FbInstallReferrerAdObjectiveName string `json:"fb_install_referrer_ad_objective_name"`
FbInstallReferrerAdgroupId string `json:"fb_install_referrer_adgroup_id"`
FbInstallReferrerAdgroupName string `json:"fb_install_referrer_adgroup_name"`
FbInstallReferrerCampaignGroupId string `json:"fb_install_referrer_campaign_group_id"`
FbInstallReferrerCampaignGroupName string `json:"fb_install_referrer_campaign_group_name"`
FbInstallReferrerCampaignId string `json:"fb_install_referrer_campaign_id"`
FbInstallReferrerCampaignName string `json:"fb_install_referrer_campaign_name"`
FbInstallReferrerPublisherPlatform string `json:"fb_install_referrer_publisher_platform"`
FireAdid string `json:"fire_adid"`
FirstTracker string `json:"first_tracker"`
FirstTrackerName string `json:"first_tracker_name"`
Gbraid string `json:"gbraid"`
Gclid string `json:"gclid"`
GmpProductType string `json:"gmp_product_type"`
GoogleAdsAdType string `json:"google_ads_ad_type"`
GoogleAdsAdgroupId string `json:"google_ads_adgroup_id"`
GoogleAdsAdgroupName string `json:"google_ads_adgroup_name"`
GoogleAdsCampaignId string `json:"google_ads_campaign_id"`
GoogleAdsCampaignName string `json:"google_ads_campaign_name"`
GoogleAdsCampaignType string `json:"google_ads_campaign_type"`
GoogleAdsCreativeId string `json:"google_ads_creative_id"`
GoogleAdsEngagementType string `json:"google_ads_engagement_type"`
GoogleAdsExternalCustomerId string `json:"google_ads_external_customer_id"`
GoogleAdsKeyword string `json:"google_ads_keyword"`
GoogleAdsMatchtype string `json:"google_ads_matchtype"`
GoogleAdsNetworkSubtype string `json:"google_ads_network_subtype"`
GoogleAdsNetworkType string `json:"google_ads_network_type"`
GoogleAdsPlacement string `json:"google_ads_placement"`
GoogleAdsVideoId string `json:"google_ads_video_id"`
GoogleAppSetId string `json:"google_app_set_id"`
GpsAdid string `json:"gps_adid"`
GpsAdidMd5 string `json:"gps_adid_md5"`
HardwareName string `json:"hardware_name"`
IadAdId string `json:"iad_ad_id"`
IadConversionType string `json:"iad_conversion_type"`
IadCountryOrRegion string `json:"iad_country_or_region"`
IadKeyword string `json:"iad_keyword"`
IadKeywordId string `json:"iad_keyword_id"`
IadOrgId string `json:"iad_org_id"`
Idfa string `json:"idfa"`
IdfaAndroidId string `json:"idfa_android_id"`
IdfaGpsAdid string `json:"idfa_gps_adid"`
IdfaGpsAdidFireAdid string `json:"idfa_gps_adid_fire_adid"`
IdfaMd5 string `json:"idfa_md5"`
IdfaMd5Hex string `json:"idfa_md5_hex"`
IdfaUpper string `json:"idfa_upper"`
Idfv string `json:"idfv"`
IdfvGoogleAppSetId string `json:"idfv_google_app_set_id"`
ImpressionBased string `json:"impression_based"`
ImpressionTime string `json:"impression_time"`
ImpressionTimeHour string `json:"impression_time_hour"`
InstalledAt int64 `json:"installed_at"`
InstalledAtHour int64 `json:"installed_at_hour"`
IpAddress string `json:"ip_address"`
IsImported string `json:"is_imported"`
IsOrganic string `json:"is_organic"`
IsReattributed string `json:"is_reattributed"`
IsS2s string `json:"is_s2s"`
Isp string `json:"isp"`
Label string `json:"label"`
Language string `json:"language"`
LastFallbackTime string `json:"last_fallback_time"`
LastFallbackTimeHour string `json:"last_fallback_time_hour"`
LastSessionTime string `json:"last_session_time"`
LastTracker string `json:"last_tracker"`
LastTrackerName string `json:"last_tracker_name"`
LifetimeSessionCount string `json:"lifetime_session_count"`
MacMd5 string `json:"mac_md5"`
MacSha1 string `json:"mac_sha1"`
MatchType string `json:"match_type"`
Mcc string `json:"mcc"`
Mnc string `json:"mnc"`
NetworkName string `json:"network_name"`
NetworkType string `json:"network_type"`
Nonce string `json:"nonce"`
Oaid string `json:"oaid"`
OaidMd5 string `json:"oaid_md5"`
OsName string `json:"os_name"`
OsVersion string `json:"os_version"`
PartnerParameters string `json:"partner_parameters"`
Platform string `json:"platform"`
PostalCode string `json:"postal_code"`
PredictedValue string `json:"predicted_value"`
PredictionLabel string `json:"prediction_label"`
PredictionPeriodDays string `json:"prediction_period_days"`
ProxyIpAddress string `json:"proxy_ip_address"`
PublisherParameters string `json:"publisher_parameters"`
PushToken string `json:"push_token"`
Random string `json:"random"`
RandomUserId string `json:"random_user_id"`
ReattributedAt int64 `json:"reattributed_at"`
ReattributedAtHour int64 `json:"reattributed_at_hour"`
ReceivedAt int64 `json:"received_at"`
Referrer string `json:"referrer"`
Reftag string `json:"reftag"`
Region string `json:"region"`
ReinstalledAt int64 `json:"reinstalled_at"`
ReportingCurrency string `json:"reporting_currency"`
ReportingRevenue string `json:"reporting_revenue"`
Revenue string `json:"revenue"`
RevenueCny string `json:"revenue_cny"`
RevenueCnyCents string `json:"revenue_cny_cents"`
RevenueFloat string `json:"revenue_float"`
RevenueUsd string `json:"revenue_usd"`
RevenueUsdCents string `json:"revenue_usd_cents"`
Rida string `json:"rida"`
RokuContentId string `json:"roku_content_id"`
RokuPlacementType string `json:"roku_placement_type"`
SanEngagementTimes string `json:"san_engagement_times"`
SdkVersion string `json:"sdk_version"`
SessionCount string `json:"session_count"`
SimSlotIds string `json:"sim_slot_ids"`
SkCoarseConversionValue string `json:"sk_coarse_conversion_value"`
SkConversionValue string `json:"sk_conversion_value"`
SkConversionValueDevice string `json:"sk_conversion_value_device"`
SkConversionValueDeviceTime string `json:"sk_conversion_value_device_time"`
SkConversionValueStatus string `json:"sk_conversion_value_status"`
SkConversionValueTime string `json:"sk_conversion_value_time"`
SkCvWindowExpiration string `json:"sk_cv_window_expiration"`
SkRegisteredAt int64 `json:"sk_registered_at"`
SkTimerExpiration string `json:"sk_timer_expiration"`
SnapchatAdId string `json:"snapchat_ad_id"`
Store string `json:"store"`
ThirdPartySharingDisabled string `json:"third_party_sharing_disabled"`
Tifa string `json:"tifa"`
TimeSpent string `json:"time_spent"`
Timezone string `json:"timezone"`
Tracker string `json:"tracker"`
TrackerName string `json:"tracker_name"`
TrackingEnabled string `json:"tracking_enabled"`
TrackingLimited string `json:"tracking_limited"`
TweetId string `json:"tweet_id"`
TwitterLineItemId string `json:"twitter_line_item_id"`
UninstalledAt int64 `json:"uninstalled_at"`
UserAgent string `json:"user_agent"`
Vida string `json:"vida"`
VizioContentId string `json:"vizio_content_id"`
VizioPlacementType string `json:"vizio_placement_type"`
Wbraid string `json:"wbraid"`
WebUuid string `json:"web_uuid"`
WinAdid string `json:"win_adid"`
WinHwid string `json:"win_hwid"`
WinNaid string `json:"win_naid"`
WinUdid string `json:"win_udid"`
WithinCallbackTtl string `json:"within_callback_ttl"`
YahooCreativeId string `json:"yahoo_creative_id"`
YahooCreativeName string `json:"yahoo_creative_name"`
YahooSiteId string `json:"yahoo_site_id"`
AdImpressionsCount int64 `json:"ad_impressions_count,omitempty"` // 时间
AdMediationPlatform string `json:"ad_mediation_platform,omitempty"`
AdRevenueNetwork string `json:"ad_revenue_network,omitempty"`
AdRevenuePayload string `json:"ad_revenue_payload,omitempty"`
AdRevenuePlacement string `json:"ad_revenue_placement,omitempty"`
AdRevenueUnit string `json:"ad_revenue_unit,omitempty"`
}
type AdjustExportFilter struct {
Filename string
Tokens []string
Event string
Fields []string
CreatedAtFrom time.Time
CreatedAtTo time.Time
Location *time.Location //当前时期
Countries []string
Channels []string
InstallTimeFrom *time.Time
InstallTimeTo *time.Time
InstallHour *int
SumFields []string
Conditons map[string][]string
ConditionsNeq map[string][]string
CsvHeaders []string //csv头部
Offset int
}
type AdjustCondition struct {
Key int64 `json:"key"`
Value string `json:"value"`
}
type CallBackData struct {
Token string
Content []string
MapKeyData map[string]interface{}
}
type AdjustEventType string
const (
AdjustEventTypeInstall AdjustEventType = "install"
AdjustEventTypeGlobal AdjustEventType = "global"
AdjustEventTypeAdRevenue AdjustEventType = "ad_revenue"
)
func (d AdjustEventType) String() string {
return string(d)
}
func CheckAdjustQueueCondition(filter *AdjustExportFilter, info *CallbackInfo) (*CallBackData, bool) {
//判断token
if !InSlice(info.AppToken, filter.Tokens) {
return nil, false
}
//判断事件
if filter.Event == AdjustEventTypeGlobal.String() {
if info.ActivityKind == AdjustEventTypeAdRevenue.String() {
return nil, false
}
} else {
if info.ActivityKind != filter.Event {
return nil, false
}
}
//判断创建时间 @todo
fromTime, _ := time.ParseInLocation(time.DateTime, fmt.Sprintf("%s 00:00:00", filter.CreatedAtFrom.In(time.Local).Format(time.DateOnly)), filter.Location)
toTime, _ := time.ParseInLocation(time.DateTime, fmt.Sprintf("%s 23:59:59", filter.CreatedAtTo.In(time.Local).Format(time.DateOnly)), filter.Location)
if info.CreatedAt < fromTime.Unix() || info.CreatedAt > toTime.Unix() {
return nil, false
}
//判断国家
if len(filter.Countries) > 0 {
if !InSlice(info.Country, filter.Countries) {
return nil, false
}
}
//判断渠道
if len(filter.Channels) > 0 {
if !InSlice(info.NetworkName, filter.Channels) {
return nil, false
}
}
//判断安装时间
if filter.InstallTimeFrom != nil && filter.InstallTimeTo != nil {
installFormTime, _ := time.ParseInLocation(time.DateTime, fmt.Sprintf("%s 00:00:00", filter.InstallTimeFrom.In(time.Local).Format(time.DateOnly)), filter.Location)
installToTime, _ := time.ParseInLocation(time.DateTime, fmt.Sprintf("%s 23:59:59", filter.InstallTimeTo.In(time.Local).Format(time.DateOnly)), filter.Location)
if info.InstalledAt < installFormTime.Unix() || info.InstalledAt > installToTime.Unix() {
return nil, false
}
}
//判断小时
if filter.InstallHour != nil {
installHour := *filter.InstallHour
if info.CreatedAt-info.InstalledAt > 3600*int64(installHour) {
return nil, false
}
}
mapKeyData := utils.StructToMapJson(*info)
//判断自定义条件等于,仅支持string
if len(filter.Conditons) > 0 {
for k, filterValue := range filter.Conditons {
//如果自定义字段存在,判断值是否符合
if mapVal, ok := mapKeyData[k].(string); ok {
if !InSlice(mapVal, filterValue) {
return nil, false
}
} else {
return nil, false
}
}
}
//判断自定义条件不等于,仅支持string
if len(filter.ConditionsNeq) > 0 {
for k, filterValue := range filter.ConditionsNeq {
//如果自定义字段存在,判断值是否符合
if mapVal, ok := mapKeyData[k].(string); ok {
if utils.InSlice("NULL", filterValue) {
if mapVal == "" {
return nil, false
}
} else {
// 存在值则跳过数据
if InSlice(mapVal, filterValue) {
return nil, false
}
}
} else {
return nil, false
}
}
}
//获取筛选字段的值
content := make([]string, 0)
for _, field := range filter.Fields {
if mapVal, ok := mapKeyData[field]; ok {
content = append(content, fmt.Sprintf("%v", mapVal))
}
//单独处理date
if field == "date" {
rowDate := time.Unix(info.CreatedAt, 0)
rowDateString := rowDate.In(filter.Location).Format(time.DateOnly)
content = append(content, rowDateString)
}
}
//根据自定义字段返回数据
data := &CallBackData{
Token: info.AppToken,
Content: content,
MapKeyData: mapKeyData,
}
return data, true
}
func InSlice(str string, slice []string) bool {
for _, v := range slice {
if formatString(v) == formatString(str) {
return true
}
}
return false
}
func formatString(str string) string {
return strings.TrimSpace(strings.ToLower(str))
}

View File

@ -0,0 +1,221 @@
package biz
import (
"context"
"fmt"
"time"
"sandc/pkg/utils"
"github.com/google/wire"
"gorm.io/gorm"
)
// ProviderSet is biz providers.
var ProviderSet = wire.NewSet(NewEonlineUsecase)
type Cache interface {
GetValue(ctx context.Context, key string) (string, error)
DelValue(ctx context.Context, keys ...string) error
WriteValue(ctx context.Context, key string, value interface{}, timeout int32) error
Remember(ctx context.Context, key string, secone int32, fn func(ctx context.Context) (interface{}, error)) ([]byte, error)
RedisLock(ctx context.Context, key string, value interface{}, timeout int32) (bool, error)
RedisUnLock(ctx context.Context, key string) (bool, error)
IncrValue(ctx context.Context, key string) error
}
type Transaction interface {
InTx(context.Context, func(ctx context.Context) error) error
DB(ctx context.Context) *gorm.DB
}
var SignFixedParameters = []string{
"Platform",
"Deviceid",
"Version",
"Ip",
"Ts",
}
// PayoutItem 账号状态
type PayoutItemId int
const (
PayoutItemId1 PayoutItemId = iota + 1 // 提现0.1
PayoutItemId2 // 提现金币大额1
PayoutItemId3 // 提现绿钞大额1
PayoutItemId4 // 5.0美金,身份文件提交奖励
)
var PayoutItemIdAmountes = []float64{
PayoutItemId1: 5,
PayoutItemId2: 0.1,
PayoutItemId3: 0.1,
}
func (d PayoutItemId) Float64() float64 {
n := int(d)
if n < len(PayoutItemIdAmountes) && n > 0 {
return PayoutItemIdAmountes[n]
}
return 0
}
// PayoutItemStatus item状态类型
type PayoutItemStatus uint
const (
// 可提现
PayoutItemStatusAvailable PayoutItemStatus = iota + 1
// 条件未达成
PayoutItemStatusUnfinished
// 已提现
PayoutItemStatusPayouted
// 禁止提现
PayoutItemStatusForbidden
// 提现中
PayoutItemStatusPayouting
)
var PayoutItemStatusNames = []string{
PayoutItemStatusAvailable: "available",
PayoutItemStatusUnfinished: "unfinished",
PayoutItemStatusPayouted: "payouted",
PayoutItemStatusForbidden: "forbidden",
}
func (d PayoutItemStatus) String() string {
n := int(d)
if n < len(PayoutItemStatusNames) && n > 0 {
return PayoutItemStatusNames[n]
}
return ""
}
// PayoutStatus
type PayoutStatus uint
const (
// 提现中
PayoutStatusPayouting PayoutStatus = iota + 1
// 提现成功
PayoutStatusPayouted
// 提现失败
PayoutStatusPayoutFailed
)
var PayoutStatusNames = []string{
PayoutStatusPayouting: "payouting",
PayoutStatusPayouted: "payouted",
PayoutStatusPayoutFailed: "payout_failed",
}
func (d PayoutStatus) String() string {
n := int(d)
if n < len(PayoutStatusNames) && n > 0 {
return PayoutStatusNames[n]
}
return ""
}
// PayoutRecordLimit1 提现次数总限制
const PayoutRecordLimit1 = 1
const PayoutRecordLimit2 = 0
const PayoutRecordLimit3 = 0
const PayoutRecordLimit4 = 0
// PayoutAmountLimit 提现金额限制
const PayoutAmountLimit = 5
// GenPayoutUuid 生成payout_uuid
func GenPayoutUuid(deviceId string) string {
str := fmt.Sprintf("%s-tk0630", deviceId)
str = utils.MD5Any(str)
return str
}
// GetUuidPayoutRedisKey 获取uuid redis key当日提现记录
func GetUuidPayoutRedisKey(uuid string, date string, itemId uint32) string {
if date == "" {
date = time.Now().Format("20060102")
}
// uuidRedisKey := fmt.Sprintf("pt_%s_%s", uuid, date)
uuidRedisKey := fmt.Sprintf("pt:%s_%s_%d", uuid, date, itemId)
return uuidRedisKey
}
// GetUuidLockRedisKey 获取uuid redis lock key提现操作加锁防止并发
func GetUuidLockRedisKey(uuid string, date string) string {
if date == "" {
date = time.Now().Format("20060102")
}
uuidRedisKey := fmt.Sprintf("ptlock_%s_%s", uuid, date)
return uuidRedisKey
}
// GetPayoutNotifyRedisKey 获取提现通知redis key
func GetPayoutNotifyRedisKey(payoutId string, date string) string {
if date == "" {
date = time.Now().Format("20060102")
}
uuidRedisKey := fmt.Sprintf("pt_notify_%s_%s", payoutId, date)
return uuidRedisKey
}
// GetUserLoginRedisKey 获取用户登录redis key当日登录记录
func GetUserLoginRedisKey(userId string, date string) string {
if date == "" {
date = time.Now().Format("20060102")
}
uuidRedisKey := fmt.Sprintf("pt_login_%s_%s", userId, date)
return uuidRedisKey
}
// GetPayoutOrderIdRedisKey 获取提现订单对应的 提现reids记录 GetUuidPayoutRedisKey生成的 redis key
func GetPayoutOrderIdRedisKey(orderId string) string {
uuidRedisKey := fmt.Sprintf("ts:%s", orderId)
return uuidRedisKey
}
// 用户的paypal账号生成审核结果的 redis key
func GetCheckResultRedisKey(account string) string {
return fmt.Sprintf("pt_result:%s", account)
}
// 用户的paypal账号生成审核没通过的原因描述的 redis key
func GetCheckResultFailRedisKey(account string) string {
return fmt.Sprintf("pt_fail:%s", account)
}
// 用户的paypal账号生成提交审核的 redis key 存储的数据结构[paypal, uuid]
func GetCheckSubmitRedisKey(account string) string {
return fmt.Sprintf("pt_submit:%s", account)
}
// 用户的paypal账号生成提交审核的 redis key 存储的数据结构[uuid, paypal]
func GetUuid2PaypalRedisKey(uuid string) string {
return fmt.Sprintf("pt_uuid:%s", uuid)
}
// 提交审核计数的 redis key
func GetCheckSubmitNumRedisKey() string {
return fmt.Sprintf("svr_submitNum")
}
// 返回true表示t1,t2是同一天
func isSameDay(t1, t2 time.Time) bool {
y1 := t1.Year()
y2 := t2.Year()
if y1 != y2 {
return false
}
d1 := t1.YearDay()
d2 := t2.YearDay()
if d1 != d2 {
return false
}
return true
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
package biz
import (
"context"
"encoding/json"
"fmt"
"sandc/pkg/middleware/xhttp"
"sandc/pkg/utils"
"sandc/pkg/xcrypto/pscrypto"
"github.com/go-kratos/kratos/v2/log"
)
// PayoutReq 支付请求参数
type PayoutReq struct {
Name string `json:"name,omitempty"`
Phone string `json:"phone,omitempty"`
Email string `json:"email,omitempty"`
Account string `json:"account,omitempty"`
AccountType string `json:"account_type,omitempty"`
Method string `json:"method,omitempty"`
Channel string `json:"channel,omitempty"`
CustomCode string `json:"custom_code,omitempty"`
FeeBear string `json:"fee_bear,omitempty"`
Amount string `json:"amount,omitempty"`
SourceCurrency string `json:"source_currency,omitempty"`
ArrivalCurrency string `json:"arrival_currency,omitempty"`
NotifyUrl string `json:"notify_url,omitempty"`
AdditionalRemark string `json:"additional_remark,omitempty"`
Country string `json:"country,omitempty"`
Document_id string `json:"document_id,omitempty"`
Document_type string `json:"document_type,omitempty"`
ClientData string `json:"clientData,omitempty"`
}
// PayoutReply 支付请求响应
type PayoutReply struct {
Code int `json:"code,omitempty"`
Msg string `json:"msg,omitempty"`
Time int `json:"time,omitempty"`
Data PayoutReplyData `json:"data,omitempty"`
}
type PayoutReplyData struct {
Id string `json:"id,omitempty"`
CustomCode string `json:"custom_code,omitempty"`
ArrivalAmount string `json:"arrival_amount,omitempty"`
ArrivalCurrency string `json:"arrival_currency,omitempty"`
SourceAmount string `json:"source_amount,omitempty"`
SourceCurrency string `json:"source_currency,omitempty"`
Status string `json:"status,omitempty"`
}
type PagsmileClient struct {
log *log.Helper
out *PayoutClient
}
type PayoutClient struct {
AppId string
AppKey string
ApiUrl string
NotifyUrl string
}
func NewPagsmileClient(out *PayoutClient, logger log.Logger) *PagsmileClient {
return &PagsmileClient{
out: out,
log: log.NewHelper(logger),
}
}
// genAuthorization 生成签名授权
func (uc *PayoutClient) genAuthorization(ctx context.Context, req interface{}) string {
mapJson := utils.StructToMapJson(req)
sign := pscrypto.GetSign(mapJson, uc.AppKey)
return sign
}
// Payout 打款
func (c *PayoutClient) Payout(ctx context.Context, req *PayoutReq) (*PayoutReplyData, error) {
req.NotifyUrl = c.NotifyUrl
auth := c.genAuthorization(ctx, *req)
str := fmt.Sprintf("auth: %s", auth)
fmt.Println(str)
log.Info(str)
b, err := json.Marshal(req)
if err != nil {
return nil, fmt.Errorf("Payout marshl json failed: %w", err)
}
// 记录当前payout请求全数据:
str = fmt.Sprintf("payout req: %s - %s\n", req.CustomCode, string(b))
fmt.Println(str)
log.Info(str)
// bhttp, err := bhttp.NewBhttpClient()
// if err != nil {
// return nil, fmt.Errorf("Payout new bhttp client failed: %w", err)
// }
// bhttp.SetHeader("Authorization", auth)
// bhttp.SetHeader("AppId", c.AppId)
// bhttp.SetBody(b)
// payoutUrl := fmt.Sprintf("%s/api/payout", c.ApiUrl)
// str = fmt.Sprintf("payoutUrl:%s", payoutUrl)
// fmt.Println(str)
// log.Info(str)
// body, err := bhttp.DoPost(payoutUrl)
// if err != nil {
// return nil, fmt.Errorf("Payout do post failed: %w", err)
// }
// str = fmt.Sprintf("[%s] payout body: %s - %s\n", time.Now().Format("2006-01-02 15:04:05"), req.CustomCode, string(body))
// fmt.Println(str)
// log.Info(str)
var reply PayoutReply
// err = json.Unmarshal(body, &reply)
// if err != nil {
// return nil, fmt.Errorf("Payout unmarshal failed: %w", err)
// }
//
// if reply.Code != http.StatusOK {
// return nil, fmt.Errorf("Payout error: %s", reply.Msg)
// }
//
// if reply.Data.Status != "IN_PROCESSING" {
// return nil, fmt.Errorf("Payout failed: %s", reply.Data.Status)
// }
reply.Data.Id = "Test"
reply.Data.CustomCode = req.CustomCode
return &reply.Data, nil
}
// PayoutNotifyReq 打款回调请求参数
type PayoutNotifyReq struct {
PayoutId string `json:"payoutId,omitempty"`
CustomCode string `json:"custom_code,omitempty"`
Status string `json:"status,omitempty"`
Msg string `json:"msg,omitempty"`
Timestamp int64 `json:"timestamp,omitempty"`
}
// PayoutNotify 打款回调
func (c *PayoutClient) PayoutNotify(ctx context.Context, req *PayoutNotifyReq) error {
// 验证回调签名
auth := c.genAuthorization(ctx, *req)
fmt.Println("auth: ", auth)
httpContext := xhttp.RequestFromContext(ctx)
if httpContext == nil {
return fmt.Errorf("PayoutNotify http context is nil")
}
authHeader := httpContext.Header().Get("Authorization")
if authHeader != auth {
fmt.Printf("authHeader: %s, auth: %s \n", authHeader, auth)
return fmt.Errorf("PayoutNotify auth failed")
}
return nil
}

View File

@ -0,0 +1,88 @@
package biz
import (
"time"
"sandc/pkg/pagination"
)
// PayoutUser 提现用户信息
type PayoutUser struct {
Id uint `json:"id"` // 用户ID
Platform string `json:"platform"` // 平台
Ip string `json:"ip"` // ip地址
Country string `json:"country"` // 国家
DeviceId string `json:"device_id"` // 设备ID
Version string `json:"version"` // 版本号
Uuid string `json:"uuid"` // 用户唯一ID根据ip, country,device_id生成
LoginDays uint `json:"login_days"` // 登录天数
CreatedAt time.Time `json:"created_at"` // 创建时间
UpdatedAt time.Time `json:"updated_at"` // 更新时间
ClientData string `json:"clientData"` // 客户端数据
}
// 提现记录
type PayoutRecord struct {
Id uint `json:"id"` // 提现记录ID
PayoutId string `json:"payout_id"` // 支付第三方id
RecordNo string `json:"record_no"` // 提现唯一编码
Channel string `json:"channel"` // 支付渠道
Uuid string `json:"uuid"` // 提现用户唯一编码
Account string `json:"account"` // 提现账号
ItemId uint `json:"item_id"` // 提现的item对应id
Amount float64 `json:"amount"` // 提现金额
Currency string `json:"currency"` // 货币单位
Status uint8 `json:"status"` // 提现状态 1:提现中,2:提现成功,3:提现失败
Ecpm uint8 `json:"ecpm"` // ecpm等级
Version string `json:"version"` // 版本号
CreatedAt time.Time `json:"created_at"` // 创建时间
UpdatedAt time.Time `json:"updated_at"` // 更新时间
Fail string `json:"fail"` // 提现失败原因
Email string `json:"email"` // 邮箱
}
// 分红记录
type BonusRecord struct {
Id uint `json:"id"` // 年月日时间ID
Dau uint `json:"dau"` // 原始dau
Pass uint `json:"pass"` // 通关总份额
Coin uint `json:"coin"` // 分红每一份额美分数
Bonus uint `json:"bonus"` // 服务器分红总额美分
BonusCur uint `json:"bonus_cur"` // 服务器实际分红总额美分
CreatedAt time.Time `json:"created_at"` // 创建时间
UpdatedAt time.Time `json:"updated_at"` // 更新时间
}
// SearchPayoutUserReq 查询提现用户信息请求
type SearchPayoutUserReq struct {
Page pagination.Paginator // 分页信息
DisablePaging bool
SelectFields string
SortBy string
Uuid string
StartTime time.Time
EndTime time.Time
}
// ListPayoutUser 提现用户信息列表
type ListPayoutUser struct {
Total int32
Items []*PayoutUser
}
// SearchPayoutRecordReq 查询提现记录请求
type SearchPayoutRecordReq struct {
Page pagination.Paginator // 分页信息
DisablePaging bool
SelectFields string
SortBy string
Uuid string
StartTime time.Time
EndTime time.Time
}
// ListPayoutRecord
type ListPayoutRecord struct {
Total int32
Items []*PayoutRecord
}

View File

@ -0,0 +1,34 @@
package biz
import (
"context"
"fmt"
"github.com/tx7do/kratos-transport/broker"
)
type ExampleStruct struct {
Name string `json:"name"`
ID int `json:"id"`
}
func ExampleCreator() broker.Any { return &ExampleStruct{} }
type ExmapleHandler func(_ context.Context, topic string, headers broker.Headers, msg *ExampleStruct) error
func RegisterExampleHandler(fnc ExmapleHandler) broker.Handler {
return func(ctx context.Context, event broker.Event) error {
if event.Error() != nil {
return event.Error()
}
msg, ok := event.Message().Body.(*ExampleStruct)
if !ok {
return fmt.Errorf("[Kafka] unsupported type: %T", event.Message().Body)
}
if err := fnc(ctx, event.Topic(), event.Message().Headers, msg); err != nil {
return err
}
return nil
}
}

View File

@ -0,0 +1,372 @@
package biz
import (
"context"
"fmt"
"strconv"
"strings"
"time"
v1 "sandc/api/eonline/v1"
"sandc/app/eonline/internal/biz/adjust"
"sandc/app/eonline/internal/biz/shushu"
"sandc/app/eonline/internal/conf"
"github.com/go-kratos/kratos/v2/log"
)
var gEnv string
var appConfig *conf.AppConfig
func InitReport(bootstrap *conf.Bootstrap) {
gEnv = strings.ToLower(bootstrap.Server.Env)
appConfig = bootstrap.AppConfig
log.Infof("InitReport gEnv[%s] AdjustId[%s] AdjustS2SToken[%s] AdjustEventTokenSuccess[%s] AdjustEventTokenFail[%s] SsAppId[%s]",
gEnv, appConfig.AdjustAppToken, appConfig.AdjustS2SToken, appConfig.AdjustEventTokenSuccess, appConfig.AdjustEventTokenFail, appConfig.SsAppId)
var err error
_, err = newAdjustClient()
if err != nil {
log.Fatalf("InitReport: adjust.NewAdjustClient err[%+v]", err)
}
_, err = newShuShuClient()
if err != nil {
log.Fatalf("InitReport: shushu.NewClient err[%+v]", err)
}
}
func GetAdjustData(req *v1.PayoutReq, errStr, ip string) *adjust.AdjustEventParams {
if req.DataAdjust == nil {
log.Infof("GetAdjustData error: req.DataAdjust is nil Deviceid[%s]", req.Deviceid)
return nil
}
data := &adjust.AdjustEventParams{
GpsAdid: req.DataAdjust.GpsAdid,
Adid: req.DataAdjust.Adid,
AndroidId: req.DataAdjust.AndroidId,
IpAddress: ip,
CreatedAtUnix: strconv.Itoa(int(time.Now().Unix())),
Currency: req.DataAdjust.Currency,
Environment: gEnv,
UserAgent: req.DataAdjust.UserAgent,
Price: req.DataAdjust.Price,
FailReason: errStr,
AppToken: appConfig.AdjustAppToken,
EventToken: appConfig.AdjustEventTokenSuccess,
S2S: "1",
ClientName: req.ClientName,
// AppToken: "5l2aubga4by8",
// EventToken: "xlwfxq",
}
if len(errStr) > 0 {
// data.EventToken = "t4c6tj"
data.EventToken = appConfig.AdjustEventTokenFail
}
return data
}
func GetAdjustData2(req *v1.PbAdjustData, errStr string) *adjust.AdjustEventParams {
if req == nil {
log.Infof("GetAdjustData2 error: req is nil")
return nil
}
data := &adjust.AdjustEventParams{
GpsAdid: req.GpsAdid,
Adid: req.Adid,
AndroidId: req.AndroidId,
IpAddress: req.IpAddress,
CreatedAtUnix: req.CreatedAtUnix,
Currency: req.Currency,
Environment: gEnv,
UserAgent: req.UserAgent,
Price: req.Price,
FailReason: errStr,
AppToken: req.AppToken,
EventToken: req.EventToken,
S2S: req.S2S,
ClientName: req.ClientName,
}
if len(errStr) > 0 {
// data.EventToken = "t4c6tj"
data.EventToken = appConfig.AdjustEventTokenFail
}
return data
}
func getReportKey(key string) string {
return fmt.Sprintf("report:%s", key)
}
func AddReportData(key string, adjustEventParams *adjust.AdjustEventParams, iapReport *shushu.SSIapProperties) {
data := &v1.PbReportData{
Adjust: &v1.PbAdjustData{
GpsAdid: adjustEventParams.GpsAdid,
Adid: adjustEventParams.Adid,
AndroidId: adjustEventParams.AndroidId,
IpAddress: adjustEventParams.IpAddress,
CreatedAtUnix: adjustEventParams.CreatedAtUnix,
Currency: adjustEventParams.Currency,
Environment: adjustEventParams.Environment,
UserAgent: adjustEventParams.UserAgent,
Price: adjustEventParams.Price,
FailReason: adjustEventParams.FailReason,
AppToken: adjustEventParams.AppToken,
EventToken: adjustEventParams.EventToken,
S2S: adjustEventParams.S2S,
ClientName: adjustEventParams.ClientName,
},
ShuShu: &v1.PbShuShuData{
GpsAdid: iapReport.GpsAdid,
AppToken: iapReport.AppToken,
EventToken: iapReport.EventToken,
S2S: iapReport.S2S,
AndroidId: iapReport.AndroidId,
Adid: iapReport.Adid,
IpAddress: iapReport.IpAddress,
CreatedAtUnix: iapReport.CreatedAtUnix,
UserAgent: iapReport.UserAgent,
Price: iapReport.Price,
Currency: iapReport.Currency,
FailReason: iapReport.FailReason,
PayoutId: iapReport.PayoutId,
MerchantReference: iapReport.MerchantReference,
PaymentMethod: iapReport.PaymentMethod,
PaymentType: iapReport.PaymentType,
PaymentNumber: iapReport.PaymentNumber,
IapName: iapReport.IapName,
GamecoinNumber: iapReport.GamecoinNumber,
GamecoinType: iapReport.GamecoinType,
SsAccountId: iapReport.SsAccountId,
SsDistinctId: iapReport.SsDistinctId,
SsSuperProperties: iapReport.SsSuperProperties,
ClientName: iapReport.ClientName,
},
Rf: uint32(time.Now().Unix()),
}
// AddReportOne(key, data)
key = getReportKey(key)
report := NewReportData(db_name, key)
*report.GetData(true) = *data
report.Expire(15 * 3600) // 提现平台最后一次发送回调消息是14小时
err := report.Save()
if err != nil {
log.Infof("report.Save error: key[%s] error[%+v]", key, err)
}
}
func GetReportData(key string) *v1.PbReportData {
// return GetReportOne(key)
key = getReportKey(key)
report := NewReportData(db_name, key)
err := report.Load()
if err != nil {
log.Infof("report.Load error: key[%s] error[%+v]", key, err)
return nil
}
data := report.GetData(false)
err = report.Delete()
if err != nil {
log.Infof("report.Delete error: key[%s] error[%+v]", key, err)
}
return data
}
func SendReport(ctx context.Context, adjustEventParams *adjust.AdjustEventParams, iapReport *shushu.SSIapProperties) {
if adjustEventParams == nil || iapReport == nil {
return
}
err1 := sendAdjustReport(ctx, adjustEventParams)
if err1 != nil {
log.Infof("adjust send err[%+v]", err1)
}
err2 := sendShuShuReport(iapReport)
if err2 != nil {
log.Infof("shushu send err[%+v]", err2)
}
if err1 == nil && err2 == nil {
log.Infof("SendReport successed: GpsAdid[%s]", adjustEventParams.GpsAdid)
}
}
func newAdjustClient() (adjust.AdjustClient, error) {
// return adjust.NewAdjustClient("5l2aubga4by8", "7ea35d86e3e6688c2debcadc4efd7230", gEnv)
return adjust.NewAdjustClient(appConfig.AdjustAppToken, appConfig.AdjustS2SToken, gEnv)
}
func sendAdjustReport(ctx context.Context, adjustEventParams *adjust.AdjustEventParams) error {
adjustClient, err := newAdjustClient()
if err != nil {
return fmt.Errorf("adjust.NewAdjustClient error: %v", err)
}
// 上报IAP数据
err = adjustClient.ReportEvent(ctx, adjustEventParams)
if err != nil {
return fmt.Errorf("adjustClient.ReportEvent error: %v", err)
}
return nil
}
func GetShuShuData(req *v1.PayoutReq, errStr, ip string) *shushu.SSIapProperties {
if req.DataAdjust == nil {
log.Infof("GetAdjustData error: req.DataAdjust is nil Deviceid[%s]", req.Deviceid)
return nil
}
data := &shushu.SSIapProperties{
// EventToken: "xlwfxq",
// AppToken: "5l2aubga4by8",
GpsAdid: req.DataAdjust.GpsAdid,
AppToken: appConfig.AdjustAppToken,
EventToken: appConfig.AdjustEventTokenSuccess,
S2S: "1",
AndroidId: req.DataAdjust.AndroidId,
Adid: req.DataAdjust.Adid,
IpAddress: ip,
CreatedAtUnix: strconv.Itoa(int(time.Now().Unix())),
UserAgent: req.DataAdjust.UserAgent,
Price: req.DataAdjust.Price,
Currency: req.DataAdjust.Currency,
FailReason: errStr,
PayoutId: "",
MerchantReference: "",
PaymentMethod: req.DataShuShu.PaymentMethod,
PaymentType: req.DataShuShu.PaymentType,
PaymentNumber: req.DataShuShu.PaymentNumber,
IapName: req.DataShuShu.IapName,
GamecoinNumber: req.DataShuShu.GamecoinNumber,
GamecoinType: req.DataShuShu.GamecoinType,
SsAccountId: req.DataShuShu.SsAccountId,
SsDistinctId: req.DataShuShu.SsDistinctId,
SsSuperProperties: req.DataShuShu.SsSuperProperties,
ClientName: req.ClientName,
}
if len(errStr) > 0 {
// data.EventToken = "t4c6tj"
data.EventToken = appConfig.AdjustEventTokenFail
}
return data
}
func GetShuShuData2(req *v1.PbShuShuData, errStr string) *shushu.SSIapProperties {
if req == nil {
log.Infof("GetAdjustData2 error: req is nil")
return nil
}
data := &shushu.SSIapProperties{
GpsAdid: req.GpsAdid,
AppToken: req.AppToken,
EventToken: req.EventToken,
S2S: req.S2S,
AndroidId: req.AndroidId,
Adid: req.Adid,
IpAddress: req.IpAddress,
CreatedAtUnix: req.CreatedAtUnix,
UserAgent: req.UserAgent,
Price: req.Price,
Currency: req.Currency,
FailReason: errStr,
PayoutId: req.PayoutId,
MerchantReference: req.MerchantReference,
PaymentMethod: req.PaymentMethod,
PaymentType: req.PaymentType,
PaymentNumber: req.PaymentNumber,
IapName: req.IapName,
GamecoinNumber: req.GamecoinNumber,
GamecoinType: req.GamecoinType,
SsAccountId: req.SsAccountId,
SsDistinctId: req.SsDistinctId,
SsSuperProperties: req.SsSuperProperties,
ClientName: req.ClientName,
}
if len(errStr) > 0 {
// data.EventToken = "t4c6tj"
data.EventToken = appConfig.AdjustEventTokenFail
}
return data
}
func newShuShuClient() (shushu.Client, error) {
// return shushu.NewClient("https://ss.zolnm.com", "3774fd57014846d99ccd145a76780866", gEnv)
return shushu.NewClient("https://ss.zolnm.com", appConfig.SsAppId, gEnv)
}
func sendShuShuReport(iapReport *shushu.SSIapProperties) error {
ssClient, err := newShuShuClient()
if err != nil {
return fmt.Errorf("shushu.NewClient error: %v", err)
}
propertiesMap := shushu.SSProperties{
"gps_adid": iapReport.GpsAdid,
"app_token": iapReport.AppToken,
"event_token": iapReport.EventToken,
"s2s": iapReport.S2S,
"android_id": iapReport.AndroidId,
"adid": iapReport.Adid,
"ip_address": iapReport.IpAddress,
"created_at_unix": iapReport.CreatedAtUnix,
"user_agent": iapReport.UserAgent,
"price": iapReport.Price,
"currency": iapReport.Currency,
"fail_reason": iapReport.FailReason,
"payout_id": iapReport.PayoutId,
"merchant_reference": iapReport.MerchantReference,
"payment_method": iapReport.PaymentMethod,
"payment_type": iapReport.PaymentType,
"payment_number": iapReport.PaymentNumber,
"iap_name": iapReport.IapName,
"gamecoin_number": iapReport.GamecoinNumber,
"gamecoin_type": iapReport.GamecoinType,
"ss_account_id": iapReport.SsAccountId,
"ss_distinct_id": iapReport.SsDistinctId,
"ss_super_properties": iapReport.SsSuperProperties,
"client_name": iapReport.ClientName,
}
// 上报IAP数据
if len(iapReport.FailReason) <= 0 {
eventName := "cash_out"
if gEnv == "qa" {
eventName = fmt.Sprintf("%s_qa", eventName)
}
err = ssClient.SyncIapData(iapReport.SsAccountId, iapReport.SsDistinctId, eventName, iapReport.IpAddress, propertiesMap)
if err != nil {
return fmt.Errorf("ssClient.SyncIapData error: %v", err)
}
} else {
eventName := "cash_fail"
if gEnv == "qa" {
eventName = fmt.Sprintf("%s_qa", eventName)
}
err = ssClient.ReportError(iapReport.SsAccountId, iapReport.SsDistinctId, eventName, iapReport.IpAddress, propertiesMap)
if err != nil {
return fmt.Errorf("ssClient.ReportError error: %v", err)
}
}
return nil
}
func CloseReport() {
log.Infof("CloseReport gEnv[%s] AdjustId[%s] AdjustS2SToken[%s] AdjustEventTokenSuccess[%s] AdjustEventTokenFail[%s] SsAppId[%s]",
gEnv, appConfig.AdjustAppToken, appConfig.AdjustS2SToken, appConfig.AdjustEventTokenSuccess, appConfig.AdjustEventTokenFail, appConfig.SsAppId)
}

View File

@ -0,0 +1,240 @@
package biz
import (
"errors"
"fmt"
"sync"
"time"
go_redis_orm "github.com/fananchong/go-redis-orm.v2"
"github.com/go-kratos/kratos/v2/log"
v1 "sandc/api/eonline/v1"
"sandc/app/eonline/internal/conf"
)
var (
G_SvrData *SvrData
MutexSvrData sync.RWMutex
ERR_INIT_USER_DATA = errors.New("init db user data error")
)
const (
db_name = "my_redis_db"
NS2MS int64 = 1_000_000 // 纳秒转换成毫秒,需要的被除数
)
func InitSvrData(bootstrap *conf.Bootstrap) {
go_redis_orm.SetNewRedisHandler(go_redis_orm.NewDefaultRedisClient)
err := go_redis_orm.CreateDB(db_name, []string{bootstrap.Data.Redis.Addr}, bootstrap.Data.Redis.Password, int(bootstrap.Data.Redis.Db))
if nil != err {
log.Fatalf("go_redis_orm.CreateDB err: dbName[%v] Idx[%v] Redis[%v] err[%v]", db_name, bootstrap.Data.Redis.Db, bootstrap.Data.Redis.Addr, err)
}
err = loadSvrData(uint32(bootstrap.Server.SvrId))
if err != nil {
log.Fatal("loadSvrData error: %v", err)
} else {
log.Infof("loadSvrData success")
}
}
func SaveSvrDataOnTimer() {
begin := time.Now().UnixNano()
var save map[string]interface{}
getSaveDataSvrData(&save)
var err error
go func() {
begin := time.Now().UnixNano()
err = saveDataSvrData(&save)
if err != nil {
log.Infof("saveDataSvrData error: %v", err)
}
save = nil
end := time.Now().UnixNano()
delta := end - begin
log.Infof("saveDataSvrData: begin[%dns] end[%dns], spend[%dms %dns]", begin, end, delta/NS2MS, delta%NS2MS)
}()
end := time.Now().UnixNano()
delta := end - begin
log.Infof("SaveSvrDataOnTimer: begin[%dns] end[%dns], spend[%dms %dns]", begin, end, delta/NS2MS, delta%NS2MS)
}
func SaveSvrDataShutDown() {
begin := time.Now().UnixNano()
err := saveDataSvrData2()
if err != nil {
log.Infof("saveSvrDataShutDown error: %v", err)
}
end := time.Now().UnixNano()
delta := end - begin
log.Infof("SaveSvrDataShutDown: begin[%dns] end[%dns], spend[%dms %dns]", begin, end, delta/NS2MS, delta%NS2MS)
}
func loadSvrData(key uint32) error {
MutexSvrData.Lock()
defer MutexSvrData.Unlock()
G_SvrData = NewSvrData(db_name, key)
if G_SvrData.IsLoad() {
log.Infof("神奇的已加载数据 SvrData")
return nil
}
var hasKey int
var err error
hasKey, err = G_SvrData.HasKey()
switch hasKey {
case 1:
err = G_SvrData.Load()
if err == nil {
initValueSvrDataOnLoad(key)
}
case 0:
// new
err := initValueSvrData(key)
if err != nil {
log.Error("initValueSvrData %v data error: %v", key, err)
return ERR_INIT_USER_DATA
}
case -1:
return err
default:
log.Error("loadSvrData HasKey key[%v] hasKey[%d] error: %v", key, hasKey, err)
return errors.New(fmt.Sprintf("error haskey[%d]", hasKey))
}
return nil
}
func initValueSvrData(key uint32) error {
initValueSvrDataOnLoad(key)
return nil
}
func initValueSvrDataOnLoad(key uint32) {
bChange := false
data := G_SvrData.GetData(false)
if data.LstChat == nil {
bChange = true
data.LstChat = []*v1.PbMsgOne{}
}
// if data.MapReportData == nil {
// bChange = true
// data.MapReportData = map[string]*v1.PbReportData{}
// }
if bChange {
G_SvrData.GetData(true)
}
}
func getSaveDataSvrData(temp *map[string]interface{}) error {
MutexSvrData.Lock()
defer MutexSvrData.Unlock()
var err error
*temp, err = G_SvrData.DirtyData()
return err
}
func saveDataSvrData(temp *map[string]interface{}) error {
MutexSvrData.RLock()
defer MutexSvrData.RUnlock()
var err error
err = G_SvrData.Save2(*temp)
return err
}
func saveDataSvrData2() error {
MutexSvrData.Lock()
defer MutexSvrData.Unlock()
var err error
err = G_SvrData.Save()
return err
}
func AddChat(req *v1.AddChatReq) {
MutexSvrData.Lock()
defer MutexSvrData.Unlock()
lst := &G_SvrData.GetData(true).LstChat
*lst = append(*lst, &v1.PbMsgOne{
TimeStamp: time.Now().UnixNano(),
Uuid: req.Uuid,
Name: "",
Msg: req.Msg,
})
lstNum := len(*lst)
if lstNum > 100 {
*lst = (*lst)[lstNum-100:]
}
}
func GetChat(timeStamp int64) []*v1.PbMsgOne {
MutexSvrData.RLock()
defer MutexSvrData.RUnlock()
lst := G_SvrData.GetData(false).LstChat
if timeStamp <= 0 {
return lst
}
for k, v := range lst {
if v.TimeStamp >= timeStamp {
return lst[k:]
}
}
return lst
}
func AddReportOne(key string, data *v1.PbReportData) {
// MutexSvrData.Lock()
// defer MutexSvrData.Unlock()
//
// now := uint32(time.Now().Unix())
//
// svrData := G_SvrData.GetData(true)
// lst := &svrData.MapReportData
//
// // 清理超时的
// if svrData.RfClearReportData+30*60 <= now {
// svrData.RfClearReportData = now
//
// for k, v := range *lst {
// if v.Rf+15*60*60 <= now { // 提现平台最后一次发送回调消息是14小时
// delete(*lst, k)
// }
// }
// }
//
// (*lst)[key] = data
}
func GetReportOne(key string) *v1.PbReportData {
// MutexSvrData.Lock()
// defer MutexSvrData.Unlock()
//
// lst := &G_SvrData.GetData(false).MapReportData
//
// if v, ok := (*lst)[key]; ok {
// delete(*lst, key)
// return v
// }
//
return nil
}

View File

@ -0,0 +1,240 @@
package shushu
import (
"encoding/json"
"fmt"
"time"
"sandc/pkg/bhttp"
"sandc/pkg/utils"
"github.com/go-kratos/kratos/v2/log"
)
// 定义数数client的接口
type Client interface {
SyncIapData(accountId, distinctId, eventName string, ip string, properties SSProperties) error
ReportError(accountId, distinctId, eventName string, ip string, properties SSProperties) error
}
// 定义数数client的实例
type client struct {
serverUrl string
appId string
env string
service *bhttp.BhttpService
}
// SyncData 定义数数上传结构体
type SyncData struct {
Appid string `json:"appid,omitempty"`
Debug int `json:"debug,omitempty"`
Data Data `json:"data,omitempty"`
}
type Data struct {
AccountId string `json:"#account_id,omitempty"`
DistinctId string `json:"#distinct_id,omitempty"`
Type string `json:"#type,omitempty"`
Ip string `json:"#ip,omitempty"`
Uuid string `json:"#uuid,omitempty"`
Time string `json:"#time,omitempty"`
EventName string `json:"#event_name,omitempty"`
Properties interface{} `json:"properties,omitempty"`
}
// SSIapProperties 定义数数上传Properties结构体
type SSIapProperties struct {
// Add your properties here
GpsAdid string `json:"gps_adid"` // 用户的gaid
AppToken string `json:"app_token"` // 控制面板上的 Adjust 应用识别码
EventToken string `json:"event_token"` // 控制面板上的 Adjust 事件识别码
S2S string `json:"s2s"` // s2s 参数设置为 1
AndroidId string `json:"android_id"` // 原始安卓 ID
Adid string `json:"adid"` // 与设备关联的 Adjust 标识符
IpAddress string `json:"ip_address"` // 设备 IP 地址。用于将事件关联至第三方 (例如 Google) 并在回传中包含位置相关信息 (例如city 、 postal_code )。 ip_address参数仅接受 IPv4 地址。当前不支持 IPv6。
CreatedAtUnix string `json:"created_at_unix"` // 事件发生的日期和时间。
UserAgent string `json:"user_agent"` // 设备的User-Agent。必须进行 URL 编码。
Price string `json:"price"` // 客户端上报的价格
Currency string `json:"currency"` // 货币单位
FailReason string `json:"fail_reason"` // 失败原因
PayoutId string `json:"payout_id"` // 提现订单号1实例TS202504150316045rg110SPMDjPB
MerchantReference string `json:"merchant_reference"` // 提现订单号2实例PGs bfd267c7823a80d97519197a30bfdf28
PaymentMethod string `json:"payment_method"` // 收款方式
PaymentType string `json:"payment_type"` // 账户形式
PaymentNumber string `json:"payment_number"` // 账户号码
IapName string `json:"iap_name"` // 商品名称
GamecoinNumber string `json:"gamecoin_number"` // 提现消耗的虚拟货币数
GamecoinType string `json:"gamecoin_type"` // 提现消耗的虚拟货币类型
SsAccountId string `json:"ss_account_id"` // 数数账号ID
SsDistinctId string `json:"ss_distinct_id"` // 数数访客ID
SsSuperProperties string `json:"ss_super_properties"` // 数数的公共属性和预制属性
ClientName string `json:"client_name"` // 客户端包名
// Value float64 `json:"value"`
// Platform string `json:"platform"`
// PlatformChannel string `json:"platform_channel"`
// PlatformOs string `json:"platform_os"`
// ProductId string `json:"product_id"`
// OrderId string `json:"order_id"`
// Currency string `json:"currency"`
// Environment string `json:"environment"`
// AdNetwork string `json:"ad_network"`
// Campaign string `json:"campaign"`
// Adgroup string `json:"adgroup"`
// Creative string `json:"creative"`
}
// SSErrorProperties 定义数数上报的错误信息
type SSErrorProperties struct {
Value float64 `json:"value"`
Platform string `json:"platform"`
ProductId string `json:"product_id"`
OrderId string `json:"order_id"`
Currency string `json:"currency"`
Environment string `json:"environment"`
Msg string `json:"msg"`
AdNetwork string `json:"ad_network"`
Campaign string `json:"campaign"`
Adgroup string `json:"adgroup"`
Creative string `json:"creative"`
PlatformChannel string `json:"platform_channel"`
PlatformOs string `json:"platform_os"`
}
type SSProperties map[string]interface{}
// SyncRes 定义数数上传返回结构体
type SyncRes struct {
Code int `json:"code"`
Message string `json:"msg"`
}
func NewClient(serverUrl string, appId string, env string) (Client, error) {
service, err := bhttp.NewBhttpService(bhttp.WithCheckStatusOk(true), bhttp.WithTimeout(30))
if err != nil {
return nil, err
}
service.Client.SetHeader("Content-Type", "application/json")
return &client{
appId: appId,
serverUrl: serverUrl,
env: env,
service: service,
}, nil
}
func (c *client) syncJson(accountId, distinctId, eventName string, ip string, properties interface{}) error {
debug := 0
if !c.IsProd() {
debug = 1
}
if accountId == "" && distinctId == "" {
return fmt.Errorf("accountId or distinctId is empty")
}
// 根据properties生成唯一的uuid
propertiesStr := utils.MD5Any(properties)
uuid := utils.GenerateUUID(propertiesStr)
syncData := &SyncData{
Appid: c.appId,
Debug: debug,
Data: Data{
AccountId: accountId,
DistinctId: distinctId,
Type: "track",
Ip: ip,
Uuid: uuid,
Time: time.Now().Format("2006-01-02 15:04:05.000"),
EventName: eventName,
Properties: properties,
},
}
postBody, err := json.Marshal(syncData)
if err != nil {
return fmt.Errorf("json.Marshal SyncIapData error: %v", err)
}
c.service.Client.SetBody(postBody)
url := fmt.Sprintf("%s/sync_json", c.serverUrl)
// utils.PrintLog("SyncIapData-url: %s", url)
// utils.PrintLog("SyncIapData-postbody: %s", postBody)
log.Infof("SyncIapData-url: %s", url)
log.Infof("SyncIapData-postbody: %s", postBody)
sendData := postBody
numMax := 1
for i := 0; i < numMax; i++ {
body, err := c.service.Client.DoPost(url)
if err != nil {
return fmt.Errorf("shushu server err: %s, reader: %s", err, sendData)
}
var res SyncRes
err = json.Unmarshal(body, &res)
if err != nil {
return fmt.Errorf("shushu Unmarshal err: %s, reader: %s", res.Message, sendData)
}
if res.Code == 0 {
log.Infof("shushu send successed: i[%d] reader: %s", i, sendData)
break
} else {
log.Infof("shushu res error: %s, i[%d] reader: %s", res.Message, i, sendData)
if i+1 >= numMax {
return fmt.Errorf("shushu res err: %s, reader: %s", res.Message, sendData)
}
}
}
return nil
}
func setSsSuperPropertiesMap(propertiesMap SSProperties) {
v, ok := propertiesMap["ss_super_properties"]
if !ok || v == nil {
log.Infof("setSsSuperPropertiesMap error: ss_super_properties not found in propertiesMap[%v]", propertiesMap)
return
}
ssSuperProperties, ok := v.(string)
if !ok {
log.Infof("setSsSuperPropertiesMap error: ss_super_properties not string[%v]", propertiesMap)
return
}
// 解析 ss_super_properties
var ssSuperPropertiesMap SSProperties
if ssSuperProperties != "" {
err := json.Unmarshal([]byte(ssSuperProperties), &ssSuperPropertiesMap)
if err != nil {
log.Infof("setSsSuperPropertiesMap error: unmarshal err[%v], ssSuperProperties[%s]", err, ssSuperProperties)
return
}
// 插入解析出来的新字段
for key, value := range ssSuperPropertiesMap {
if _, ok := propertiesMap[key]; !ok && key != "#zone_offset" {
propertiesMap[key] = value
}
}
} else {
log.Infof("setSsSuperPropertiesMap error: ss_super_properties is empty[%v]", propertiesMap)
}
}
func (c *client) ReportError(accountId, distinctId, eventName string, ip string, properties SSProperties) error {
setSsSuperPropertiesMap(properties)
return c.syncJson(accountId, distinctId, eventName, ip, properties)
}
func (c *client) SyncIapData(accountId, distinctId, eventName string, ip string, properties SSProperties) error {
setSsSuperPropertiesMap(properties)
return c.syncJson(accountId, distinctId, eventName, ip, properties)
}
func (c *client) IsProd() bool {
return c.env == "prod"
}

View File

@ -0,0 +1,164 @@
package biz
import (
"errors"
"fmt"
v1 "sandc/api/eonline/v1"
go_redis_orm "github.com/fananchong/go-redis-orm.v2"
"github.com/gomodule/redigo/redis"
"google.golang.org/protobuf/proto"
)
type SvrData struct {
__key uint32
data v1.PbSvrData
__dirtyData map[string]interface{}
__dirtyDataForStructFiled map[string]interface{}
__isLoad bool
__dbKey string
__dbName string
__expire uint
}
func NewSvrData(dbName string, key uint32) *SvrData {
return &SvrData{
__key: key,
__dbName: dbName,
__dbKey: "SvrData:" + fmt.Sprintf("%d", key),
__dirtyData: make(map[string]interface{}),
__dirtyDataForStructFiled: make(map[string]interface{}),
}
}
// 若访问数据库失败返回-1若 key 存在返回 1 ,否则返回 0 。
func (this *SvrData) HasKey() (int, error) {
db := go_redis_orm.GetDB(this.__dbName)
val, err := redis.Int(db.Do("EXISTS", this.__dbKey))
if err != nil {
return -1, err
}
return val, nil
}
func (this *SvrData) Load() error {
if this.__isLoad == true {
return errors.New("already load!")
}
db := go_redis_orm.GetDB(this.__dbName)
val, err := redis.Values(db.Do("HGETALL", this.__dbKey))
if err != nil {
return err
}
if len(val) == 0 {
return go_redis_orm.ERR_ISNOT_EXIST_KEY
}
var data struct {
Data []byte `redis:"data"`
}
if err := redis.ScanStruct(val, &data); err != nil {
return err
}
if err := proto.Unmarshal(data.Data, &this.data); err != nil {
return err
}
this.__isLoad = true
return nil
}
func (this *SvrData) Save() error {
if len(this.__dirtyData) == 0 && len(this.__dirtyDataForStructFiled) == 0 {
return nil
}
for k, _ := range this.__dirtyDataForStructFiled {
_ = k
if k == "data" {
data, err := proto.Marshal(&this.data)
if err != nil {
return err
}
this.__dirtyData["data"] = data
}
}
db := go_redis_orm.GetDB(this.__dbName)
if _, err := db.Do("HMSET", redis.Args{}.Add(this.__dbKey).AddFlat(this.__dirtyData)...); err != nil {
return err
}
if this.__expire != 0 {
if _, err := db.Do("EXPIRE", this.__dbKey, this.__expire); err != nil {
return err
}
}
this.__dirtyData = make(map[string]interface{})
this.__dirtyDataForStructFiled = make(map[string]interface{})
return nil
}
func (this *SvrData) Delete() error {
db := go_redis_orm.GetDB(this.__dbName)
_, err := db.Do("DEL", this.__dbKey)
if err == nil {
this.__isLoad = false
this.__dirtyData = make(map[string]interface{})
this.__dirtyDataForStructFiled = make(map[string]interface{})
}
return err
}
func (this *SvrData) IsLoad() bool {
return this.__isLoad
}
func (this *SvrData) Expire(v uint) {
this.__expire = v
}
func (this *SvrData) GetKey() uint32 {
return this.__key
}
func (this *SvrData) DirtyData() (map[string]interface{}, error) {
for k, _ := range this.__dirtyDataForStructFiled {
_ = k
if k == "data" {
data, err := proto.Marshal(&this.data)
if err != nil {
return nil, err
}
this.__dirtyData["data"] = data
}
}
data := make(map[string]interface{})
for k, v := range this.__dirtyData {
data[k] = v
}
this.__dirtyData = make(map[string]interface{})
this.__dirtyDataForStructFiled = make(map[string]interface{})
return data, nil
}
func (this *SvrData) Save2(dirtyData map[string]interface{}) error {
if len(dirtyData) == 0 {
return nil
}
db := go_redis_orm.GetDB(this.__dbName)
if _, err := db.Do("HMSET", redis.Args{}.Add(this.__dbKey).AddFlat(dirtyData)...); err != nil {
return err
}
if this.__expire != 0 {
if _, err := db.Do("EXPIRE", this.__dbKey, this.__expire); err != nil {
return err
}
}
return nil
}
func (this *SvrData) GetData(mutable bool) *v1.PbSvrData {
if mutable {
this.__dirtyDataForStructFiled["data"] = nil
}
return &this.data
}

View File

@ -0,0 +1,26 @@
package biz
import (
"github.com/go-kratos/kratos/v2/log"
)
func getUserData(uuid string) *UserData {
data := NewUserData(db_name, uuid)
err := data.Load()
if err != nil {
log.Infof("getUserData error: uuid[%s] error[%v]", uuid, err)
return nil
}
return data
}
func saveUserData(data *UserData) bool {
err := data.Save()
if err != nil {
log.Infof("getUserData error: uuid[%s] error[%v]", data.GetKey(), err)
return false
}
return true
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,105 @@
syntax = "proto3";
package kratos.api;
option go_package = "sandc/app/eonline/internal/conf;conf";
import "google/protobuf/duration.proto";
message Bootstrap {
Server server = 1;
Data data = 2;
Queue queue = 3;
Pagsmile pagsmile = 4;
ConfigFiles configFiles = 5;
AppConfig appConfig = 7;
}
message Server {
message HTTP {
string network = 1;
string addr = 2;
google.protobuf.Duration timeout = 3;
}
message GRPC {
string network = 1;
string addr = 2;
google.protobuf.Duration timeout = 3;
}
message ETCD {
repeated string addr = 1;
string username = 2;
string password = 3;
}
HTTP http = 1;
GRPC grpc = 2;
ETCD etcd = 3;
string trace_endpoint = 4;
string env = 6;
string geo_file = 7;
int32 svr_id = 8; // id
int32 first_day = 9; // 202309062023.9.6
string ver_check = 10; //
int32 timeoutTimerPer10Second = 11; // 10timer执行超时时间纳秒
}
message Data {
message Database {
string driver = 1;
string source = 2;
}
message Redis {
string network = 1;
string addr = 2;
int32 db = 3;
string password = 4;
int32 pool = 5;
google.protobuf.Duration read_timeout = 6;
google.protobuf.Duration write_timeout = 7;
}
Database database = 1;
Redis redis = 2;
}
message Queue {
message Kafka {
repeated string addrs = 1;
string topic = 2;
string group = 3;
string username = 4;
string password = 5;
}
message Asynq {
string network = 1;
string addr = 2;
int32 db = 3;
string password = 4;
int32 pool = 5;
google.protobuf.Duration read_timeout = 6;
google.protobuf.Duration write_timeout = 7;
int32 concurrency = 8;
}
Kafka kafka = 1;
Asynq asynq = 2;
}
message Pagsmile {
message Payout {
string app_id = 1;
string app_key = 2;
string api_url = 3;
string notify_url = 4;
}
Payout payout = 1;
}
message ConfigFiles {
string path = 1;
}
message AppConfig {
string adjustAppToken = 1;
string adjustS2SToken = 2;
string adjustEventTokenSuccess = 3;
string adjustEventTokenFail = 4;
string ssAppId = 5;
}

View File

@ -0,0 +1,115 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package google.protobuf;
option cc_enable_arenas = true;
option go_package = "google.golang.org/protobuf/types/known/durationpb";
option java_package = "com.google.protobuf";
option java_outer_classname = "DurationProto";
option java_multiple_files = true;
option objc_class_prefix = "GPB";
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
// A Duration represents a signed, fixed-length span of time represented
// as a count of seconds and fractions of seconds at nanosecond
// resolution. It is independent of any calendar and concepts like "day"
// or "month". It is related to Timestamp in that the difference between
// two Timestamp values is a Duration and it can be added or subtracted
// from a Timestamp. Range is approximately +-10,000 years.
//
// # Examples
//
// Example 1: Compute Duration from two Timestamps in pseudo code.
//
// Timestamp start = ...;
// Timestamp end = ...;
// Duration duration = ...;
//
// duration.seconds = end.seconds - start.seconds;
// duration.nanos = end.nanos - start.nanos;
//
// if (duration.seconds < 0 && duration.nanos > 0) {
// duration.seconds += 1;
// duration.nanos -= 1000000000;
// } else if (duration.seconds > 0 && duration.nanos < 0) {
// duration.seconds -= 1;
// duration.nanos += 1000000000;
// }
//
// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
//
// Timestamp start = ...;
// Duration duration = ...;
// Timestamp end = ...;
//
// end.seconds = start.seconds + duration.seconds;
// end.nanos = start.nanos + duration.nanos;
//
// if (end.nanos < 0) {
// end.seconds -= 1;
// end.nanos += 1000000000;
// } else if (end.nanos >= 1000000000) {
// end.seconds += 1;
// end.nanos -= 1000000000;
// }
//
// Example 3: Compute Duration from datetime.timedelta in Python.
//
// td = datetime.timedelta(days=3, minutes=10)
// duration = Duration()
// duration.FromTimedelta(td)
//
// # JSON Mapping
//
// In JSON format, the Duration type is encoded as a string rather than an
// object, where the string ends in the suffix "s" (indicating seconds) and
// is preceded by the number of seconds, with nanoseconds expressed as
// fractional seconds. For example, 3 seconds with 0 nanoseconds should be
// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
// be expressed in JSON format as "3.000000001s", and 3 seconds and 1
// microsecond should be expressed in JSON format as "3.000001s".
//
message Duration {
// Signed seconds of the span of time. Must be from -315,576,000,000
// to +315,576,000,000 inclusive. Note: these bounds are computed from:
// 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
int64 seconds = 1;
// Signed fractions of a second at nanosecond resolution of the span
// of time. Durations less than one second are represented with a 0
// `seconds` field and a positive or negative `nanos` field. For durations
// of one second or more, a non-zero value for the `nanos` field must be
// of the same sign as the `seconds` field. Must be from -999,999,999
// to +999,999,999 inclusive.
int32 nanos = 2;
}

View File

@ -0,0 +1,10 @@
# Generated with protoc-gen-openapi
# https://github.com/google/gnostic/tree/master/cmd/protoc-gen-openapi
openapi: 3.0.3
info:
title: ""
version: 0.0.1
paths: {}
components:
schemas: {}

View File

@ -0,0 +1,662 @@
package serialization
import (
"errors"
"math"
)
var EmptyBytes []byte
var UnmarshalErr = errors.New("read not enough")
func init() {
EmptyBytes = make([]byte, 0)
}
type ByteBuf struct {
readerIndex int
writerIndex int
capacity int
bytes []byte
}
func NewByteBuf(capacity int) *ByteBuf {
v := &ByteBuf{}
v.bytes = make([]byte, capacity, capacity)
v.readerIndex = 0
v.writerIndex = 0
v.capacity = capacity
return v
}
func WrapByteBuf(bytes []byte) *ByteBuf {
v := &ByteBuf{}
v.bytes = bytes
v.readerIndex = 0
v.writerIndex = len(bytes)
v.capacity = len(bytes)
return v
}
func (buf *ByteBuf) Replace(bytes []byte) {
buf.bytes = bytes
buf.readerIndex = 0
buf.writerIndex = len(bytes)
buf.capacity = len(bytes)
}
func (buf *ByteBuf) Clear() {
buf.readerIndex = 0
buf.writerIndex = 0
}
func (buf *ByteBuf) Size() int {
return buf.writerIndex - buf.readerIndex
}
func (buf *ByteBuf) GetBytes() []byte {
return buf.bytes
}
func (buf *ByteBuf) CopyRemainData() []byte {
size := len(buf.bytes)
if size > 0 {
bs := make([]byte, size, size)
copy(bs, buf.bytes[buf.readerIndex:buf.writerIndex])
return bs
} else {
return EmptyBytes
}
}
func (buf *ByteBuf) CalcNewCap(curSize int, needSize int) int {
curSize *= 2
if curSize < 16 {
curSize = 16
}
for ; curSize < needSize; curSize *= 2 {
}
return curSize
}
func (buf *ByteBuf) EnsureWrite(remain int) {
if buf.writerIndex+remain > buf.capacity {
size := buf.Size()
if size+remain <= buf.capacity {
copy(buf.bytes, buf.bytes[buf.readerIndex:buf.writerIndex])
} else {
buf.capacity = buf.CalcNewCap(buf.capacity, size+remain)
newBytes := make([]byte, buf.capacity, buf.capacity)
copy(newBytes, buf.bytes[buf.readerIndex:buf.writerIndex])
buf.bytes = newBytes
}
buf.writerIndex = size
buf.readerIndex = 0
}
}
func (buf *ByteBuf) ReadBool() (bool, error) {
if buf.readerIndex < buf.writerIndex {
x := buf.bytes[buf.readerIndex] != 0
buf.readerIndex++
return x, nil
} else {
return false, UnmarshalErr
}
}
func (buf *ByteBuf) WriteBool(x bool) {
buf.EnsureWrite(1)
if x {
buf.bytes[buf.writerIndex] = 1
} else {
buf.bytes[buf.writerIndex] = 0
}
buf.writerIndex++
}
func (buf *ByteBuf) ReadByte() (byte, error) {
if buf.readerIndex < buf.writerIndex {
x := buf.bytes[buf.readerIndex]
buf.readerIndex++
return x, nil
} else {
return 0, UnmarshalErr
}
}
func (buf *ByteBuf) WriteByte(x byte) {
buf.EnsureWrite(1)
buf.bytes[buf.writerIndex] = x
buf.writerIndex++
}
func (buf *ByteBuf) ReadShort() (int16, error) {
if buf.readerIndex >= buf.writerIndex {
return 0, UnmarshalErr
}
h := uint32(buf.bytes[buf.readerIndex])
if h < 0x80 {
buf.readerIndex++
return int16(h), nil
} else if h < 0xc0 {
if buf.readerIndex+2 > buf.writerIndex {
return 0, UnmarshalErr
}
x := ((h & 0x3f) << 8) | uint32(buf.bytes[buf.readerIndex+1])
buf.readerIndex += 2
return int16(x), nil
} else if h == 0xff {
if buf.readerIndex+3 > buf.writerIndex {
return 0, UnmarshalErr
}
x := (uint32(buf.bytes[buf.readerIndex+1]) << 8) | uint32(buf.bytes[buf.readerIndex+2])
buf.readerIndex += 3
return int16(x), nil
} else {
return 0, UnmarshalErr
}
}
func (buf *ByteBuf) WriteShort(x int16) {
if x >= 0 {
if x < 0x80 {
buf.EnsureWrite(1)
buf.bytes[buf.writerIndex] = byte(x)
buf.writerIndex++
return
} else if x < 0x4000 {
buf.EnsureWrite(2)
buf.bytes[buf.writerIndex+1] = byte(x)
buf.bytes[buf.writerIndex] = byte((x >> 8) | 0x80)
buf.writerIndex += 2
return
}
}
buf.EnsureWrite(3)
buf.bytes[buf.writerIndex] = 0xff
buf.bytes[buf.writerIndex+2] = byte(x)
buf.bytes[buf.writerIndex+1] = byte(x >> 8)
buf.writerIndex += 3
}
func (buf *ByteBuf) ReadFshort() (int16, error) {
if buf.readerIndex+2 > buf.writerIndex {
return 0, UnmarshalErr
}
x := int(buf.bytes[buf.readerIndex]) | (int(buf.bytes[buf.readerIndex+1]) << 8)
buf.readerIndex += 2
return int16(x), nil
}
func (buf *ByteBuf) WriteFshort(x int16) {
buf.EnsureWrite(2)
buf.bytes[buf.writerIndex] = byte(x)
buf.bytes[buf.writerIndex+1] = byte(x >> 8)
buf.writerIndex += 2
}
func (buf *ByteBuf) ReadInt() (int32, error) {
x, err := buf.ReadUint()
return int32(x), err
}
func (buf *ByteBuf) WriteInt(x int32) {
buf.WriteUint(uint32(x))
}
func (buf *ByteBuf) ReadUint() (uint32, error) {
if buf.readerIndex >= buf.writerIndex {
return 0, UnmarshalErr
}
h := uint32(buf.bytes[buf.readerIndex])
if h < 0x80 {
buf.readerIndex++
return h, nil
} else if h < 0xc0 {
if buf.readerIndex+2 > buf.writerIndex {
return 0, UnmarshalErr
}
x := ((h & 0x3f) << 8) | uint32(buf.bytes[buf.readerIndex+1])
buf.readerIndex += 2
return x, nil
} else if h < 0xe0 {
if buf.readerIndex+3 > buf.writerIndex {
return 0, UnmarshalErr
}
x := ((h & 0x1f) << 16) | (uint32(buf.bytes[buf.readerIndex+1]) << 8) | uint32(buf.bytes[buf.readerIndex+2])
buf.readerIndex += 3
return x, nil
} else if h < 0xf0 {
if buf.readerIndex+4 > buf.writerIndex {
return 0, UnmarshalErr
}
x := ((h & 0x0f) << 24) | (uint32(buf.bytes[buf.readerIndex+1]) << 16) | (uint32(buf.bytes[buf.readerIndex+2]) << 8) | uint32(buf.bytes[buf.readerIndex+3])
buf.readerIndex += 4
return x, nil
} else {
if buf.readerIndex+5 > buf.writerIndex {
return 0, UnmarshalErr
}
x := (uint32(buf.bytes[buf.readerIndex+1]) << 24) | (uint32(buf.bytes[buf.readerIndex+2]) << 16) | (uint32(buf.bytes[buf.readerIndex+3]) << 8) | uint32(buf.bytes[buf.readerIndex+4])
buf.readerIndex += 5
return x, nil
}
}
func (buf *ByteBuf) WriteUint(x uint32) {
if x < 0x80 {
buf.EnsureWrite(1)
buf.bytes[buf.writerIndex] = byte(x)
buf.writerIndex++
} else if x < 0x4000 {
buf.EnsureWrite(2)
buf.bytes[buf.writerIndex+1] = byte(x)
buf.bytes[buf.writerIndex] = byte((x >> 8) | 0x80)
buf.writerIndex += 2
} else if x < 0x200000 {
buf.EnsureWrite(3)
buf.bytes[buf.writerIndex+2] = byte(x)
buf.bytes[buf.writerIndex+1] = byte(x >> 8)
buf.bytes[buf.writerIndex] = byte((x >> 16) | 0xc0)
buf.writerIndex += 3
} else if x < 0x10000000 {
buf.EnsureWrite(4)
buf.bytes[buf.writerIndex+3] = byte(x)
buf.bytes[buf.writerIndex+2] = byte(x >> 8)
buf.bytes[buf.writerIndex+1] = byte(x >> 16)
buf.bytes[buf.writerIndex] = byte((x >> 24) | 0xe0)
buf.writerIndex += 4
} else {
buf.EnsureWrite(5)
buf.bytes[buf.writerIndex] = 0xf0
buf.bytes[buf.writerIndex+4] = byte(x)
buf.bytes[buf.writerIndex+3] = byte(x >> 8)
buf.bytes[buf.writerIndex+2] = byte(x >> 16)
buf.bytes[buf.writerIndex+1] = byte(x >> 24)
buf.writerIndex += 5
}
}
func (buf *ByteBuf) ReadFint() (int32, error) {
if buf.readerIndex+4 > buf.writerIndex {
return 0, UnmarshalErr
}
x := int32(uint(buf.bytes[buf.readerIndex]) | (uint(buf.bytes[buf.readerIndex+1]) << 8) |
(uint(buf.bytes[buf.readerIndex+2]) << 16) | (uint(buf.bytes[buf.readerIndex+3]) << 24))
buf.readerIndex += 4
return x, nil
}
func (buf *ByteBuf) WriteFint(x int32) {
buf.EnsureWrite(4)
buf.bytes[buf.writerIndex] = byte(x)
buf.bytes[buf.writerIndex+1] = byte(x >> 8)
buf.bytes[buf.writerIndex+2] = byte(x >> 16)
buf.bytes[buf.writerIndex+3] = byte(x >> 24)
buf.writerIndex += 4
}
func (buf *ByteBuf) ReadLong() (int64, error) {
x, err := buf.ReadUlong()
return int64(x), err
}
func (buf *ByteBuf) WriteLong(x int64) {
buf.WriteUlong(uint64(x))
}
func (buf *ByteBuf) ReadUlong() (uint64, error) {
if buf.readerIndex >= buf.writerIndex {
return 0, UnmarshalErr
}
h := uint64(buf.bytes[buf.readerIndex])
if h < 0x80 {
buf.readerIndex++
return h, nil
} else if h < 0xc0 {
if buf.readerIndex+2 > buf.writerIndex {
return 0, UnmarshalErr
}
x := ((h & 0x3f) << 8) | uint64(buf.bytes[buf.readerIndex+1])
buf.readerIndex += 2
return x, nil
} else if h < 0xe0 {
if buf.readerIndex+3 > buf.writerIndex {
return 0, UnmarshalErr
}
x := ((h & 0x1f) << 16) | (uint64(buf.bytes[buf.readerIndex+1]) << 8) | uint64(buf.bytes[buf.readerIndex+2])
buf.readerIndex += 3
return x, nil
} else if h < 0xf0 {
if buf.readerIndex+4 > buf.writerIndex {
return 0, UnmarshalErr
}
x := ((h & 0x1f) << 24) | (uint64(buf.bytes[buf.readerIndex+1]) << 16) | (uint64(buf.bytes[buf.readerIndex+2]) << 8) |
uint64(buf.bytes[buf.readerIndex+3])
buf.readerIndex += 4
return x, nil
} else if h < 0xf8 {
if buf.readerIndex+5 > buf.writerIndex {
return 0, UnmarshalErr
}
x := ((h & 0x7) << 32) | (uint64(buf.bytes[buf.readerIndex+1]) << 24) | (uint64(buf.bytes[buf.readerIndex+2]) << 16) |
(uint64(buf.bytes[buf.readerIndex+3]) << 8) | uint64(buf.bytes[buf.readerIndex+4])
buf.readerIndex += 5
return x, nil
} else if h < 0xfc {
if buf.readerIndex+6 > buf.writerIndex {
return 0, UnmarshalErr
}
x := ((h & 0x3) << 40) | (uint64(buf.bytes[buf.readerIndex+1]) << 32) | (uint64(buf.bytes[buf.readerIndex+2]) << 24) |
(uint64(buf.bytes[buf.readerIndex+3]) << 16) | (uint64(buf.bytes[buf.readerIndex+4]) << 8) |
(uint64(buf.bytes[buf.readerIndex+5]))
buf.readerIndex += 6
return x, nil
} else if h < 0xfe {
if buf.readerIndex+7 > buf.writerIndex {
return 0, UnmarshalErr
}
x := ((h & 0x1) << 48) | (uint64(buf.bytes[buf.readerIndex+1]) << 40) | (uint64(buf.bytes[buf.readerIndex+2]) << 32) |
(uint64(buf.bytes[buf.readerIndex+3]) << 24) | (uint64(buf.bytes[buf.readerIndex+4]) << 16) |
(uint64(buf.bytes[buf.readerIndex+5]) << 8) | (uint64(buf.bytes[buf.readerIndex+6]))
buf.readerIndex += 7
return x, nil
} else if h < 0xff {
if buf.readerIndex+8 > buf.writerIndex {
return 0, UnmarshalErr
}
x := (uint64(buf.bytes[buf.readerIndex+1]) << 48) | (uint64(buf.bytes[buf.readerIndex+2]) << 40) |
(uint64(buf.bytes[buf.readerIndex+3]) << 32) | (uint64(buf.bytes[buf.readerIndex+4]) << 24) |
(uint64(buf.bytes[buf.readerIndex+5]) << 16) | (uint64(buf.bytes[buf.readerIndex+6]) << 8) |
(uint64(buf.bytes[buf.readerIndex+7]))
buf.readerIndex += 8
return x, nil
} else {
if buf.readerIndex+9 > buf.writerIndex {
return 0, UnmarshalErr
}
x := (uint64(buf.bytes[buf.readerIndex+1]) << 56) | (uint64(buf.bytes[buf.readerIndex+2]) << 48) |
(uint64(buf.bytes[buf.readerIndex+3]) << 40) | (uint64(buf.bytes[buf.readerIndex+4]) << 32) |
(uint64(buf.bytes[buf.readerIndex+5]) << 24) | (uint64(buf.bytes[buf.readerIndex+6]) << 16) |
(uint64(buf.bytes[buf.readerIndex+7]) << 8) | (uint64(buf.bytes[buf.readerIndex+8]))
buf.readerIndex += 9
return x, nil
}
}
func (buf *ByteBuf) WriteUlong(x uint64) {
if x < 0x80 {
buf.EnsureWrite(1)
buf.bytes[buf.writerIndex] = byte(x)
buf.writerIndex++
} else if x < 0x4000 {
buf.EnsureWrite(2)
buf.bytes[buf.writerIndex+1] = byte(x)
buf.bytes[buf.writerIndex] = byte((x >> 8) | 0x80)
buf.writerIndex += 2
} else if x < 0x200000 {
buf.EnsureWrite(3)
buf.bytes[buf.writerIndex+2] = byte(x)
buf.bytes[buf.writerIndex+1] = byte(x >> 8)
buf.bytes[buf.writerIndex] = byte((x >> 16) | 0xc0)
buf.writerIndex += 3
} else if x < 0x10000000 {
buf.EnsureWrite(4)
buf.bytes[buf.writerIndex+3] = byte(x)
buf.bytes[buf.writerIndex+2] = byte(x >> 8)
buf.bytes[buf.writerIndex+1] = byte(x >> 16)
buf.bytes[buf.writerIndex] = byte((x >> 24) | 0xe0)
buf.writerIndex += 4
} else if x < 0x800000000 {
buf.EnsureWrite(5)
buf.bytes[buf.writerIndex+4] = byte(x)
buf.bytes[buf.writerIndex+3] = byte(x >> 8)
buf.bytes[buf.writerIndex+2] = byte(x >> 16)
buf.bytes[buf.writerIndex+1] = byte(x >> 24)
buf.bytes[buf.writerIndex] = byte((x >> 32) | 0xf0)
buf.writerIndex += 5
} else if x < 0x40000000000 {
buf.EnsureWrite(6)
buf.bytes[buf.writerIndex+5] = byte(x)
buf.bytes[buf.writerIndex+4] = byte(x >> 8)
buf.bytes[buf.writerIndex+3] = byte(x >> 16)
buf.bytes[buf.writerIndex+2] = byte(x >> 24)
buf.bytes[buf.writerIndex+1] = byte(x >> 32)
buf.bytes[buf.writerIndex] = byte((x >> 40) | 0xf8)
buf.writerIndex += 6
} else if x < 0x200000000000 {
buf.EnsureWrite(7)
buf.bytes[buf.writerIndex+6] = byte(x)
buf.bytes[buf.writerIndex+5] = byte(x >> 8)
buf.bytes[buf.writerIndex+4] = byte(x >> 16)
buf.bytes[buf.writerIndex+3] = byte(x >> 24)
buf.bytes[buf.writerIndex+2] = byte(x >> 32)
buf.bytes[buf.writerIndex+1] = byte(x >> 40)
buf.bytes[buf.writerIndex] = byte((x >> 48) | 0xfc)
buf.writerIndex += 7
} else if x < 0x100000000000000 {
buf.EnsureWrite(8)
buf.bytes[buf.writerIndex+7] = byte(x)
buf.bytes[buf.writerIndex+6] = byte(x >> 8)
buf.bytes[buf.writerIndex+5] = byte(x >> 16)
buf.bytes[buf.writerIndex+4] = byte(x >> 24)
buf.bytes[buf.writerIndex+3] = byte(x >> 32)
buf.bytes[buf.writerIndex+2] = byte(x >> 40)
buf.bytes[buf.writerIndex+1] = byte(x >> 48)
buf.bytes[buf.writerIndex] = byte((x >> 56) | 0xfe)
buf.writerIndex += 8
} else {
buf.EnsureWrite(9)
buf.bytes[buf.writerIndex+8] = byte(x)
buf.bytes[buf.writerIndex+7] = byte(x >> 8)
buf.bytes[buf.writerIndex+6] = byte(x >> 16)
buf.bytes[buf.writerIndex+5] = byte(x >> 24)
buf.bytes[buf.writerIndex+4] = byte(x >> 32)
buf.bytes[buf.writerIndex+3] = byte(x >> 40)
buf.bytes[buf.writerIndex+2] = byte(x >> 48)
buf.bytes[buf.writerIndex+1] = byte(x >> 56)
buf.bytes[buf.writerIndex] = 0xff
buf.writerIndex += 9
}
}
func (buf *ByteBuf) ReadFlong() (int64, error) {
if buf.readerIndex+8 > buf.writerIndex {
return 0, UnmarshalErr
}
x := (uint64(buf.bytes[buf.readerIndex+7]) << 56) | (uint64(buf.bytes[buf.readerIndex+6]) << 48) |
(uint64(buf.bytes[buf.readerIndex+5]) << 40) | (uint64(buf.bytes[buf.readerIndex+4]) << 32) |
(uint64(buf.bytes[buf.readerIndex+3]) << 24) | (uint64(buf.bytes[buf.readerIndex+2]) << 16) |
(uint64(buf.bytes[buf.readerIndex+1]) << 8) | (uint64(buf.bytes[buf.readerIndex]))
buf.readerIndex += 8
return int64(x), nil
}
func (buf *ByteBuf) WriteFlong(x int64) {
buf.EnsureWrite(8)
buf.bytes[buf.writerIndex] = byte(x)
buf.bytes[buf.writerIndex+1] = byte(x >> 8)
buf.bytes[buf.writerIndex+2] = byte(x >> 16)
buf.bytes[buf.writerIndex+3] = byte(x >> 24)
buf.bytes[buf.writerIndex+4] = byte(x >> 32)
buf.bytes[buf.writerIndex+5] = byte(x >> 40)
buf.bytes[buf.writerIndex+6] = byte(x >> 48)
buf.bytes[buf.writerIndex+7] = byte(x >> 56)
buf.writerIndex += 8
}
func (buf *ByteBuf) ReadFloat() (float32, error) {
if x, err := buf.ReadFint(); err == nil {
return math.Float32frombits(uint32(x)), nil
} else {
return 0, err
}
}
func (buf *ByteBuf) WriteFloat(x float32) {
buf.WriteFint(int32(math.Float32bits(x)))
}
func (buf *ByteBuf) ReadDouble() (float64, error) {
if x, err := buf.ReadFlong(); err == nil {
return math.Float64frombits(uint64(x)), nil
} else {
return 0, err
}
}
func (buf *ByteBuf) WriteDouble(x float64) {
buf.WriteFlong(int64(math.Float64bits(x)))
}
func (buf *ByteBuf) ReadSize() (int, error) {
x, err := buf.ReadUint()
return int(x), err
}
func (buf *ByteBuf) WriteSize(x int) {
buf.WriteUint(uint32(x))
}
// marshal int
// n -> (n << 1) ^ (n >> 31)
// Read
// (x >>> 1) ^ ((x << 31) >> 31)
// (x >>> 1) ^ -(n&1)
func (buf *ByteBuf) ReadSint() (int32, error) {
if x, err := buf.ReadUint(); err == nil {
return int32((x >> 1) ^ ((x & 1) << 31)), nil
} else {
return 0, err
}
}
func (buf *ByteBuf) WriteSint(x int32) {
buf.WriteUint((uint32(x) << 1) ^ (uint32(x) >> 31))
}
// marshal long
// n -> (n << 1) ^ (n >> 63)
// Read
// (x >>> 1) ^((x << 63) >> 63)
// (x >>> 1) ^ -(n&1L)
func (buf *ByteBuf) ReadSlong() (int64, error) {
if x, err := buf.ReadUlong(); err == nil {
return int64((x >> 1) ^ ((x & 1) << 63)), nil
} else {
return 0, err
}
}
func (buf *ByteBuf) WriteSlong(x int64) {
buf.WriteUlong((uint64(x) << 1) ^ (uint64(x) >> 31))
}
func (buf *ByteBuf) WriteString(x string) {
bs := []byte(x)
buf.WriteSize(len(bs))
buf.WriteBytesWithoutSize(bs)
}
func (buf *ByteBuf) ReadString() (string, error) {
if size, err := buf.ReadSize(); err == nil {
if buf.readerIndex+size > buf.writerIndex {
return "", UnmarshalErr
}
s := string(buf.bytes[buf.readerIndex : buf.readerIndex+size])
buf.readerIndex += size
return s, nil
} else {
return "", err
}
}
func (buf *ByteBuf) ReadBytes() ([]byte, error) {
if size, err := buf.ReadSize(); err == nil {
if size == 0 {
return EmptyBytes, nil
} else if buf.readerIndex+size > buf.writerIndex {
return nil, UnmarshalErr
} else {
bs := make([]byte, size)
copy(bs, buf.bytes[buf.readerIndex:buf.readerIndex+size])
buf.readerIndex += size
return bs, nil
}
} else {
return nil, err
}
}
func (buf *ByteBuf) WriteBytes(x []byte) {
size := len(x)
buf.WriteSize(size)
if size > 0 {
buf.EnsureWrite(size)
copy(buf.bytes[buf.writerIndex:], x)
buf.writerIndex += size
}
}
func (buf *ByteBuf) WriteBytesWithSize(x []byte) {
buf.WriteBytes(x)
}
func (buf *ByteBuf) WriteBytesWithoutSize(x []byte) {
size := len(x)
buf.EnsureWrite(size)
copy(buf.bytes[buf.writerIndex:], x)
buf.writerIndex += size
}
func (buf *ByteBuf) ReadVector2() (Vector2, error) {
if x, err := buf.ReadFloat(); err == nil {
if y, err2 := buf.ReadFloat(); err2 == nil {
return Vector2{X: x, Y: y}, nil
}
}
return Vector2{}, UnmarshalErr
}
func (buf *ByteBuf) WriteVector2(x Vector2) {
buf.WriteFloat(x.X)
buf.WriteFloat(x.Y)
}
func (buf *ByteBuf) ReadVector3() (Vector3, error) {
if x, err := buf.ReadFloat(); err == nil {
if y, err2 := buf.ReadFloat(); err2 == nil {
if z, err3 := buf.ReadFloat(); err3 == nil {
return Vector3{X: x, Y: y, Z: z}, nil
}
}
}
return Vector3{}, UnmarshalErr
}
func (buf *ByteBuf) WriteVector3(x Vector3) {
buf.WriteFloat(x.X)
buf.WriteFloat(x.Y)
buf.WriteFloat(x.Z)
}
func (buf *ByteBuf) ReadVector4() (Vector4, error) {
if x, err := buf.ReadFloat(); err == nil {
if y, err2 := buf.ReadFloat(); err2 == nil {
if z, err3 := buf.ReadFloat(); err3 == nil {
if w, err4 := buf.ReadFloat(); err4 == nil {
return Vector4{X: x, Y: y, Z: z, W: w}, nil
}
}
}
}
return Vector4{}, UnmarshalErr
}
func (buf *ByteBuf) WriteVector4(x Vector4) {
buf.WriteFloat(x.X)
buf.WriteFloat(x.Y)
buf.WriteFloat(x.Z)
buf.WriteFloat(x.W)
}

View File

@ -0,0 +1,7 @@
package serialization
type ISerializable interface {
GetTypeId() int32
Serialize(buf *ByteBuf)
Deserialize(buf *ByteBuf) error
}

View File

@ -0,0 +1,10 @@
package serialization
type Vector2 struct {
X float32
Y float32
}
func NewVector2(x float32, y float32) Vector2 {
return Vector2{X: x, Y: y}
}

View File

@ -0,0 +1,11 @@
package serialization
type Vector3 struct {
X float32
Y float32
Z float32
}
func NewVector3(x float32, y float32, z float32) Vector3 {
return Vector3{X: x, Y: y, Z: z}
}

View File

@ -0,0 +1,12 @@
package serialization
type Vector4 struct {
X float32
Y float32
Z float32
W float32
}
func NewVector4(x float32, y float32, z float32, w float32) Vector4 {
return Vector4{X: x, Y: y, Z: z, W: w}
}

View File

@ -0,0 +1,205 @@
package serialization
import (
"bytes"
"testing"
)
func TestMarshal(t *testing.T) {
buf := NewByteBuf(10)
for i := 0; i < 2; i++ {
x := i != 0
buf.WriteBool(x)
if v, err := buf.ReadBool(); err != nil || v != x {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
for i := 0; i < 256; i = i*3/2 + 1 {
x := byte(i)
buf.WriteByte(x)
if v, err := buf.ReadByte(); err != nil || v != x {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
for i := 0; i < 0x10000; i = i*3/2 + 1 {
x := int16(i)
buf.WriteShort(x)
if v, err := buf.ReadShort(); err != nil || v != x {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
for i := 0; i < 0x10000; i = i*3/2 + 1 {
x := int16(i)
buf.WriteFshort(x)
if v, err := buf.ReadFshort(); err != nil || v != x {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
for i := 0; i < 0x1000000000; i = i*3/2 + 1 {
x := int32(i)
buf.WriteInt(x)
if v, err := buf.ReadInt(); err != nil || v != x {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
for i := 0; i < 0x1000000000; i = i*3/2 + 1 {
x := int32(i)
buf.WriteFint(x)
if v, err := buf.ReadFint(); err != nil || v != x {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
for i := 0; i < 0x100000000; i = i*3/2 + 1 {
x := int(i)
buf.WriteSize(x)
if v, err := buf.ReadSize(); err != nil || v != x {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
for i := 0; i < 0x100000000; i = i*3/2 + 1 {
x := int32(i)
buf.WriteSint(x)
if v, err := buf.ReadSint(); err != nil || v != x {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
for i := 0; i < 0x1000000000000000; i = i*3/2 + 1 {
x := int64(i)
buf.WriteLong(x)
if v, err := buf.ReadLong(); err != nil || v != x {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
x = -x
buf.WriteLong(x)
if v, err := buf.ReadLong(); err != nil || v != x {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
for i := 0; i < 0x100000000; i = i*3/2 + 1 {
x := float32(i)
buf.WriteFloat(x)
if v, err := buf.ReadFloat(); err != nil || v != x {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
for i := 0; i < 0x100000000; i = i*3/2 + 1 {
x := float64(i)
buf.WriteDouble(x)
if v, err := buf.ReadDouble(); err != nil || v != x {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
{
x := "walon"
buf.WriteString(x)
if v, err := buf.ReadString(); err != nil || v != x {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
{
x := Vector2{X: 1, Y: 2}
buf.WriteVector2(x)
if v, err := buf.ReadVector2(); err != nil || v != x {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
{
x := Vector3{X: 1, Y: 2, Z: 3}
buf.WriteVector3(x)
if v, err := buf.ReadVector3(); err != nil || v != x {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
{
x := Vector4{X: 1, Y: 2, Z: 3, W: 4}
buf.WriteVector4(x)
if v, err := buf.ReadVector4(); err != nil || v != x {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
{
x := []byte{1, 2, 3}
buf.WriteBytes(x)
if v, err := buf.ReadBytes(); err != nil || !bytes.Equal(x, v) {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
{
x := []byte{1, 2, 3, 4}
buf.WriteBytesWithoutSize(x)
if v, err := buf.ReadFint(); err != nil || v != 0x04030201 {
t.Fatalf("expect %v, get %v", x, v)
}
if buf.Size() != 0 {
t.Fatalf("expect empty. but size:%v, x:%v", buf.Size(), x)
}
}
}

View File

@ -0,0 +1,114 @@
package config
import (
"fmt"
"io/ioutil"
"strconv"
"strings"
"sandc/app/eonline/internal/config/bright/serialization"
Config "sandc/app/eonline/internal/config/config"
"github.com/go-kratos/kratos/v2/log"
)
var (
// 处理的特别数据
PublicCheckNum uint32 // 最大验证数量,超过这个数量,新的用户将不再出现信息验证入口
PublicCheckCoin int32 // 提交身份审核,提现奖励的钱/美分
PublicVersionMin uint32
// 读表
g_tables *Config.Tables // bin读表数据
g_path *string
)
func ConfigInit(path, env, ver_check *string) {
log.Info("读取cvs配置文件开始")
g_path = path
loadConfig(ver_check)
checkConfig(env)
log.Info("读取cvs配置文件结束")
}
func loadConfig(ver_check *string) {
readBin(ver_check)
}
func loader(file string) (*serialization.ByteBuf, error) {
if bytes, err := ioutil.ReadFile(*g_path + file + ".bytes"); err != nil {
return nil, err
} else {
return serialization.WrapByteBuf(bytes), nil
}
}
func readBin(ver_check *string) {
var err error
g_tables, err = Config.NewTables(loader)
if err != nil {
log.Fatal("readBin error: %s", err.Error())
} else {
log.Info("readBin success")
}
log.Debugf("%+v", g_tables.Tbglobal.Get(100000))
// 处理的特别数据
PublicCheckNum = 5000
PublicCheckCoin = 500
PublicVersionMin = Version2int(ver_check)
}
// 检查配置
func checkConfig(env *string) {
if *env != "qa" {
return
}
{
var item *Config.ConfiguserState
lst := g_tables.TbuserState.GetDataList()
for i := 0; i < len(lst); i++ {
item = lst[i]
if item.State < 0 || item.State > 1 {
log.Infof("checkConfig error: userState table id[%d] State[%d] < 0 || > 1", item.Id, item.State)
}
}
}
log.Info("checkConfig结束")
}
// 将二段、三段式版本号字符串如“1.0”、“1.0.1”转换成6位数字
func Version2int(ver *string) uint32 {
strs := strings.Split(*ver, ".")
var err error
var b, idx int
var result, str string
for idx, str = range strs {
b, err = strconv.Atoi(str)
if err == nil {
result += fmt.Sprintf("%02d", b)
}
}
b, _ = strconv.Atoi(result)
for ; idx < 2; idx++ {
b *= 100
}
return uint32(b)
}
func GetUserStateData() []*Config.ConfiguserState {
return g_tables.TbuserState.GetDataList()
}

View File

@ -0,0 +1,59 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
package Config
import "sandc/app/eonline/internal/config/bright/serialization"
type ByteBufLoader func(string) (*serialization.ByteBuf, error)
type Tables struct {
TbCoinAdReward *ConfigTbCoinAdReward
TbMinigame *ConfigTbMinigame
Tbglobal *ConfigTbglobal
TbCashOut *ConfigTbCashOut
TbuserState *ConfigTbuserState
}
func NewTables(loader ByteBufLoader) (*Tables, error) {
var err error
var buf *serialization.ByteBuf
tables := &Tables{}
if buf, err = loader("config_tbcoinadreward"); err != nil {
return nil, err
}
if tables.TbCoinAdReward, err = NewConfigTbCoinAdReward(buf); err != nil {
return nil, err
}
if buf, err = loader("config_tbminigame"); err != nil {
return nil, err
}
if tables.TbMinigame, err = NewConfigTbMinigame(buf); err != nil {
return nil, err
}
if buf, err = loader("config_tbglobal"); err != nil {
return nil, err
}
if tables.Tbglobal, err = NewConfigTbglobal(buf); err != nil {
return nil, err
}
if buf, err = loader("config_tbcashout"); err != nil {
return nil, err
}
if tables.TbCashOut, err = NewConfigTbCashOut(buf); err != nil {
return nil, err
}
if buf, err = loader("config_tbuserstate"); err != nil {
return nil, err
}
if tables.TbuserState, err = NewConfigTbuserState(buf); err != nil {
return nil, err
}
return tables, nil
}

View File

@ -0,0 +1,76 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
package Config
import (
"sandc/app/eonline/internal/config/bright/serialization"
)
import "errors"
type ConfigCashOut struct {
ID int32
Type int32
LimitTime int32
Price float32
PriceShow float32
}
const TypeId_ConfigCashOut = 1836307535
func (*ConfigCashOut) GetTypeId() int32 {
return 1836307535
}
func (_v *ConfigCashOut) Serialize(_buf *serialization.ByteBuf) {
// not support
}
func (_v *ConfigCashOut) Deserialize(_buf *serialization.ByteBuf) (err error) {
{
if _v.ID, err = _buf.ReadInt(); err != nil {
err = errors.New("_v.ID error")
return
}
}
{
if _v.Type, err = _buf.ReadInt(); err != nil {
err = errors.New("_v.Type error")
return
}
}
{
if _v.LimitTime, err = _buf.ReadInt(); err != nil {
err = errors.New("_v.LimitTime error")
return
}
}
{
if _v.Price, err = _buf.ReadFloat(); err != nil {
err = errors.New("_v.Price error")
return
}
}
{
if _v.PriceShow, err = _buf.ReadFloat(); err != nil {
err = errors.New("_v.PriceShow error")
return
}
}
return
}
func DeserializeConfigCashOut(_buf *serialization.ByteBuf) (*ConfigCashOut, error) {
v := &ConfigCashOut{}
if err := v.Deserialize(_buf); err == nil {
return v, nil
} else {
return nil, err
}
}

View File

@ -0,0 +1,76 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
package Config
import (
"sandc/app/eonline/internal/config/bright/serialization"
)
import "errors"
type ConfigCoinAdReward struct {
ID int32
Starttimes int32
Endtimes int32
SaveCoinMin int32
SaveCoinMax int32
}
const TypeId_ConfigCoinAdReward = -100324817
func (*ConfigCoinAdReward) GetTypeId() int32 {
return -100324817
}
func (_v *ConfigCoinAdReward) Serialize(_buf *serialization.ByteBuf) {
// not support
}
func (_v *ConfigCoinAdReward) Deserialize(_buf *serialization.ByteBuf) (err error) {
{
if _v.ID, err = _buf.ReadInt(); err != nil {
err = errors.New("_v.ID error")
return
}
}
{
if _v.Starttimes, err = _buf.ReadInt(); err != nil {
err = errors.New("_v.Starttimes error")
return
}
}
{
if _v.Endtimes, err = _buf.ReadInt(); err != nil {
err = errors.New("_v.Endtimes error")
return
}
}
{
if _v.SaveCoinMin, err = _buf.ReadInt(); err != nil {
err = errors.New("_v.SaveCoinMin error")
return
}
}
{
if _v.SaveCoinMax, err = _buf.ReadInt(); err != nil {
err = errors.New("_v.SaveCoinMax error")
return
}
}
return
}
func DeserializeConfigCoinAdReward(_buf *serialization.ByteBuf) (*ConfigCoinAdReward, error) {
v := &ConfigCoinAdReward{}
if err := v.Deserialize(_buf); err == nil {
return v, nil
} else {
return nil, err
}
}

View File

@ -0,0 +1,90 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
package Config
import (
"sandc/app/eonline/internal/config/bright/serialization"
)
import "errors"
type ConfigMinigame struct {
ID int32
Type int32
Level int32
SaveCoinMin int32
SaveCoinMax int32
Double int32
Weights int32
}
const TypeId_ConfigMinigame = -292238827
func (*ConfigMinigame) GetTypeId() int32 {
return -292238827
}
func (_v *ConfigMinigame) Serialize(_buf *serialization.ByteBuf) {
// not support
}
func (_v *ConfigMinigame) Deserialize(_buf *serialization.ByteBuf) (err error) {
{
if _v.ID, err = _buf.ReadInt(); err != nil {
err = errors.New("_v.ID error")
return
}
}
{
if _v.Type, err = _buf.ReadInt(); err != nil {
err = errors.New("_v.Type error")
return
}
}
{
if _v.Level, err = _buf.ReadInt(); err != nil {
err = errors.New("_v.Level error")
return
}
}
{
if _v.SaveCoinMin, err = _buf.ReadInt(); err != nil {
err = errors.New("_v.SaveCoinMin error")
return
}
}
{
if _v.SaveCoinMax, err = _buf.ReadInt(); err != nil {
err = errors.New("_v.SaveCoinMax error")
return
}
}
{
if _v.Double, err = _buf.ReadInt(); err != nil {
err = errors.New("_v.Double error")
return
}
}
{
if _v.Weights, err = _buf.ReadInt(); err != nil {
err = errors.New("_v.Weights error")
return
}
}
return
}
func DeserializeConfigMinigame(_buf *serialization.ByteBuf) (*ConfigMinigame, error) {
v := &ConfigMinigame{}
if err := v.Deserialize(_buf); err == nil {
return v, nil
} else {
return nil, err
}
}

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