feat: 积分质押功能

This commit is contained in:
2025-04-03 16:17:20 +08:00
parent 229f1d181b
commit 8119bcefdc
40 changed files with 2552 additions and 108 deletions

View File

@@ -1,6 +1,6 @@
host ?= 192.168.2.108:3306
user ?= huangjie
pwd ?= jMDqPQM^a6hsAR
host ?= 192.168.2.184:3306
user ?= root
pwd ?= SLsl>2017409
table ?=
cache ?=
database ?= "nova_home"

View File

@@ -29,6 +29,10 @@ service novatask {
@doc "根据地址修复质押"
@handler StakeByAddress
post /stake_by_address (StakeByAddressReq)
@doc "GameAction"
@handler GameAction
post /game_action (GameActionReq) returns (GameActionResp)
}
type EmailReward {
@@ -46,3 +50,14 @@ type StakeByAddressReq {
Address []string `json:"address"`
}
type GameActionReq {
RoleId int64 `json:"role_id"`
Action string `json:"action"`
}
type GameActionResp {
Ret int `json:"ret"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}

View File

@@ -5,6 +5,7 @@ import "carv.api"
import "admin.api"
import "game7.api"
import "kgen.api"
import "stakepoint.api"
info (
desc: "nova api"

55
doc/api/stakepoint.api Normal file
View File

@@ -0,0 +1,55 @@
syntax = "v1"
@server (
prefix: /gapi/stakepoint/v1
jwt: Auth
group: stakepoint
)
service novatask {
@doc "获取质押档位列表"
@handler GetStakeLevelList
get /level (GetStakeLevelListReq) returns (GetStakeLevelListResp)
@doc "质押积分操作"
@handler StakePoint
post /stake (StakePointReq)
}
type GetStakeLevelListReq {
RoleID int64 `form:"role_id"` // 角色id
}
type PointStakeLevel {
Id int `json:"id"` // 档位id
Title string `json:"title"` // 档位标题
Level int `json:"level"` // 精灵等级
Points int `json:"points"` // 积分数量
Days float64 `json:"days"` // 质押天数
RenewDays float64 `json:"renew_days"` // 续期天数
}
type StakeLevel {
Id int `json:"id"`
Title string `json:"title"` // 档位标题
Level int `json:"level"` // 精灵等级
Points int `json:"points"` // 积分数量
Days float64 `json:"days"` // 质押天数
RenewDays float64 `json:"renew_days"` // 续期天数
StartTime string `json:"start_time"` // 开始时间
EndTime string `json:"end_time"` // 结束时间
CanRenew bool `json:"can_renew"` // 是否可续约
}
type GetStakeLevelListResp {
State int `json:"state"` // 状态1表示已开启可质押 0表示不可质押
Staking *StakeLevel `json:"staking,optional"` // 质押中的档位信息
RenewLevel *StakeLevel `json:"renew_level,optional"` // 已续约的档位信息
Levels []PointStakeLevel `json:"levels"` // 档位列表
}
type StakePointReq {
RoleID int64 `json:"role_id"` // 角色id
LevelId int `json:"level_id"` // 档位id
Action int `json:"action"` // 操作类型1表示质押2表示升级质押 3表示续约
}

View File

@@ -4,9 +4,9 @@ CREATE TABLE `nh_task_progress`
`uid` int(11) unsigned NOT NULL,
`task_id` int(11) unsigned NOT NULL COMMENT '任务id',
`task_seq` int(11) NOT NULL COMMENT '用于可重复任务的序列号',
`stage` tinyint NOT NULL DEFAULT 0 COMMENT '任务的阶段, 0:未完成 1:待校验 2:已完成未领取 3:已领取',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`stage` tinyint NOT NULL DEFAULT 0 COMMENT '任务的阶段, 0:未完成 1:待校验 2:已完成未领取 3:已领取',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uid_task_id_seq` (`uid`, `task_id`, `task_seq`)
) COMMENT ='用户任务节点';
@@ -14,12 +14,12 @@ CREATE TABLE `nh_task_progress`
CREATE TABLE `nh_nft_holder`
(
`id` int unsigned NOT NULL AUTO_INCREMENT,
`address` varchar(80) NOT NULL COMMENT '钱包地址',
`token_id` varchar(32) NOT NULL COMMENT 'token id',
`address` varchar(80) NOT NULL COMMENT '钱包地址',
`token_id` varchar(32) NOT NULL COMMENT 'token id',
`balance` int(11) NOT NULL DEFAULT 0 COMMENT '余额',
`update_seq` int NOT NULL COMMENT '更新序列号',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`update_seq` int NOT NULL COMMENT '更新序列号',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY (`token_id`),
INDEX (`update_seq`)
@@ -28,12 +28,12 @@ CREATE TABLE `nh_nft_holder`
CREATE TABLE `nh_nft_holder_change_log`
(
`id` int unsigned NOT NULL AUTO_INCREMENT,
`address` varchar(80) NOT NULL COMMENT '钱包地址',
`token_id` varchar(32) NOT NULL COMMENT 'token id',
`address` varchar(80) NOT NULL COMMENT '钱包地址',
`token_id` varchar(32) NOT NULL COMMENT 'token id',
`value` int(11) NOT NULL COMMENT '变化数量',
`balance` int(11) NOT NULL COMMENT '余额',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`)
) COMMENT ='nft 持有表变化日志';
@@ -42,11 +42,11 @@ CREATE TABLE `nh_task_nft_stake`
`id` int unsigned NOT NULL AUTO_INCREMENT,
`uid` int unsigned NOT NULL COMMENT '用户钱包',
`role_id` bigint unsigned NOT NULL COMMENT '角色id',
`token_id` varchar(32) NOT NULL COMMENT 'token id',
`token_id` varchar(32) NOT NULL COMMENT 'token id',
`type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '类型0=小塔罗1=大塔罗',
`state` tinyint NOT NULL DEFAULT 0 COMMENT '状态1质押中 0已取消质押',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`state` tinyint NOT NULL DEFAULT 0 COMMENT '状态1质押中 0已取消质押',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY (`token_id`)
) COMMENT ='nft质押表';
@@ -56,16 +56,16 @@ CREATE TABLE `nh_task_nft_stake_log`
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`uid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '用户钱包',
`role_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '角色id',
`token_id` varchar(32) NOT NULL COMMENT 'token id',
`token_id` varchar(32) NOT NULL COMMENT 'token id',
`operate` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态1质押 2取消质押, 3转出',
`callback_status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '下发通知状态:0未通知,1已通知,2通知异常',
`callback_num` int(10) NOT NULL DEFAULT '0' COMMENT '发送通知次数',
`callback_at` timestamp NULL DEFAULT NULL COMMENT '发送通知最新时间',
`callback_remark` varchar(255) NOT NULL DEFAULT '' COMMENT '通知回调备注',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`callback_at` timestamp NULL DEFAULT NULL COMMENT '发送通知最新时间',
`callback_remark` varchar(255) NOT NULL DEFAULT '' COMMENT '通知回调备注',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
KEY `callback_status` (`callback_status`) USING BTREE
KEY `callback_status` (`callback_status`) USING BTREE
) COMMENT ='nft质押日志表';
CREATE TABLE `nh_task_nft_stake_reward`
@@ -101,9 +101,24 @@ CREATE TABLE `nh_email_reward`
CREATE TABLE `nh_nft_tarot`
(
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`token_id` varchar(32) NOT NULL COMMENT 'token id',
`tarot_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '类型0=小塔罗1=大塔罗',
`tarot_img` varchar(128) NOT NULL COMMENT '塔罗图片',
`token_id` varchar(32) NOT NULL COMMENT 'token id',
`tarot_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '类型0=小塔罗1=大塔罗',
`tarot_img` varchar(128) NOT NULL COMMENT '塔罗图片',
PRIMARY KEY (`id`),
UNIQUE KEY (`token_id`)
) COMMENT ='塔罗信息';
) COMMENT ='塔罗信息';
CREATE TABLE `nh_stake_points`
(
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`uid` int unsigned NOT NULL COMMENT '用户id',
`role_id` bigint unsigned NOT NULL COMMENT '角色id',
`level_id` int(11) unsigned NOT NULL COMMENT '档位id',
`level` int unsigned NOT NULL COMMENT '档位',
`points` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '积分数量',
`start_time` timestamp NOT NULL COMMENT '开始时间戳',
`end_time` timestamp NOT NULL COMMENT '结束时间戳',
`status` tinyint(1) NOT NULL DEFAULT 0 COMMENT '状态1=质押中2=已升级3=已续约4=已过期',
PRIMARY KEY (`id`),
INDEX (`uid`, `role_id`, `level_id`, `status`)
) COMMENT ='积分质押表';

View File

@@ -69,6 +69,33 @@
]
}
},
"/gapi/admin/game_action": {
"post": {
"summary": "GameAction",
"operationId": "GameAction",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/GameActionResp"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/GameActionReq"
}
}
],
"tags": [
"admin"
]
}
},
"/gapi/admin/nft_holder_update": {
"get": {
"summary": "NFT持有者更新",
@@ -437,6 +464,71 @@
]
}
},
"/gapi/stakepoint/v1/level": {
"get": {
"summary": "获取质押档位列表",
"operationId": "GetStakeLevelList",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/GetStakeLevelListResp"
}
}
},
"parameters": [
{
"name": "role_id",
"description": " 角色id",
"in": "query",
"required": true,
"type": "integer",
"format": "int64"
}
],
"tags": [
"stakepoint"
],
"consumes": [
"multipart/form-data"
],
"security": [
{
"apiKey": []
}
]
}
},
"/gapi/stakepoint/v1/stake": {
"post": {
"summary": "质押积分操作",
"operationId": "StakePoint",
"responses": {
"200": {
"description": "A successful response.",
"schema": {}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/StakePointReq"
}
}
],
"tags": [
"stakepoint"
],
"security": [
{
"apiKey": []
}
]
}
},
"/gapi/task/v1/bind_tribally": {
"get": {
"summary": "绑定Tribally账号",
@@ -946,6 +1038,44 @@
"type"
]
},
"GameActionReq": {
"type": "object",
"properties": {
"role_id": {
"type": "integer",
"format": "int64"
},
"action": {
"type": "string"
}
},
"title": "GameActionReq",
"required": [
"role_id",
"action"
]
},
"GameActionResp": {
"type": "object",
"properties": {
"ret": {
"type": "integer",
"format": "int32"
},
"msg": {
"type": "string"
},
"data": {
"type": "object"
}
},
"title": "GameActionResp",
"required": [
"ret",
"msg",
"data"
]
},
"GetCommunityListResp": {
"type": "object",
"properties": {
@@ -974,6 +1104,50 @@
"wallet_address"
]
},
"GetStakeLevelListReq": {
"type": "object",
"properties": {
"role_id": {
"type": "integer",
"format": "int64",
"description": " 角色id"
}
},
"title": "GetStakeLevelListReq",
"required": [
"role_id"
]
},
"GetStakeLevelListResp": {
"type": "object",
"properties": {
"state": {
"type": "integer",
"format": "int32",
"description": " 状态1表示已开启可质押 0表示不可质押"
},
"staking": {
"$ref": "#/definitions/StakeLevel",
"description": " 质押中的档位信息"
},
"renew_level": {
"$ref": "#/definitions/StakeLevel",
"description": " 已续约的档位信息"
},
"levels": {
"type": "array",
"items": {
"$ref": "#/definitions/PointStakeLevel"
},
"description": " 档位列表"
}
},
"title": "GetStakeLevelListResp",
"required": [
"state",
"levels"
]
},
"GetTaskListReq": {
"type": "object",
"properties": {
@@ -1141,6 +1315,49 @@
"total"
]
},
"PointStakeLevel": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int32",
"description": " 档位id"
},
"title": {
"type": "string",
"description": " 档位标题"
},
"level": {
"type": "integer",
"format": "int32",
"description": " 精灵等级"
},
"points": {
"type": "integer",
"format": "int32",
"description": " 积分数量"
},
"days": {
"type": "number",
"format": "double",
"description": " 质押天数"
},
"renew_days": {
"type": "number",
"format": "double",
"description": " 续期天数"
}
},
"title": "PointStakeLevel",
"required": [
"id",
"title",
"level",
"points",
"days",
"renew_days"
]
},
"Result": {
"type": "object",
"properties": {
@@ -1169,6 +1386,64 @@
"address"
]
},
"StakeLevel": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int32"
},
"title": {
"type": "string",
"description": " 档位标题"
},
"level": {
"type": "integer",
"format": "int32",
"description": " 精灵等级"
},
"points": {
"type": "integer",
"format": "int32",
"description": " 积分数量"
},
"days": {
"type": "number",
"format": "double",
"description": " 质押天数"
},
"renew_days": {
"type": "number",
"format": "double",
"description": " 续期天数"
},
"start_time": {
"type": "string",
"description": " 开始时间"
},
"end_time": {
"type": "string",
"description": " 结束时间"
},
"can_renew": {
"type": "boolean",
"format": "boolean",
"description": " 是否可续约"
}
},
"title": "StakeLevel",
"required": [
"id",
"title",
"level",
"points",
"days",
"renew_days",
"start_time",
"end_time",
"can_renew"
]
},
"StakeNftList": {
"type": "object",
"properties": {
@@ -1190,6 +1465,32 @@
"token_ids"
]
},
"StakePointReq": {
"type": "object",
"properties": {
"role_id": {
"type": "integer",
"format": "int64",
"description": " 角色id"
},
"level_id": {
"type": "integer",
"format": "int32",
"description": " 档位id"
},
"action": {
"type": "integer",
"format": "int32",
"description": " 操作类型1表示质押2表示升级质押 3表示续约"
}
},
"title": "StakePointReq",
"required": [
"role_id",
"level_id",
"action"
]
},
"StakeReward": {
"type": "object",
"properties": {

View File

@@ -19,9 +19,9 @@ Auth: # js-sdk鉴权相关配置
AccessSecret: "Mj2G%szYe&$MP@ytNv8JktQN1n5^cPq%" # 鉴权token密钥
MySql: # mysql相关配置
Addr: "192.168.2.108:3306" # mysql地址
User: "huangjie" # mysql用户
Password: "jMDqPQM^a6hsAR" # mysql密码
Addr: "192.168.2.184:3306" # mysql地址
User: "root" # mysql用户
Password: "SLsl>2017409" # mysql密码
Database: "nova_home" # 数据库名
#MySql: # mysql相关配置
@@ -30,6 +30,12 @@ MySql: # mysql相关配置
# Password: "123456" # mysql密码
# Database: "nova_home" # 数据库名
GameDB: # mysql相关配置
Addr: "192.168.2.184:3306" # mysql地址
User: "root" # mysql用户
Password: "SLsl>2017409" # mysql密码
Database: "novadata" # 数据库名
Redis:
Host: "127.0.0.1:6379"

11
go.mod
View File

@@ -4,6 +4,7 @@ go 1.24
require (
github.com/aptos-labs/aptos-go-sdk v1.4.1
github.com/block-vision/sui-go-sdk v1.0.6
github.com/earn-alliance/earnalliance-go v0.0.2
github.com/go-sql-driver/mysql v1.8.1
github.com/golang-jwt/jwt/v4 v4.5.1
@@ -26,15 +27,21 @@ require (
github.com/fatih/color v1.18.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.12.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
github.com/hasura/go-graphql-client v0.12.1 // indirect
github.com/hdevalence/ed25519consensus v0.2.0 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/leodido/go-urn v1.2.2 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/openzipkin/zipkin-go v0.4.3 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
@@ -45,6 +52,9 @@ require (
github.com/prometheus/procfs v0.15.1 // indirect
github.com/redis/go-redis/v9 v9.7.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/tidwall/gjson v1.14.4 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect
@@ -61,6 +71,7 @@ require (
golang.org/x/net v0.31.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/text v0.20.0 // indirect
golang.org/x/time v0.8.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
google.golang.org/grpc v1.65.0 // indirect

26
go.sum
View File

@@ -10,6 +10,8 @@ github.com/aptos-labs/aptos-go-sdk v1.4.1 h1:foBM3FCLpxtjIO8hfmHHs3VcP5QY/sdAteN
github.com/aptos-labs/aptos-go-sdk v1.4.1/go.mod h1:Ohl8Rq8mAGIbmzLll7nLAR+aPUdtzW8RtmyE0IDFib8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/block-vision/sui-go-sdk v1.0.6 h1:FysCc4TJC8v4BEBbCjJPDR4iR5eKqJT1dxGwsT67etg=
github.com/block-vision/sui-go-sdk v1.0.6/go.mod h1:FyK1vGE8lWm9QA1fdQpf1agfXQSMbPT8AV1BICgx6d8=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
@@ -45,6 +47,14 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.12.0 h1:E4gtWgxWxp8YSxExrQFv5BpCahla0PVF2oTTEYaWQGI=
github.com/go-playground/validator/v10 v10.12.0/go.mod h1:hCAPuzYvKdP33pxWa+2+6AIKXEKqjIUyqsNCtbsSJrA=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI=
@@ -55,6 +65,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
@@ -83,11 +95,15 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/leodido/go-urn v1.2.2 h1:7z68G0FCGvDk646jz1AelTYNYWrTNm0bEcFAo147wt4=
github.com/leodido/go-urn v1.2.2/go.mod h1:kUaIbLZWttglzwNuG0pgsh5vuV6u2YcGBYz1hIPjtOQ=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg=
@@ -115,6 +131,7 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rwtodd/Go.Sed v0.0.0-20210816025313-55464686f9ef/go.mod h1:8AEUvGVi2uQ5b24BIhcr0GCcpd/RNAFWaN2CJFrWIIQ=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
@@ -131,9 +148,16 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
github.com/zeromicro/go-zero v1.7.4 h1:lyIUsqbpVRzM4NmXu5pRM3XrdRdUuWOkQmHiNmJF0VU=
@@ -174,6 +198,8 @@ golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY=
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=

View File

@@ -13,10 +13,11 @@ import (
type Config struct {
rest.RestConf
MySql MySqlConf
Redis redis.RedisConf
Cache cache.CacheConf
Auth struct {
MySql MySqlConf
GameDB MySqlConf
Redis redis.RedisConf
Cache cache.CacheConf
Auth struct {
AccessSecret string
AccessExpire time.Duration `json:",default=168h"`
}
@@ -34,6 +35,7 @@ type Config struct {
PrivateKey string
IsTest bool `json:",default=false"`
} `json:",optional"`
NovaToken string `json:",default=JInj73uK5gK5BG7I53h5PaEJH41tWwBT"`
}
type Cron struct {

View File

@@ -0,0 +1,6 @@
package consts
const (
GameActionGetHomePointsState = "getStakeHomePointsState"
GameActionStakePoints = "stakeHomePoints"
)

View File

@@ -0,0 +1,30 @@
package admin
import (
"net/http"
"nova_task/internal/pkg/errs"
"github.com/zeromicro/go-zero/rest/httpx"
"nova_task/internal/logic/admin"
"nova_task/internal/svc"
"nova_task/internal/types"
)
// GameAction
func GameActionHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.GameActionReq
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := admin.NewGameActionLogic(r.Context(), svcCtx)
resp, err := l.GameAction(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
errs.WriteHttpResponse(r.Context(), w, resp)
}
}
}

View File

@@ -10,6 +10,7 @@ import (
carv "nova_task/internal/handler/carv"
game7 "nova_task/internal/handler/game7"
kgen "nova_task/internal/handler/kgen"
stakepoint "nova_task/internal/handler/stakepoint"
task "nova_task/internal/handler/task"
"nova_task/internal/svc"
@@ -39,6 +40,12 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
Path: "/fix_nft_staker",
Handler: admin.FixNftStakerHandler(serverCtx),
},
{
// GameAction
Method: http.MethodPost,
Path: "/game_action",
Handler: admin.GameActionHandler(serverCtx),
},
{
// NFT持有者更新
Method: http.MethodGet,
@@ -125,6 +132,25 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
rest.WithPrefix("/gapi/kgen"),
)
server.AddRoutes(
[]rest.Route{
{
// 获取质押档位列表
Method: http.MethodGet,
Path: "/level",
Handler: stakepoint.GetStakeLevelListHandler(serverCtx),
},
{
// 质押积分操作
Method: http.MethodPost,
Path: "/stake",
Handler: stakepoint.StakePointHandler(serverCtx),
},
},
rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
rest.WithPrefix("/gapi/stakepoint/v1"),
)
server.AddRoutes(
[]rest.Route{
{

View File

@@ -0,0 +1,29 @@
package stakepoint
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"nova_task/internal/logic/stakepoint"
"nova_task/internal/svc"
"nova_task/internal/types"
)
// 获取质押档位列表
func GetStakeLevelListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.GetStakeLevelListReq
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := stakepoint.NewGetStakeLevelListLogic(r.Context(), svcCtx)
resp, err := l.GetStakeLevelList(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}

View File

@@ -0,0 +1,29 @@
package stakepoint
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"nova_task/internal/logic/stakepoint"
"nova_task/internal/svc"
"nova_task/internal/types"
)
// 质押积分操作
func StakePointHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.StakePointReq
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := stakepoint.NewStakePointLogic(r.Context(), svcCtx)
err := l.StakePoint(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.Ok(w)
}
}
}

View File

@@ -0,0 +1,69 @@
package check_points_stake
import (
"context"
"github.com/robfig/cron/v3"
"github.com/shopspring/decimal"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"nova_task/internal/consts"
"nova_task/internal/pkg/errs"
"nova_task/internal/svc"
"time"
)
type Cron struct {
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewCron(ctx context.Context, svcCtx *svc.ServiceContext) cron.Job {
return &Cron{
ctx: ctx,
svcCtx: svcCtx,
}
}
func (c *Cron) Spec() string {
return "@every 30s"
}
func (c *Cron) Run() {
ns, err := c.svcCtx.StakePointsModel.FindOverdueList(c.ctx)
if err != nil {
logx.Errorw("find overdue list failed", logx.Field("err", err))
return
}
if len(ns) == 0 {
return
}
logx.Debugw("find overdue list", logx.Field("count", len(ns)))
for _, n := range ns {
err = c.svcCtx.DBConn.TransactCtx(c.ctx, func(ctx context.Context, session sqlx.Session) error {
err = c.svcCtx.StakePointsModel.WithSession(session).SetOverdue(ctx, n.Id)
if err != nil {
logx.Errorw("set overdue failed", logx.Field("err", err))
return err
}
err = c.svcCtx.AddUserAssetWithSession(c.ctx, session, n.Uid, int64(n.RoleId), consts.AssetType_Points, "", decimal.NewFromInt(int64(n.Points)), "stake point overdue return", 0, 0, false)
if err != nil {
return err
}
_, err = c.svcCtx.GameAction(c.ctx, int64(n.RoleId), consts.GameActionStakePoints, map[string]any{
"level": n.Level,
"operation": 4,
"start_time": time.Now().Unix(),
"end_time": 0,
"renew_times": 0,
})
if err != nil {
logx.Errorw("game action failed", logx.Field("err", err), logx.Field("uid", n.Uid), logx.Field("roleId", n.RoleId))
return errs.New(errs.ErrInternalServer, err)
}
return nil
})
if err != nil {
logx.Errorw("SetOverdue points stake", logx.Field("err", err), logx.Field("uid", n.Uid), logx.Field("roleId", n.RoleId))
}
}
}

View File

@@ -5,6 +5,7 @@ import (
"errors"
"github.com/robfig/cron/v3"
"github.com/zeromicro/go-zero/core/logx"
"nova_task/internal/job/check_points_stake"
"nova_task/internal/job/earn"
"nova_task/internal/job/holder"
"nova_task/internal/job/stake_settle"
@@ -16,6 +17,8 @@ var cronList = []func(context.Context, *svc.ServiceContext) cron.Job{
earn.NewCron,
holder.NewCron,
stake_settle.NewCron,
//game_notify.NewCron,
check_points_stake.NewCron,
}
type Corns struct {

View File

@@ -0,0 +1,81 @@
package game_notify
import (
"context"
"encoding/json"
"github.com/robfig/cron/v3"
"github.com/zeromicro/go-zero/core/logx"
"nova_task/internal/model"
"nova_task/internal/svc"
)
type Cron struct {
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewCron(ctx context.Context, svcCtx *svc.ServiceContext) cron.Job {
return &Cron{
ctx: ctx,
svcCtx: svcCtx,
}
}
func (c *Cron) Spec() string {
return "@every 30s"
}
func (c *Cron) Run() {
c.Process(model.NTF_STATUS_WAITING_PROCESS)
c.Process(model.NTF_STATUS_FAILED)
}
func (c *Cron) Process(status int8) {
nfs, err := c.svcCtx.GameServerNotifyModel.FindNotifyList(c.ctx, status)
if err != nil {
logx.Errorw("find notify list failed", logx.Field("err", err))
return
}
if len(nfs) == 0 {
logx.Debug("no notify")
return
}
for _, nf := range nfs {
var arg = map[string]any{}
if nf.Data.Valid {
err = json.Unmarshal([]byte(nf.Data.String), &arg)
if err != nil {
logx.Errorw("unmarshal notify data failed", logx.Field("err", err), logx.Field("id", nf.Id))
continue
}
}
err := c.svcCtx.GameServerNotifyModel.UpdateNotifyStatus(c.ctx, nf.Id, model.NTF_STATUS_PROCESSING)
if err != nil {
logx.Errorw("update notify status failed", logx.Field("err", err), logx.Field("id", nf.Id))
continue
}
_, err = c.svcCtx.GameAction(c.ctx, int64(nf.RoleId), nf.Action, arg)
if err != nil {
c.svcCtx.GameServerNotifyModel.UpdateNotifyStatus(c.ctx, nf.Id, model.NTF_STATUS_FAILED)
} else {
c.svcCtx.GameServerNotifyModel.UpdateNotifyStatus(c.ctx, nf.Id, model.NTF_STATUS_SUCCESS)
}
}
}
/*
CREATE TABLE `nh_game_server_notify`
(
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`role_id` bigint(20) unsigned NOT NULL COMMENT '角色id',
`action` varchar(128) NOT NULL COMMENT '事件类型',
`data` text NULL DEFAULT NULL COMMENT '事件数据',
`status` tinyint NOT NULL DEFAULT 0 COMMENT '状态1=待处理2=处理中, 3=处理失败, 4=处理成功',
`retry_times` int NOT NULL DEFAULT 0 COMMENT '重试次数',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
INDEX (`status`)
) COMMENT ='游戏服通知事件';
*/

View File

@@ -0,0 +1,27 @@
package admin
import (
"context"
"nova_task/internal/svc"
"nova_task/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GameActionLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGameActionLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GameActionLogic {
return &GameActionLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GameActionLogic) GameAction(req *types.GameActionReq) (any, error) {
return l.svcCtx.GameAction(l.ctx, req.RoleId, req.Action, nil)
}

View File

@@ -0,0 +1,147 @@
package stakepoint
import (
"context"
"errors"
"github.com/shopspring/decimal"
"github.com/spf13/cast"
"nova_task/internal/consts"
"nova_task/internal/model"
"nova_task/internal/pkg/errs"
"time"
"nova_task/internal/svc"
"nova_task/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetStakeLevelListLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetStakeLevelListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetStakeLevelListLogic {
return &GetStakeLevelListLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetStakeLevelListLogic) GetStakeLevelList(req *types.GetStakeLevelListReq) (*types.GetStakeLevelListResp, error) {
resp, err := l.svcCtx.GameAction(l.ctx, req.RoleID, consts.GameActionGetHomePointsState, nil)
if err != nil {
l.Errorw("GetStakeLevelList", logx.Field("err", err))
return nil, errs.New(errs.GameServerError, err)
}
if !cast.ToBool(resp.(map[string]any)["data"]) {
l.Debugw("getStakeHomePointsState", logx.Field("role", req.RoleID), logx.Field("resp", resp))
return &types.GetStakeLevelListResp{
State: 0,
}, nil
}
lvs, err := l.svcCtx.StakePointConfigModel.All(l.ctx)
if err != nil {
l.Errorw("GetStakeLevelList", logx.Field("err", err))
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
var ls []types.PointStakeLevel
for _, lv := range lvs {
ls = append(ls, types.PointStakeLevel{
Id: int(lv.Id),
Title: lv.Title,
Level: int(lv.Level),
Points: int(lv.Points),
Days: lv.Days.InexactFloat64(),
RenewDays: lv.RenewDays.InexactFloat64(),
})
}
stake, err := l.svcCtx.StakePointsModel.FindCurrentLevel(l.ctx, req.RoleID)
if err != nil && !errors.Is(err, model.ErrNotFound) {
l.Errorw("GetStakeLevelList", logx.Field("err", err), logx.Field("role_id", req.RoleID))
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
var staking *types.StakeLevel
var hasRenew bool
if stake != nil {
var (
title string
level int
points int
days float64
renewDays float64
canRenew bool
)
for _, lv := range lvs {
if lv.Id == stake.LevelId {
title = lv.Title
level = int(lv.Level)
points = int(lv.Points)
days = lv.Days.InexactFloat64()
renewDays = lv.RenewDays.InexactFloat64()
canRenew = stake.EndTime.Sub(time.Now()) <= time.Duration(lv.RenewDays.Mul(decimal.NewFromInt(int64(time.Hour*24))).IntPart()) && stake.Status == model.PointsStakeStatusStaking
break
}
}
hasRenew = stake.Status == model.PointsStakeStatusRenew
staking = &types.StakeLevel{
Id: int(stake.LevelId),
Title: title,
Level: level,
Points: points,
Days: days,
RenewDays: renewDays,
StartTime: stake.StartTime.Format(time.DateTime),
EndTime: stake.EndTime.Format(time.DateTime),
CanRenew: canRenew,
}
}
var renewLevel *types.StakeLevel
if hasRenew {
stk, err := l.svcCtx.StakePointsModel.FindRenewLevel(l.ctx, req.RoleID)
if err != nil && !errors.Is(err, model.ErrNotFound) {
l.Errorw("GetStakeLevelList", logx.Field("err", err), logx.Field("role_id", req.RoleID))
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
if stk != nil {
var (
title string
level int
points int
days float64
renewDays float64
)
for _, lv := range lvs {
if lv.Id == stk.LevelId {
title = lv.Title
level = int(lv.Level)
points = int(lv.Points)
days = lv.Days.InexactFloat64()
renewDays = lv.RenewDays.InexactFloat64()
break
}
}
renewLevel = &types.StakeLevel{
Id: int(stk.LevelId),
Title: title,
Level: level,
Points: points,
Days: days,
RenewDays: renewDays,
StartTime: stk.StartTime.Format(time.DateTime),
EndTime: stk.EndTime.Format(time.DateTime),
CanRenew: false,
}
}
}
return &types.GetStakeLevelListResp{
State: 1,
Staking: staking,
RenewLevel: renewLevel,
Levels: ls,
}, nil
}

View File

@@ -0,0 +1,237 @@
package stakepoint
import (
"context"
"errors"
"github.com/shopspring/decimal"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"nova_task/internal/consts"
"nova_task/internal/model"
"nova_task/internal/pkg/errs"
"nova_task/internal/pkg/utils"
"time"
"nova_task/internal/svc"
"nova_task/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type StakePointLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
// 质押积分操作
func NewStakePointLogic(ctx context.Context, svcCtx *svc.ServiceContext) *StakePointLogic {
return &StakePointLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *StakePointLogic) StakePoint(req *types.StakePointReq) error {
uid := utils.GetUid(l.ctx)
r, err := l.svcCtx.RoleModel.FindOneByRoleId(l.ctx, req.RoleID)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return errs.New(errs.ErrRoleNotFound, "role not exist")
}
l.Errorw("find role error", logx.Field("err", err), logx.Field("role_id", req.RoleID), logx.Field("uid", uid), logx.Field("level_id", req.LevelId), logx.Field("action", req.Action))
return errs.New(errs.ErrDatabaseOperate, err)
}
u, err := l.svcCtx.UserModel.FindOneByEmail(l.ctx, r.Account)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return errs.New(errs.ErrUserNotFound, "user not found")
}
l.Errorw("find user error", logx.Field("err", err), logx.Field("role_id", req.RoleID), logx.Field("uid", uid), logx.Field("level_id", req.LevelId), logx.Field("action", req.Action))
return errs.New(errs.ErrDatabaseOperate, err)
}
if u.Id != uint(uid) {
return errs.New(errs.ErrRoleNotFound, "role not exist")
}
lv, err := l.svcCtx.StakePointConfigModel.FindOne(l.ctx, uint(req.LevelId))
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return errs.New(errs.ErrPointLevelConfigNotFound, "stake point level config not found")
}
return errs.New(errs.ErrDatabaseOperate, err)
}
clv, err := l.svcCtx.StakePointsModel.FindCurrentLevel(l.ctx, req.RoleID)
if err != nil && !errors.Is(err, model.ErrNotFound) {
l.Errorw("find current level error", logx.Field("err", err), logx.Field("role_id", req.RoleID), logx.Field("uid", uid), logx.Field("level_id", req.LevelId), logx.Field("action", req.Action))
return errs.New(errs.ErrDatabaseOperate, err)
}
start := time.Now()
end := start.Add(time.Duration(lv.Days.Mul(decimal.NewFromInt(int64(time.Hour * 24))).IntPart()))
switch req.Action {
case 1:
if err == nil {
return errs.New(errs.ErrPointsStakeExist, "stake points exist")
}
err = l.svcCtx.DBConn.TransactCtx(l.ctx, func(ctx context.Context, session sqlx.Session) error {
err = l.svcCtx.AddUserAssetWithSession(ctx, session, uint(uid), req.RoleID, consts.AssetType_Points, "", decimal.NewFromInt(int64(-lv.Points)), "stake points", 0, 0, false)
if err != nil {
return err
}
_, err = l.svcCtx.StakePointsModel.WithSession(session).Insert(l.ctx, &model.NhStakePoints{
Uid: uint(uid),
RoleId: uint64(req.RoleID),
LevelId: lv.Id,
Level: lv.Level,
Points: lv.Points,
StartTime: start,
EndTime: end,
Status: model.PointsStakeStatusStaking,
})
if err != nil {
return errs.New(errs.ErrDatabaseOperate, err)
}
_, err := l.svcCtx.GameAction(ctx, req.RoleID, consts.GameActionStakePoints, map[string]any{
"level": lv.Level,
"operation": req.Action,
"start_time": start.Unix(),
"end_time": end.Unix(),
"renew_times": 0,
})
return err
})
if err != nil {
l.Errorw("积分质押", logx.Field("err", err), logx.Field("role_id", req.RoleID), logx.Field("uid", uid), logx.Field("level_id", req.LevelId), logx.Field("action", req.Action))
return errs.New(errs.ErrInternalServer, err)
}
case 2:
if err != nil {
l.Errorw("用户在未质押的情况下进行升级", logx.Field("uid", uid), logx.Field("role_id", req.RoleID))
return errs.New(errs.ErrPointStakeNotExist, "stake points not exist")
}
clvConfig, err := l.svcCtx.StakePointConfigModel.FindOne(l.ctx, clv.LevelId)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return errs.New(errs.ErrPointLevelConfigNotFound, "current stake point level config not found")
}
return errs.New(errs.ErrDatabaseOperate, err)
}
if lv.Level <= clvConfig.Level {
return errs.New(errs.ErrPointsStakeLevelNotAllow, "Upgraded pledge credit bracket must be higher than current bracket")
}
// 已续约,不可升级
if clv.Status != model.PointsStakeStatusStaking {
return errs.New(errs.ErrPointsStakeHasRenew, "Current stake has renew")
}
err = l.svcCtx.DBConn.TransactCtx(l.ctx, func(ctx context.Context, session sqlx.Session) error {
points := lv.Points - clvConfig.Points
err = l.svcCtx.AddUserAssetWithSession(ctx, session, uint(uid), req.RoleID, consts.AssetType_Points, "", decimal.NewFromInt(int64(-points)), "stake points", 0, 0, false)
if err != nil {
return err
}
clv.Status = model.PointsStakeStatusUpgraded
clv.EndTime = start
spm := l.svcCtx.StakePointsModel.WithSession(session)
err := spm.Update(ctx, clv)
if err != nil {
return errs.New(errs.ErrDatabaseOperate, err)
}
end = start.Add(time.Duration(lv.Days.Mul(decimal.NewFromInt(int64(time.Hour*24))).IntPart()) - start.Sub(clv.StartTime))
_, err = spm.Insert(l.ctx, &model.NhStakePoints{
Uid: uint(uid),
RoleId: uint64(req.RoleID),
LevelId: lv.Id,
Level: lv.Level,
Points: lv.Points,
StartTime: start,
EndTime: end,
Status: model.PointsStakeStatusStaking,
})
if err != nil {
return errs.New(errs.ErrDatabaseOperate, err)
}
_, err = l.svcCtx.GameAction(ctx, req.RoleID, consts.GameActionStakePoints, map[string]any{
"level": lv.Level,
"operation": req.Action,
"start_time": start.Unix(),
"end_time": end.Unix(),
"renew_times": 0,
})
return err
})
if err != nil {
l.Errorw("积分质押升级失败", logx.Field("err", err), logx.Field("role_id", req.RoleID), logx.Field("uid", uid), logx.Field("level_id", req.LevelId), logx.Field("action", req.Action))
return errs.New(errs.ErrInternalServer, err)
}
case 3:
if err != nil {
l.Errorw("用户在未质押的情况下进行续约", logx.Field("uid", uid), logx.Field("role_id", req.RoleID))
return errs.New(errs.ErrPointStakeNotExist, "stake points not exist")
}
clvConfig, err := l.svcCtx.StakePointConfigModel.FindOne(l.ctx, clv.LevelId)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return errs.New(errs.ErrPointLevelConfigNotFound, "current stake point level config not found")
}
return errs.New(errs.ErrDatabaseOperate, err)
}
// 续约等级不能小于当前等级
if lv.Level < clvConfig.Level {
return errs.New(errs.ErrPointsStakeLevelNotAllow, "Renewal level cannot be lower than current level")
}
// 已续约,不可重复续约
if clv.Status != model.PointsStakeStatusStaking {
return errs.New(errs.ErrPointsStakeHasRenew, "Current stake has renew")
}
// 判断是否在可续约时间范围内
if clv.EndTime.Sub(time.Now()) > time.Duration(clvConfig.RenewDays.Mul(decimal.NewFromInt(int64(time.Hour*24))).IntPart()) {
return errs.New(errs.ErrPointsStakeNotInRenewTime, "Not within the renewal time frame")
}
// 判断是否属于续约期内
err = l.svcCtx.DBConn.TransactCtx(l.ctx, func(ctx context.Context, session sqlx.Session) error {
points := lv.Points - clvConfig.Points
if points > 0 {
err = l.svcCtx.AddUserAssetWithSession(ctx, session, uint(uid), req.RoleID, consts.AssetType_Points, "", decimal.NewFromInt(int64(-points)), "stake points", 0, 0, false)
if err != nil {
return err
}
}
clv.Status = model.PointsStakeStatusRenew
spm := l.svcCtx.StakePointsModel.WithSession(session)
err := spm.Update(ctx, clv)
if err != nil {
return errs.New(errs.ErrDatabaseOperate, err)
}
end = clv.EndTime.Add(time.Duration(lv.Days.Mul(decimal.NewFromInt(int64(time.Hour * 24))).IntPart()))
_, err = spm.Insert(l.ctx, &model.NhStakePoints{
Uid: uint(uid),
RoleId: uint64(req.RoleID),
LevelId: lv.Id,
Level: lv.Level,
Points: lv.Points,
StartTime: clv.EndTime,
EndTime: end,
Status: model.PointsStakeStatusStaking,
})
if err != nil {
return errs.New(errs.ErrDatabaseOperate, err)
}
_, err = l.svcCtx.GameAction(ctx, req.RoleID, consts.GameActionStakePoints, map[string]any{
"level": lv.Level,
"operation": req.Action,
"start_time": start.Unix(),
"end_time": end.Unix(),
"renew_times": 0,
})
return err
})
if err != nil {
l.Errorw("积分质押续期失败", logx.Field("err", err), logx.Field("role_id", req.RoleID), logx.Field("uid", uid), logx.Field("level_id", req.LevelId), logx.Field("action", req.Action))
return errs.New(errs.ErrInternalServer, err)
}
default:
return errs.New(errs.ErrInvalidParam, "Invalid action")
}
return errs.Success()
}

View File

@@ -0,0 +1,57 @@
package model
import (
"context"
"errors"
"fmt"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
var _ MgServersModel = (*customMgServersModel)(nil)
type (
// MgServersModel is an interface to be customized, add more methods here,
// and implement the added methods in customMgServersModel.
MgServersModel interface {
mgServersModel
withSession(session sqlx.Session) MgServersModel
GetGameServer(ctx context.Context, agentId, serverId int64) (*GameServer, error)
}
customMgServersModel struct {
*defaultMgServersModel
}
GameServer struct {
AgentID int `db:"agent_id"` // 代理ID
ServerID int `db:"server_id"` // 服务器ID
WebPort int `db:"web_port"` // web访问端口
ServerIP string `db:"server_ip"` // 内网IP
PublicServerIP string `db:"public_server_ip"` // 公网IP
}
)
func (m *customMgServersModel) GetGameServer(ctx context.Context, agentId, serverId int64) (*GameServer, error) {
query := fmt.Sprintf("SELECT g.agent_id, g.server_id, g.web_port, s.ip AS server_ip, s.public_ip AS public_server_ip FROM ms_game_server AS g LEFT JOIN mg_servers AS s ON s.id = g.server_server_id WHERE g.server_id = ? AND g.agent_id = ?")
var result GameServer
err := m.conn.QueryRowCtx(ctx, &result, query, serverId, agentId)
switch {
case err == nil:
return &result, nil
case errors.Is(err, sqlx.ErrNotFound):
return nil, ErrNotFound
default:
return nil, err
}
}
// NewMgServersModel returns a model for the database table.
func NewMgServersModel(conn sqlx.SqlConn) MgServersModel {
return &customMgServersModel{
defaultMgServersModel: newMgServersModel(conn),
}
}
func (m *customMgServersModel) withSession(session sqlx.Session) MgServersModel {
return NewMgServersModel(sqlx.NewSqlConnFromSession(session))
}

View File

@@ -0,0 +1,92 @@
// Code generated by goctl. DO NOT EDIT.
// versions:
// goctl version: 1.7.6
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
mgServersFieldNames = builder.RawFieldNames(&MgServers{})
mgServersRows = strings.Join(mgServersFieldNames, ",")
mgServersRowsExpectAutoSet = strings.Join(stringx.Remove(mgServersFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
mgServersRowsWithPlaceHolder = strings.Join(stringx.Remove(mgServersFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
)
type (
mgServersModel interface {
Insert(ctx context.Context, data *MgServers) (sql.Result, error)
FindOne(ctx context.Context, id int) (*MgServers, error)
Update(ctx context.Context, data *MgServers) error
Delete(ctx context.Context, id int) error
}
defaultMgServersModel struct {
conn sqlx.SqlConn
table string
}
MgServers struct {
Id int `db:"id"`
RegionId int `db:"region_id"` // 区域ID
Ip sql.NullString `db:"ip"` // 内网IP
PublicIp sql.NullString `db:"public_ip"` // 公网IP
Domain sql.NullString `db:"domain"` // 域名
ServerCategory sql.NullInt64 `db:"server_category"` // 服务器分类 1:游戏节点服, 2:游戏业务数据库服, 3:游戏日志数据库服,
ServerType sql.NullInt64 `db:"server_type"` // 服务器类型 1:本地开发;3:Android服;4:iOS服;
AdminId sql.NullInt64 `db:"admin_id"`
AddTime sql.NullTime `db:"add_time"`
}
)
func newMgServersModel(conn sqlx.SqlConn) *defaultMgServersModel {
return &defaultMgServersModel{
conn: conn,
table: "`mg_servers`",
}
}
func (m *defaultMgServersModel) Delete(ctx context.Context, id int) error {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, id)
return err
}
func (m *defaultMgServersModel) FindOne(ctx context.Context, id int) (*MgServers, error) {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", mgServersRows, m.table)
var resp MgServers
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultMgServersModel) Insert(ctx context.Context, data *MgServers) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?)", m.table, mgServersRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.RegionId, data.Ip, data.PublicIp, data.Domain, data.ServerCategory, data.ServerType, data.AdminId, data.AddTime)
return ret, err
}
func (m *defaultMgServersModel) Update(ctx context.Context, data *MgServers) error {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, mgServersRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, data.RegionId, data.Ip, data.PublicIp, data.Domain, data.ServerCategory, data.ServerType, data.AdminId, data.AddTime, data.Id)
return err
}
func (m *defaultMgServersModel) tableName() string {
return m.table
}

View File

@@ -0,0 +1,29 @@
package model
import "github.com/zeromicro/go-zero/core/stores/sqlx"
var _ MsGameServerModel = (*customMsGameServerModel)(nil)
type (
// MsGameServerModel is an interface to be customized, add more methods here,
// and implement the added methods in customMsGameServerModel.
MsGameServerModel interface {
msGameServerModel
withSession(session sqlx.Session) MsGameServerModel
}
customMsGameServerModel struct {
*defaultMsGameServerModel
}
)
// NewMsGameServerModel returns a model for the database table.
func NewMsGameServerModel(conn sqlx.SqlConn) MsGameServerModel {
return &customMsGameServerModel{
defaultMsGameServerModel: newMsGameServerModel(conn),
}
}
func (m *customMsGameServerModel) withSession(session sqlx.Session) MsGameServerModel {
return NewMsGameServerModel(sqlx.NewSqlConnFromSession(session))
}

View File

@@ -0,0 +1,125 @@
// Code generated by goctl. DO NOT EDIT.
// versions:
// goctl version: 1.7.6
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
msGameServerFieldNames = builder.RawFieldNames(&MsGameServer{})
msGameServerRows = strings.Join(msGameServerFieldNames, ",")
msGameServerRowsExpectAutoSet = strings.Join(stringx.Remove(msGameServerFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
msGameServerRowsWithPlaceHolder = strings.Join(stringx.Remove(msGameServerFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
)
type (
msGameServerModel interface {
Insert(ctx context.Context, data *MsGameServer) (sql.Result, error)
FindOne(ctx context.Context, id int) (*MsGameServer, error)
Update(ctx context.Context, data *MsGameServer) error
Delete(ctx context.Context, id int) error
}
defaultMsGameServerModel struct {
conn sqlx.SqlConn
table string
}
MsGameServer struct {
Id int `db:"id"` // ID
AgentId int `db:"agent_id"` // 代理ID
ServerId int `db:"server_id"` // 服务器ID
AgentServer sql.NullInt64 `db:"agent_server"` // agent_id 和 server_id的组合agent_id*10000000 + server_id
ServerName string `db:"server_name"` // 服名称
ServerServerId sql.NullInt64 `db:"server_server_id"` // 游戏节点服的物理服务器ID
MainNodes sql.NullString `db:"main_nodes"` // 主节点集合
Gateways sql.NullString `db:"gateways"` // 网关节点集合
GatewayPort int `db:"gateway_port"` // 游戏服端口
GameCode string `db:"game_code"` // 游戏名
AgentCode string `db:"agent_code"` // 代理
Branch string `db:"branch"` // 分支
ServerStartTime sql.NullTime `db:"server_start_time"` // 开服时间
WebPort int `db:"web_port"` // web访问端口
LogLevel int `db:"log_level"` // 日志等级
LogDir string `db:"log_dir"` // 日志地址
IsDebug string `db:"is_debug"` // debug是否开启,默认false
BackgroundLogOpen string `db:"background_log_open"` // 是否记录后台日志,默认开启
CenterId int `db:"center_id"` // 游戏中央服id
CenterIp string `db:"center_ip"` // 游戏中央服ip
ReplayId int `db:"replay_id"` // 重播日志服务器id
CrossId int `db:"cross_id"` // 跨服服务器id
DbServerId sql.NullInt64 `db:"db_server_id"` // 游戏业务数据库的物理服务器ID
DbPort int `db:"db_port"` // 游戏数据库port
RedisServerId sql.NullInt64 `db:"redis_server_id"` // redis的物理服务器ID
RedisPort sql.NullInt64 `db:"redis_port"` // redis端口
AdminServerId sql.NullInt64 `db:"admin_server_id"` // 游戏日志数据库的物理服务器ID
AdminPort int `db:"admin_port"` // 日志数据库端口
SdkVerifyUrl string `db:"sdk_verify_url"` // SDK验证地址
SdkVerifySandboxUrl string `db:"sdk_verify_sandbox_url"` // SDK验证地址(沙盒)
WebUrl string `db:"web_url"` // API接口域名
EsUrl string `db:"es_url"` // ES接口地址
IsMerge uint `db:"is_merge"` // 是否是合服后的新服
MergeTime sql.NullString `db:"merge_time"` // 合服时间
HbCheckClosed string `db:"hb_check_closed"` // 心跳包检查是否关闭,默认关闭
ItemBanList sql.NullString `db:"item_ban_list"` // 禁用道具
RegionIso string `db:"region_iso"` // 地区ISO
BytedanceLogOpen string `db:"bytedance_log_open"` // 字节跳动元宝日志,默认开启
IsFightLog string `db:"is_fight_log"` // 是否开启战斗日志默认false
CookieExtend string `db:"cookie_extend"` // 节点cookie
IsOverseas int8 `db:"is_overseas"` // 0国内 1国外
Status int8 `db:"status"` // 1:正常; 2:被合服了; 4:关服
}
)
func newMsGameServerModel(conn sqlx.SqlConn) *defaultMsGameServerModel {
return &defaultMsGameServerModel{
conn: conn,
table: "`ms_game_server`",
}
}
func (m *defaultMsGameServerModel) Delete(ctx context.Context, id int) error {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, id)
return err
}
func (m *defaultMsGameServerModel) FindOne(ctx context.Context, id int) (*MsGameServer, error) {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", msGameServerRows, m.table)
var resp MsGameServer
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultMsGameServerModel) Insert(ctx context.Context, data *MsGameServer) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, msGameServerRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.AgentId, data.ServerId, data.AgentServer, data.ServerName, data.ServerServerId, data.MainNodes, data.Gateways, data.GatewayPort, data.GameCode, data.AgentCode, data.Branch, data.ServerStartTime, data.WebPort, data.LogLevel, data.LogDir, data.IsDebug, data.BackgroundLogOpen, data.CenterId, data.CenterIp, data.ReplayId, data.CrossId, data.DbServerId, data.DbPort, data.RedisServerId, data.RedisPort, data.AdminServerId, data.AdminPort, data.SdkVerifyUrl, data.SdkVerifySandboxUrl, data.WebUrl, data.EsUrl, data.IsMerge, data.MergeTime, data.HbCheckClosed, data.ItemBanList, data.RegionIso, data.BytedanceLogOpen, data.IsFightLog, data.CookieExtend, data.IsOverseas, data.Status)
return ret, err
}
func (m *defaultMsGameServerModel) Update(ctx context.Context, data *MsGameServer) error {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, msGameServerRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, data.AgentId, data.ServerId, data.AgentServer, data.ServerName, data.ServerServerId, data.MainNodes, data.Gateways, data.GatewayPort, data.GameCode, data.AgentCode, data.Branch, data.ServerStartTime, data.WebPort, data.LogLevel, data.LogDir, data.IsDebug, data.BackgroundLogOpen, data.CenterId, data.CenterIp, data.ReplayId, data.CrossId, data.DbServerId, data.DbPort, data.RedisServerId, data.RedisPort, data.AdminServerId, data.AdminPort, data.SdkVerifyUrl, data.SdkVerifySandboxUrl, data.WebUrl, data.EsUrl, data.IsMerge, data.MergeTime, data.HbCheckClosed, data.ItemBanList, data.RegionIso, data.BytedanceLogOpen, data.IsFightLog, data.CookieExtend, data.IsOverseas, data.Status, data.Id)
return err
}
func (m *defaultMsGameServerModel) tableName() string {
return m.table
}

View File

@@ -0,0 +1,52 @@
package model
import (
"context"
"errors"
"fmt"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
var _ MsMergeServersModel = (*customMsMergeServersModel)(nil)
type (
// MsMergeServersModel is an interface to be customized, add more methods here,
// and implement the added methods in customMsMergeServersModel.
MsMergeServersModel interface {
msMergeServersModel
withSession(session sqlx.Session) MsMergeServersModel
FinalServer(ctx context.Context, childAgentId, childServerId int64) (FinalAgentId, FinalServerServerId int64, err error)
}
customMsMergeServersModel struct {
*defaultMsMergeServersModel
}
)
func (m *customMsMergeServersModel) FinalServer(ctx context.Context, childAgentId, childServerId int64) (FinalAgentId, FinalServerServerId int64, err error) {
query := fmt.Sprintf("select final_agent_id, final_server_id from %s where child_agent_id = ? and child_server_id = ?", m.table)
var result struct {
FinalServerServerId int64 `db:"final_server_server_id"` // 物理服务器ID来自mg_servers的自增ID
FinalAgentId int64 `db:"final_agent_id"` // 最终被合到了此agent_id下
}
err = m.conn.QueryRowCtx(ctx, &result, query, childAgentId, childServerId)
switch {
case err == nil:
return result.FinalAgentId, result.FinalServerServerId, nil
case errors.Is(err, sqlx.ErrNotFound):
return childAgentId, childServerId, nil
default:
return 0, 0, err
}
}
// NewMsMergeServersModel returns a model for the database table.
func NewMsMergeServersModel(conn sqlx.SqlConn) MsMergeServersModel {
return &customMsMergeServersModel{
defaultMsMergeServersModel: newMsMergeServersModel(conn),
}
}
func (m *customMsMergeServersModel) withSession(session sqlx.Session) MsMergeServersModel {
return NewMsMergeServersModel(sqlx.NewSqlConnFromSession(session))
}

View File

@@ -0,0 +1,96 @@
// Code generated by goctl. DO NOT EDIT.
// versions:
// goctl version: 1.7.6
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
msMergeServersFieldNames = builder.RawFieldNames(&MsMergeServers{})
msMergeServersRows = strings.Join(msMergeServersFieldNames, ",")
msMergeServersRowsExpectAutoSet = strings.Join(stringx.Remove(msMergeServersFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
msMergeServersRowsWithPlaceHolder = strings.Join(stringx.Remove(msMergeServersFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
)
type (
msMergeServersModel interface {
Insert(ctx context.Context, data *MsMergeServers) (sql.Result, error)
FindOne(ctx context.Context, id uint) (*MsMergeServers, error)
Update(ctx context.Context, data *MsMergeServers) error
Delete(ctx context.Context, id uint) error
}
defaultMsMergeServersModel struct {
conn sqlx.SqlConn
table string
}
MsMergeServers struct {
Id uint `db:"id"`
GsId sql.NullInt64 `db:"gs_id"` // 被合的服ms_game_server里的自增id
FinalServerServerId sql.NullInt64 `db:"final_server_server_id"` // 物理服务器ID来自mg_servers的自增ID
FinalAgentId sql.NullInt64 `db:"final_agent_id"` // 最终被合到了此agent_id下
FinalServerId sql.NullInt64 `db:"final_server_id"` // 最终被合到了此server_id下
FinalAgentServer sql.NullInt64 `db:"final_agent_server"` // 最终被合到了此agent_server下
ServerId sql.NullInt64 `db:"server_id"` // 合到此服
AgentServer sql.NullInt64 `db:"agent_server"` // agent_id 和 server_id的组合
ChildAgentId sql.NullInt64 `db:"child_agent_id"` // 被合服的agent_id
ChildServerId sql.NullInt64 `db:"child_server_id"` // 被合服的server_id
ChildAgentServer sql.NullInt64 `db:"child_agent_server"` // 被合服的server_id 和 server_id组合
AdminId sql.NullInt64 `db:"admin_id"` // 操作员
AddTime sql.NullInt64 `db:"add_time"` // 合服时间
}
)
func newMsMergeServersModel(conn sqlx.SqlConn) *defaultMsMergeServersModel {
return &defaultMsMergeServersModel{
conn: conn,
table: "`ms_merge_servers`",
}
}
func (m *defaultMsMergeServersModel) Delete(ctx context.Context, id uint) error {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, id)
return err
}
func (m *defaultMsMergeServersModel) FindOne(ctx context.Context, id uint) (*MsMergeServers, error) {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", msMergeServersRows, m.table)
var resp MsMergeServers
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultMsMergeServersModel) Insert(ctx context.Context, data *MsMergeServers) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, msMergeServersRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.GsId, data.FinalServerServerId, data.FinalAgentId, data.FinalServerId, data.FinalAgentServer, data.ServerId, data.AgentServer, data.ChildAgentId, data.ChildServerId, data.ChildAgentServer, data.AdminId, data.AddTime)
return ret, err
}
func (m *defaultMsMergeServersModel) Update(ctx context.Context, data *MsMergeServers) error {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, msMergeServersRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, data.GsId, data.FinalServerServerId, data.FinalAgentId, data.FinalServerId, data.FinalAgentServer, data.ServerId, data.AgentServer, data.ChildAgentId, data.ChildServerId, data.ChildAgentServer, data.AdminId, data.AddTime, data.Id)
return err
}
func (m *defaultMsMergeServersModel) tableName() string {
return m.table
}

View File

@@ -0,0 +1,80 @@
package model
import (
"context"
"errors"
"fmt"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
var _ NhGameServerNotifyModel = (*customNhGameServerNotifyModel)(nil)
type (
// NhGameServerNotifyModel is an interface to be customized, add more methods here,
// and implement the added methods in customNhGameServerNotifyModel.
NhGameServerNotifyModel interface {
nhGameServerNotifyModel
withSession(session sqlx.Session) NhGameServerNotifyModel
FindNotifyList(ctx context.Context, status int8) ([]*NhGameServerNotify, error)
UpdateNotifyStatus(ctx context.Context, id uint, status int8) error
}
customNhGameServerNotifyModel struct {
*defaultNhGameServerNotifyModel
}
)
const (
NTF_STATUS_UNKNOWN = 0 // 未知
NTF_STATUS_WAITING_PROCESS = 1 // 待处理
NTF_STATUS_PROCESSING = 2 // 处理中
NTF_STATUS_FAILED = 3 // 处理失败
NTF_STATUS_SUCCESS = 4 // 处理成功
)
func (m *customNhGameServerNotifyModel) UpdateNotifyStatus(ctx context.Context, id uint, status int8) error {
var update string
switch status {
case NTF_STATUS_PROCESSING:
update = fmt.Sprintf("update %s set `status` = 2, `retry_times` = `retry_times` + 1 where `id` = ? and (`status` = 1 or `status` = 3)", m.table)
case NTF_STATUS_FAILED:
update = fmt.Sprintf("update %s set `status` = 3 where `id` = ? and `status` = 1", m.table)
case NTF_STATUS_SUCCESS:
update = fmt.Sprintf("update %s set `status` = 4 where `id` = ? and `status` = 1", m.table)
default:
return fmt.Errorf("unsupported status %d", status)
}
result, err := m.conn.ExecCtx(ctx, update, id)
if err != nil {
return err
}
rows, err := result.RowsAffected()
if err != nil {
return err
}
if rows == 0 {
return ErrNoRowUpdate
}
return nil
}
func (m *customNhGameServerNotifyModel) FindNotifyList(ctx context.Context, status int8) ([]*NhGameServerNotify, error) {
query := fmt.Sprintf("select %s from %s where `status` = ? and `retry_times` < 6 limit 10", nhGameServerNotifyRows, m.table)
var ntfs []*NhGameServerNotify
err := m.conn.QueryRowsCtx(ctx, &ntfs, query, status)
if err != nil && !errors.Is(err, sqlx.ErrNotFound) {
return nil, err
}
return ntfs, nil
}
// NewNhGameServerNotifyModel returns a model for the database table.
func NewNhGameServerNotifyModel(conn sqlx.SqlConn) NhGameServerNotifyModel {
return &customNhGameServerNotifyModel{
defaultNhGameServerNotifyModel: newNhGameServerNotifyModel(conn),
}
}
func (m *customNhGameServerNotifyModel) withSession(session sqlx.Session) NhGameServerNotifyModel {
return NewNhGameServerNotifyModel(sqlx.NewSqlConnFromSession(session))
}

View File

@@ -0,0 +1,92 @@
// Code generated by goctl. DO NOT EDIT.
// versions:
// goctl version: 1.7.6
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"time"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
nhGameServerNotifyFieldNames = builder.RawFieldNames(&NhGameServerNotify{})
nhGameServerNotifyRows = strings.Join(nhGameServerNotifyFieldNames, ",")
nhGameServerNotifyRowsExpectAutoSet = strings.Join(stringx.Remove(nhGameServerNotifyFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
nhGameServerNotifyRowsWithPlaceHolder = strings.Join(stringx.Remove(nhGameServerNotifyFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
)
type (
nhGameServerNotifyModel interface {
Insert(ctx context.Context, data *NhGameServerNotify) (sql.Result, error)
FindOne(ctx context.Context, id uint) (*NhGameServerNotify, error)
Update(ctx context.Context, data *NhGameServerNotify) error
Delete(ctx context.Context, id uint) error
}
defaultNhGameServerNotifyModel struct {
conn sqlx.SqlConn
table string
}
NhGameServerNotify struct {
Id uint `db:"id"`
RoleId uint64 `db:"role_id"` // 角色id
Action string `db:"action"` // 事件类型
Data sql.NullString `db:"data"` // 事件数据
Status int8 `db:"status"` // 状态1=待处理2=处理中, 3=处理失败, 4=处理成功
RetryTimes int `db:"retry_times"` // 重试次数
CreatedAt time.Time `db:"created_at"` // 创建时间
UpdatedAt time.Time `db:"updated_at"` // 修改时间
}
)
func newNhGameServerNotifyModel(conn sqlx.SqlConn) *defaultNhGameServerNotifyModel {
return &defaultNhGameServerNotifyModel{
conn: conn,
table: "`nh_game_server_notify`",
}
}
func (m *defaultNhGameServerNotifyModel) Delete(ctx context.Context, id uint) error {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, id)
return err
}
func (m *defaultNhGameServerNotifyModel) FindOne(ctx context.Context, id uint) (*NhGameServerNotify, error) {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", nhGameServerNotifyRows, m.table)
var resp NhGameServerNotify
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultNhGameServerNotifyModel) Insert(ctx context.Context, data *NhGameServerNotify) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?)", m.table, nhGameServerNotifyRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.RoleId, data.Action, data.Data, data.Status, data.RetryTimes)
return ret, err
}
func (m *defaultNhGameServerNotifyModel) Update(ctx context.Context, data *NhGameServerNotify) error {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, nhGameServerNotifyRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, data.RoleId, data.Action, data.Data, data.Status, data.RetryTimes, data.Id)
return err
}
func (m *defaultNhGameServerNotifyModel) tableName() string {
return m.table
}

View File

@@ -0,0 +1,29 @@
package model
import "github.com/zeromicro/go-zero/core/stores/sqlx"
var _ NhRequestServerLogModel = (*customNhRequestServerLogModel)(nil)
type (
// NhRequestServerLogModel is an interface to be customized, add more methods here,
// and implement the added methods in customNhRequestServerLogModel.
NhRequestServerLogModel interface {
nhRequestServerLogModel
withSession(session sqlx.Session) NhRequestServerLogModel
}
customNhRequestServerLogModel struct {
*defaultNhRequestServerLogModel
}
)
// NewNhRequestServerLogModel returns a model for the database table.
func NewNhRequestServerLogModel(conn sqlx.SqlConn) NhRequestServerLogModel {
return &customNhRequestServerLogModel{
defaultNhRequestServerLogModel: newNhRequestServerLogModel(conn),
}
}
func (m *customNhRequestServerLogModel) withSession(session sqlx.Session) NhRequestServerLogModel {
return NewNhRequestServerLogModel(sqlx.NewSqlConnFromSession(session))
}

View File

@@ -0,0 +1,90 @@
// Code generated by goctl. DO NOT EDIT.
// versions:
// goctl version: 1.7.6
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
nhRequestServerLogFieldNames = builder.RawFieldNames(&NhRequestServerLog{})
nhRequestServerLogRows = strings.Join(nhRequestServerLogFieldNames, ",")
nhRequestServerLogRowsExpectAutoSet = strings.Join(stringx.Remove(nhRequestServerLogFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
nhRequestServerLogRowsWithPlaceHolder = strings.Join(stringx.Remove(nhRequestServerLogFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
)
type (
nhRequestServerLogModel interface {
Insert(ctx context.Context, data *NhRequestServerLog) (sql.Result, error)
FindOne(ctx context.Context, id int) (*NhRequestServerLog, error)
Update(ctx context.Context, data *NhRequestServerLog) error
Delete(ctx context.Context, id int) error
}
defaultNhRequestServerLogModel struct {
conn sqlx.SqlConn
table string
}
NhRequestServerLog struct {
Id int `db:"id"`
Action string `db:"action"` // 接口
Url string `db:"url"` // 推送地址
ServerInfo string `db:"server_info"`
ReqData string `db:"req_data"` // 请求数据
ResData string `db:"res_data"` // 响应数据
CreateTime sql.NullTime `db:"create_time"` // 创建时间
}
)
func newNhRequestServerLogModel(conn sqlx.SqlConn) *defaultNhRequestServerLogModel {
return &defaultNhRequestServerLogModel{
conn: conn,
table: "`nh_request_server_log`",
}
}
func (m *defaultNhRequestServerLogModel) Delete(ctx context.Context, id int) error {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, id)
return err
}
func (m *defaultNhRequestServerLogModel) FindOne(ctx context.Context, id int) (*NhRequestServerLog, error) {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", nhRequestServerLogRows, m.table)
var resp NhRequestServerLog
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultNhRequestServerLogModel) Insert(ctx context.Context, data *NhRequestServerLog) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?)", m.table, nhRequestServerLogRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.Action, data.Url, data.ServerInfo, data.ReqData, data.ResData)
return ret, err
}
func (m *defaultNhRequestServerLogModel) Update(ctx context.Context, data *NhRequestServerLog) error {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, nhRequestServerLogRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, data.Action, data.Url, data.ServerInfo, data.ReqData, data.ResData, data.Id)
return err
}
func (m *defaultNhRequestServerLogModel) tableName() string {
return m.table
}

View File

@@ -0,0 +1,45 @@
package model
import (
"context"
"errors"
"fmt"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
var _ NhStakeHomePointConfigModel = (*customNhStakeHomePointConfigModel)(nil)
type (
// NhStakeHomePointConfigModel is an interface to be customized, add more methods here,
// and implement the added methods in customNhStakeHomePointConfigModel.
NhStakeHomePointConfigModel interface {
nhStakeHomePointConfigModel
withSession(session sqlx.Session) NhStakeHomePointConfigModel
All(ctx context.Context) ([]*NhStakeHomePointConfig, error)
}
customNhStakeHomePointConfigModel struct {
*defaultNhStakeHomePointConfigModel
}
)
func (m *customNhStakeHomePointConfigModel) All(ctx context.Context) ([]*NhStakeHomePointConfig, error) {
query := fmt.Sprintf("select %s from %s", nhStakeHomePointConfigRows, m.table)
var resp []*NhStakeHomePointConfig
err := m.conn.QueryRowsCtx(ctx, &resp, query)
if err != nil && !errors.Is(err, sqlx.ErrNotFound) {
return nil, err
}
return resp, nil
}
// NewNhStakeHomePointConfigModel returns a model for the database table.
func NewNhStakeHomePointConfigModel(conn sqlx.SqlConn) NhStakeHomePointConfigModel {
return &customNhStakeHomePointConfigModel{
defaultNhStakeHomePointConfigModel: newNhStakeHomePointConfigModel(conn),
}
}
func (m *customNhStakeHomePointConfigModel) withSession(session sqlx.Session) NhStakeHomePointConfigModel {
return NewNhStakeHomePointConfigModel(sqlx.NewSqlConnFromSession(session))
}

View File

@@ -0,0 +1,95 @@
// Code generated by goctl. DO NOT EDIT.
// versions:
// goctl version: 1.7.6
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"time"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
"github.com/shopspring/decimal"
)
var (
nhStakeHomePointConfigFieldNames = builder.RawFieldNames(&NhStakeHomePointConfig{})
nhStakeHomePointConfigRows = strings.Join(nhStakeHomePointConfigFieldNames, ",")
nhStakeHomePointConfigRowsExpectAutoSet = strings.Join(stringx.Remove(nhStakeHomePointConfigFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
nhStakeHomePointConfigRowsWithPlaceHolder = strings.Join(stringx.Remove(nhStakeHomePointConfigFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
)
type (
nhStakeHomePointConfigModel interface {
Insert(ctx context.Context, data *NhStakeHomePointConfig) (sql.Result, error)
FindOne(ctx context.Context, id uint) (*NhStakeHomePointConfig, error)
Update(ctx context.Context, data *NhStakeHomePointConfig) error
Delete(ctx context.Context, id uint) error
}
defaultNhStakeHomePointConfigModel struct {
conn sqlx.SqlConn
table string
}
NhStakeHomePointConfig struct {
Id uint `db:"id"`
Title string `db:"title"` // 名称
Level uint `db:"level"` // 精灵等级,必须为连续的数字
Points uint `db:"points"` // 积分数量
Days decimal.Decimal `db:"days"` // 天数,为了测试方便,增加小数
RenewDays decimal.Decimal `db:"renew_days"` // 续存倒数天数,为了测试方便,增加小数
Status int8 `db:"status"` // 状态0=正常1=停用
CreatedAt time.Time `db:"created_at"` // 创建时间
UpdatedAt time.Time `db:"updated_at"` // 修改时间
}
)
func newNhStakeHomePointConfigModel(conn sqlx.SqlConn) *defaultNhStakeHomePointConfigModel {
return &defaultNhStakeHomePointConfigModel{
conn: conn,
table: "`nh_stake_home_point_config`",
}
}
func (m *defaultNhStakeHomePointConfigModel) Delete(ctx context.Context, id uint) error {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, id)
return err
}
func (m *defaultNhStakeHomePointConfigModel) FindOne(ctx context.Context, id uint) (*NhStakeHomePointConfig, error) {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", nhStakeHomePointConfigRows, m.table)
var resp NhStakeHomePointConfig
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultNhStakeHomePointConfigModel) Insert(ctx context.Context, data *NhStakeHomePointConfig) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?)", m.table, nhStakeHomePointConfigRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.Title, data.Level, data.Points, data.Days, data.RenewDays, data.Status)
return ret, err
}
func (m *defaultNhStakeHomePointConfigModel) Update(ctx context.Context, data *NhStakeHomePointConfig) error {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, nhStakeHomePointConfigRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, data.Title, data.Level, data.Points, data.Days, data.RenewDays, data.Status, data.Id)
return err
}
func (m *defaultNhStakeHomePointConfigModel) tableName() string {
return m.table
}

View File

@@ -0,0 +1,103 @@
package model
import (
"context"
"errors"
"fmt"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"time"
)
var _ NhStakePointsModel = (*customNhStakePointsModel)(nil)
type (
// NhStakePointsModel is an interface to be customized, add more methods here,
// and implement the added methods in customNhStakePointsModel.
NhStakePointsModel interface {
nhStakePointsModel
WithSession(session sqlx.Session) NhStakePointsModel
FindCurrentLevel(ctx context.Context, roleId int64) (*NhStakePoints, error)
FindRenewLevel(ctx context.Context, roleId int64) (*NhStakePoints, error)
FindOverdueList(ctx context.Context) ([]*NhStakePoints, error)
SetOverdue(ctx context.Context, id uint) error
}
customNhStakePointsModel struct {
*defaultNhStakePointsModel
}
)
const (
PointsStakeStatusUnknown = 0 // 未知状态
PointsStakeStatusStaking = 1 // 质押中
PointsStakeStatusUpgraded = 2 // 已升级
PointsStakeStatusRenew = 3 // 已续约
PointsStakeStatusOverdue = 4 // 已过期
)
func (m *customNhStakePointsModel) SetOverdue(ctx context.Context, id uint) error {
update := fmt.Sprintf("update %s set `status` = %d where `id` = ? and `status` = %d", m.table, PointsStakeStatusOverdue, PointsStakeStatusStaking)
result, err := m.conn.ExecCtx(ctx, update, id)
if err != nil {
return err
}
rows, err := result.RowsAffected()
if err != nil {
return err
}
if rows == 0 {
return ErrNoRowUpdate
}
return nil
}
func (m *customNhStakePointsModel) FindOverdueList(ctx context.Context) ([]*NhStakePoints, error) {
query := fmt.Sprintf("select %s from %s where end_time <= ? and `status` = %d limit 100", nhStakePointsRows, m.table, PointsStakeStatusStaking)
var resp []*NhStakePoints
err := m.conn.QueryRowsCtx(ctx, &resp, query, time.Now())
if err != nil && !errors.Is(err, sqlx.ErrNotFound) {
return nil, err
}
return resp, nil
}
func (m *customNhStakePointsModel) FindRenewLevel(ctx context.Context, roleId int64) (*NhStakePoints, error) {
query := fmt.Sprintf("select %s from %s where `role_id` = ? and start_time > ? and `status` = %d limit 1", nhStakePointsRows, m.table, PointsStakeStatusStaking)
var resp NhStakePoints
now := time.Now()
err := m.conn.QueryRowCtx(ctx, &resp, query, roleId, now)
switch {
case err == nil:
return &resp, nil
case errors.Is(err, sqlx.ErrNotFound):
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *customNhStakePointsModel) FindCurrentLevel(ctx context.Context, roleId int64) (*NhStakePoints, error) {
query := fmt.Sprintf("select %s from %s where `role_id` = ? and start_time <= ? and end_time >= ? and (`status` = %d or `status` = %d) limit 1", nhStakePointsRows, m.table, PointsStakeStatusStaking, PointsStakeStatusRenew)
var resp NhStakePoints
now := time.Now()
err := m.conn.QueryRowCtx(ctx, &resp, query, roleId, now, now)
switch {
case err == nil:
return &resp, nil
case errors.Is(err, sqlx.ErrNotFound):
return nil, ErrNotFound
default:
return nil, err
}
}
// NewNhStakePointsModel returns a model for the database table.
func NewNhStakePointsModel(conn sqlx.SqlConn) NhStakePointsModel {
return &customNhStakePointsModel{
defaultNhStakePointsModel: newNhStakePointsModel(conn),
}
}
func (m *customNhStakePointsModel) WithSession(session sqlx.Session) NhStakePointsModel {
return NewNhStakePointsModel(sqlx.NewSqlConnFromSession(session))
}

View File

@@ -0,0 +1,93 @@
// Code generated by goctl. DO NOT EDIT.
// versions:
// goctl version: 1.7.6
package model
import (
"context"
"database/sql"
"fmt"
"strings"
"time"
"github.com/zeromicro/go-zero/core/stores/builder"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/core/stringx"
)
var (
nhStakePointsFieldNames = builder.RawFieldNames(&NhStakePoints{})
nhStakePointsRows = strings.Join(nhStakePointsFieldNames, ",")
nhStakePointsRowsExpectAutoSet = strings.Join(stringx.Remove(nhStakePointsFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
nhStakePointsRowsWithPlaceHolder = strings.Join(stringx.Remove(nhStakePointsFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
)
type (
nhStakePointsModel interface {
Insert(ctx context.Context, data *NhStakePoints) (sql.Result, error)
FindOne(ctx context.Context, id uint) (*NhStakePoints, error)
Update(ctx context.Context, data *NhStakePoints) error
Delete(ctx context.Context, id uint) error
}
defaultNhStakePointsModel struct {
conn sqlx.SqlConn
table string
}
NhStakePoints struct {
Id uint `db:"id"`
Uid uint `db:"uid"` // 用户id
RoleId uint64 `db:"role_id"` // 角色id
LevelId uint `db:"level_id"` // 档位id
Level uint `db:"level"` // 档位
Points uint `db:"points"` // 积分数量
StartTime time.Time `db:"start_time"` // 开始时间戳
EndTime time.Time `db:"end_time"` // 结束时间戳
Status int8 `db:"status"` // 状态1=质押中2=已升级3=已续约4=已过期
}
)
func newNhStakePointsModel(conn sqlx.SqlConn) *defaultNhStakePointsModel {
return &defaultNhStakePointsModel{
conn: conn,
table: "`nh_stake_points`",
}
}
func (m *defaultNhStakePointsModel) Delete(ctx context.Context, id uint) error {
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, id)
return err
}
func (m *defaultNhStakePointsModel) FindOne(ctx context.Context, id uint) (*NhStakePoints, error) {
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", nhStakePointsRows, m.table)
var resp NhStakePoints
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultNhStakePointsModel) Insert(ctx context.Context, data *NhStakePoints) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?)", m.table, nhStakePointsRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.Uid, data.RoleId, data.LevelId, data.Level, data.Points, data.StartTime, data.EndTime, data.Status)
return ret, err
}
func (m *defaultNhStakePointsModel) Update(ctx context.Context, data *NhStakePoints) error {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, nhStakePointsRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, data.Uid, data.RoleId, data.LevelId, data.Level, data.Points, data.StartTime, data.EndTime, data.Status, data.Id)
return err
}
func (m *defaultNhStakePointsModel) tableName() string {
return m.table
}

View File

@@ -17,19 +17,31 @@ const (
ErrGenerateUUid Reason = 1004 // 生成uuid错误
ErrGenerateToken Reason = 1005 // 生成token错误
ErrSystemConfig Reason = 1006 // 系统配置错误
GameServerError Reason = 1007 // 游戏服务器错误
// ======= 业务层错误20000~29999 =======
ErrUnknownLogicError Reason = 20000 // 未知的业务错误
ErrTaskNotFound Reason = 20001 // 任务不存在
ErrTaskAlreadyReward Reason = 20002 // 任务已领取
ErrTaskNotFinished Reason = 20003 // 任务未完成
ErrNotBindWallet Reason = 20004 // 未绑定钱包
ErrTaskOpenDateNotSet Reason = 20005 // 任务开放时间未设置
ErrTaskConfNotSet Reason = 20006 // 任务配置未设置
ErrUserNotFound Reason = 20007 // 用户不存在
ErrNftNotBelongToUser Reason = 20008 // NFT不属于用户
ErrInvalidApiKey Reason = 20009 // 无效的api key
ErrRoleNotFound Reason = 20010 // 角色不存在
ErrInvalidParam Reason = 20011 // 无效的参数
ErrNotBindRole Reason = 20012 // 未绑定角色
ErrUnknownLogicError Reason = 20000 // 未知的业务错误
ErrTaskNotFound Reason = 20001 // 任务不存在
ErrTaskAlreadyReward Reason = 20002 // 任务已领取
ErrTaskNotFinished Reason = 20003 // 任务未完成
ErrNotBindWallet Reason = 20004 // 未绑定钱包
ErrTaskOpenDateNotSet Reason = 20005 // 任务开放时间未设置
ErrTaskConfNotSet Reason = 20006 // 任务配置未设置
ErrUserNotFound Reason = 20007 // 用户不存在
ErrNftNotBelongToUser Reason = 20008 // NFT不属于用户
ErrInvalidApiKey Reason = 20009 // 无效的api key
ErrRoleNotFound Reason = 20010 // 角色不存在
ErrInvalidParam Reason = 20011 // 无效的参数
ErrNotBindRole Reason = 20012 // 未绑定角色
ErrPointLevelConfigNotFound Reason = 20013 // 找不到质押积分档位配置
ErrPointsStakeExist Reason = 20014 // 质押积分已存在
ErrPointStakeNotExist Reason = 20015 // 质押积分不存在
ErrInsufficientPoints Reason = 20016 // 用户积分不足
ErrInsufficientCastile Reason = 20017 // 用户Castile不足
ErrInsufficientElitePoints Reason = 20018 // 用户精英积分不足
ErrInsufficientKeys Reason = 20019 // 用户钥匙不足
ErrPointsStakeLevelNotAllow Reason = 20020 // 质押积分档位不允许
ErrPointsStakeHasRenew Reason = 20021 // 质押积分已续期
ErrPointsStakeNotInRenewTime Reason = 20022 // 质押积分不在续期时间范围内
)

126
internal/svc/game_action.go Normal file
View File

@@ -0,0 +1,126 @@
package svc
import (
"bytes"
"context"
"database/sql"
"encoding/json"
"fmt"
"github.com/spf13/cast"
"github.com/zeromicro/go-zero/core/logx"
"io"
"math"
"net/http"
"nova_task/internal/model"
"nova_task/internal/pkg/encrypt/md5"
"strconv"
"strings"
"time"
)
// GetGameServerAddress 获取游戏服地址
func (s *ServiceContext) GetGameServerAddress(ctx context.Context, roleID int64) (string, map[string]any, error) {
agentIDServerID := math.Floor(float64(roleID)/100000000) / 100000
splitStr := cast.ToString(agentIDServerID)
splitParts := []string{"0", "0"}
if parts := strings.Split(splitStr, "."); len(parts) == 2 {
splitParts = parts
}
serverInfo := map[string]any{}
originalAgentID, _ := strconv.ParseInt(splitParts[0], 10, 64)
originalServerID, _ := strconv.ParseInt(splitParts[1], 10, 64)
serverInfo["original_agent_id"] = originalAgentID
serverInfo["original_server_id"] = originalServerID
agentId, serverServerId, err := s.MergeServerModel.FinalServer(ctx, originalAgentID, originalServerID)
if err != nil {
return "", serverInfo, err
}
serverInfo["agent_id"] = agentId
serverInfo["server_id"] = serverServerId
gs, err := s.ServersModel.GetGameServer(ctx, agentId, serverServerId)
if err != nil {
return "", serverInfo, err
}
serverInfo["web_port"] = gs.WebPort
serverInfo["server_ip"] = gs.ServerIP
serverInfo["public_server_ip"] = gs.PublicServerIP
return fmt.Sprintf("http://%s:%d", gs.PublicServerIP, gs.WebPort), serverInfo, nil
}
func (s *ServiceContext) GameAction(ctx context.Context, roleId int64, action string, args map[string]any) (any, error) {
//return map[string]any{
// "data": 1,
// "ret": 1,
//}, nil
addr, serverInfo, err := s.GetGameServerAddress(ctx, roleId)
if err != nil {
return nil, err
}
now := time.Now().Unix()
request := map[string]any{
"nova_time": now,
"nova_token": md5.Md5str(fmt.Sprintf("%d%s", now, s.Config.NovaToken)),
"nova_action": action,
"role_id": roleId,
}
for k, v := range args {
if _, ok := request[k]; ok {
continue
}
request[k] = v
}
data, _ := json.Marshal(request)
httpReq, err := http.NewRequest(http.MethodPost, addr, bytes.NewReader(data))
if err != nil {
return nil, err
}
httpReq.Header.Set("Content-Type", "application/json")
httpReq.Header.Set("Accept", "application/json")
httpResp, err := http.DefaultClient.Do(httpReq)
if err != nil {
s.ErrLog(ctx, action, addr, serverInfo, request, nil)
return nil, err
}
respData, _ := io.ReadAll(httpResp.Body)
resp := map[string]any{}
if err := json.Unmarshal(respData, &resp); err != nil {
s.ErrLog(ctx, action, addr, serverInfo, request, string(respData))
return nil, err
}
if cast.ToInt64(resp["ret"]) != 1 {
s.ErrLog(ctx, action, addr, serverInfo, request, resp)
return resp, fmt.Errorf("game action msg= %s, data=%v", cast.ToString(resp["msg"]), cast.ToString(resp["data"]))
}
return resp, nil
}
func (s *ServiceContext) ErrLog(ctx context.Context, action, url string, serverInfo, req, resp any) {
var marshal = func(v any) string {
if v == nil {
return ""
}
if vv, ok := v.(string); ok {
return vv
}
data, _ := json.Marshal(v)
return string(data)
}
_, err := s.RequestServerLogModel.Insert(ctx, &model.NhRequestServerLog{
Action: action,
Url: url,
ServerInfo: marshal(serverInfo),
ReqData: marshal(req),
ResData: marshal(resp),
CreateTime: sql.NullTime{Valid: true, Time: time.Now()},
})
if err != nil {
logx.Errorw("insert request server log error", logx.Field("err", err), logx.Field("action", action), logx.Field("url", url), logx.Field("server_info", serverInfo), logx.Field("req", req), logx.Field("resp", resp))
}
}

84
internal/svc/model.go Normal file
View File

@@ -0,0 +1,84 @@
package svc
import (
"github.com/zeromicro/go-zero/core/stores/sqlx"
"nova_task/internal/model"
)
type dbModel struct {
TaskModel model.NhTaskModel
taskAssetModel model.NhTaskAssetModel
taskAssetRecordModel model.NhTaskAssetRecordModel
TaskProgressModel model.NhTaskProgressModel
TwitterModel model.NhTwitterModel
PromoteBindModel model.NhPromoteBindModel
TouristBindModel model.NhTouristBindModel
CommunityModel model.NhTaskCommunityModel
UserModel model.NhUserModel
WalletModel model.NhWalletModel
ConfigModel model.NhSystemConfigModel
NftHolderModel model.NhNftHolderModel
NftHolderChangeLogModel model.NhNftHolderChangeLogModel
StakeNftModel model.NhTaskNftStakeModel
OldStakeNftModel model.NhNftStakeModel
StakeNftLogModel model.NhTaskNftStakeLogModel
StakeRewardModel model.NhTaskNftStakeRewardModel
GamePitModel model.NhGamePitModel
StakePropertyModel model.NhNftStakePropertyModel
EmailRewardModel model.NhEmailRewardModel
AmbassadorModel model.NhTaskAmbassadorModel
GameReportModel model.NhGameReportModel
RoleModel model.NhRoleModel
GamesPropertyModel model.NhGamesPropertyLogsModel
AirdropModel model.NhAirdropLogModel
PioneerRewardsModel model.NhPioneerRewardsModel
MergeServerModel model.MsMergeServersModel
GameServerModel model.MsGameServerModel
ServersModel model.MgServersModel
GameServerNotifyModel model.NhGameServerNotifyModel
RequestServerLogModel model.NhRequestServerLogModel
StakePointConfigModel model.NhStakeHomePointConfigModel
StakePointsModel model.NhStakePointsModel
}
func newDBModel(dbConn, gameConn sqlx.SqlConn, configModel model.NhSystemConfigModel) *dbModel {
return &dbModel{
TaskModel: model.NewNhTaskModel(dbConn),
taskAssetModel: model.NewNhTaskAssetModel(dbConn),
taskAssetRecordModel: model.NewNhTaskAssetRecordModel(dbConn),
TaskProgressModel: model.NewNhTaskProgressModel(dbConn),
TwitterModel: model.NewNhTwitterModel(dbConn),
PromoteBindModel: model.NewNhPromoteBindModel(dbConn),
CommunityModel: model.NewNhTaskCommunityModel(dbConn),
UserModel: model.NewNhUserModel(dbConn),
TouristBindModel: model.NewNhTouristBindModel(dbConn),
WalletModel: model.NewNhWalletModel(dbConn),
ConfigModel: configModel,
NftHolderModel: model.NewNhNftHolderModel(dbConn),
NftHolderChangeLogModel: model.NewNhNftHolderChangeLogModel(dbConn),
StakeNftModel: model.NewNhTaskNftStakeModel(dbConn),
OldStakeNftModel: model.NewNhNftStakeModel(dbConn),
StakeRewardModel: model.NewNhTaskNftStakeRewardModel(dbConn),
GamePitModel: model.NewNhGamePitModel(dbConn),
StakePropertyModel: model.NewNhNftStakePropertyModel(dbConn),
EmailRewardModel: model.NewNhEmailRewardModel(dbConn),
AmbassadorModel: model.NewNhTaskAmbassadorModel(dbConn),
GameReportModel: model.NewNhGameReportModel(dbConn),
RoleModel: model.NewNhRoleModel(dbConn),
GamesPropertyModel: model.NewNhGamesPropertyLogsModel(dbConn),
AirdropModel: model.NewNhAirdropLogModel(dbConn),
PioneerRewardsModel: model.NewNhPioneerRewardsModel(dbConn),
StakePointConfigModel: model.NewNhStakeHomePointConfigModel(dbConn),
StakePointsModel: model.NewNhStakePointsModel(dbConn),
GameServerNotifyModel: model.NewNhGameServerNotifyModel(dbConn),
RequestServerLogModel: model.NewNhRequestServerLogModel(dbConn),
MergeServerModel: model.NewMsMergeServersModel(gameConn),
GameServerModel: model.NewMsGameServerModel(gameConn),
ServersModel: model.NewMgServersModel(gameConn),
}
}

View File

@@ -22,32 +22,7 @@ import (
type ServiceContext struct {
Config config.Config
TaskModel model.NhTaskModel
taskAssetModel model.NhTaskAssetModel
taskAssetRecordModel model.NhTaskAssetRecordModel
TaskProgressModel model.NhTaskProgressModel
TwitterModel model.NhTwitterModel
PromoteBindModel model.NhPromoteBindModel
TouristBindModel model.NhTouristBindModel
CommunityModel model.NhTaskCommunityModel
UserModel model.NhUserModel
WalletModel model.NhWalletModel
ConfigModel model.NhSystemConfigModel
NftHolderModel model.NhNftHolderModel
NftHolderChangeLogModel model.NhNftHolderChangeLogModel
StakeNftModel model.NhTaskNftStakeModel
OldStakeNftModel model.NhNftStakeModel
StakeNftLogModel model.NhTaskNftStakeLogModel
StakeRewardModel model.NhTaskNftStakeRewardModel
GamePitModel model.NhGamePitModel
StakePropertyModel model.NhNftStakePropertyModel
EmailRewardModel model.NhEmailRewardModel
AmbassadorModel model.NhTaskAmbassadorModel
GameReportModel model.NhGameReportModel
RoleModel model.NhRoleModel
GamesPropertyModel model.NhGamesPropertyLogsModel
AirdropModel model.NhAirdropLogModel
PioneerRewardsModel model.NhPioneerRewardsModel
*dbModel
ApiKeyCheck rest.Middleware
AdminSecretCheck rest.Middleware
@@ -61,44 +36,18 @@ type ServiceContext struct {
func NewServiceContext(c config.Config) *ServiceContext {
dbConn := c.MySql.Conn()
gameConn := c.GameDB.Conn()
configModel := model.NewNhSystemConfigModel(dbConn, c.Cache)
return &ServiceContext{
Config: c,
TaskModel: model.NewNhTaskModel(dbConn),
taskAssetModel: model.NewNhTaskAssetModel(dbConn),
taskAssetRecordModel: model.NewNhTaskAssetRecordModel(dbConn),
TaskProgressModel: model.NewNhTaskProgressModel(dbConn),
TwitterModel: model.NewNhTwitterModel(dbConn),
PromoteBindModel: model.NewNhPromoteBindModel(dbConn),
CommunityModel: model.NewNhTaskCommunityModel(dbConn),
UserModel: model.NewNhUserModel(dbConn),
TouristBindModel: model.NewNhTouristBindModel(dbConn),
WalletModel: model.NewNhWalletModel(dbConn),
ConfigModel: configModel,
NftHolderModel: model.NewNhNftHolderModel(dbConn),
NftHolderChangeLogModel: model.NewNhNftHolderChangeLogModel(dbConn),
StakeNftModel: model.NewNhTaskNftStakeModel(dbConn),
OldStakeNftModel: model.NewNhNftStakeModel(dbConn),
StakeRewardModel: model.NewNhTaskNftStakeRewardModel(dbConn),
GamePitModel: model.NewNhGamePitModel(dbConn),
StakePropertyModel: model.NewNhNftStakePropertyModel(dbConn),
EmailRewardModel: model.NewNhEmailRewardModel(dbConn),
AmbassadorModel: model.NewNhTaskAmbassadorModel(dbConn),
GameReportModel: model.NewNhGameReportModel(dbConn),
RoleModel: model.NewNhRoleModel(dbConn),
GamesPropertyModel: model.NewNhGamesPropertyLogsModel(dbConn),
AirdropModel: model.NewNhAirdropLogModel(dbConn),
PioneerRewardsModel: model.NewNhPioneerRewardsModel(dbConn),
Config: c,
dbModel: newDBModel(dbConn, gameConn, configModel),
ApiKeyCheck: middleware.NewApiKeyCheckMiddleware(configModel).Handle,
AdminSecretCheck: middleware.NewAdminSecretCheckMiddleware(configModel).Handle,
Game7ApiKeyCheck: middleware.NewGame7ApiKeyCheckMiddleware(configModel).Handle,
KGeNApiKeyCheck: middleware.NewKGeNApiKeyCheckMiddleware(configModel).Handle,
Earn: c.Earn.BuildEarnClient(),
DBConn: dbConn,
Redis: redis.MustNewRedis(c.Redis),
DBConn: dbConn,
Earn: c.Earn.BuildEarnClient(),
Redis: redis.MustNewRedis(c.Redis),
}
}
@@ -173,6 +122,35 @@ func (s *ServiceContext) AddUserAssetWithSession(ctx context.Context, session sq
recordModel = s.taskAssetRecordModel
gamesPropertyModel = s.GamesPropertyModel
}
if amount.LessThan(decimal.Zero) {
uAsset, err := assetModel.FindOneByUid(ctx, int(uid))
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return errs.New(errs.ErrInsufficientPoints, "insufficient point")
}
return errs.New(errs.ErrDatabaseOperate, err)
}
switch asset {
case consts.AssetType_Points:
if uAsset.Points.LessThan(amount.Abs()) {
return errs.New(errs.ErrInsufficientPoints, "insufficient point")
}
case consts.AssetType_Castile:
if uAsset.Castile.LessThan(amount.Abs()) {
return errs.New(errs.ErrInsufficientCastile, "insufficient castile")
}
case consts.AssetType_Elite_Points:
if uAsset.ElitePoints.LessThan(amount.Abs()) {
return errs.New(errs.ErrInsufficientElitePoints, "insufficient elite points")
}
case consts.AssetType_Keys:
if uAsset.Keys < int(amount.IntPart()) {
return errs.New(errs.ErrInsufficientKeys, "insufficient keys")
}
default:
return errors.New("unknown asset type")
}
}
var err error
switch asset {
case consts.AssetType_Points:
@@ -186,7 +164,7 @@ func (s *ServiceContext) AddUserAssetWithSession(ctx context.Context, session sq
case consts.AssetType_Property:
_, err = gamesPropertyModel.Insert(ctx, &model.NhGamesPropertyLogs{
Uid: uid,
RoleId: int64(role),
RoleId: role,
PropertyId: assetId,
PropertyNum: uint(amount.IntPart()),
})
@@ -234,6 +212,7 @@ func (s *ServiceContext) AddUserAssetWithSession(ctx context.Context, session sq
return s.AddUserAssetWithSession(ctx, session, pb.ShareUid, 0, asset, assetId, rewardAmount, fmt.Sprintf("分享返利,比例%s", rated.String()), 7, uid, false)
}
// AddUserAsset 增加用户资产
func (s *ServiceContext) AddUserAsset(ctx context.Context, uid uint, role int64, asset consts.AssetType, assetId string, amount decimal.Decimal, remark string, eventId uint64, provideUid uint, referralReward bool) error {
return s.AddUserAssetWithSession(ctx, nil, uid, role, asset, assetId, amount, remark, eventId, provideUid, referralReward)
}

View File

@@ -55,6 +55,17 @@ type Game7TaskCheckReq struct {
Type int8 `form:"type"` // 1.是否在官网注册并链接钱包(是/否) 2.是否有超过两个以上的英雄(是/否) 3.是否消耗召唤券召唤了新英雄(是/否) 4. 是否在游戏内绑定了官网账号(是/否) 5. 是否有一个31级以上的英雄是/否) 6. 是否完成了主线第一章(是/否)
}
type GameActionReq struct {
RoleId int64 `json:"role_id"`
Action string `json:"action"`
}
type GameActionResp struct {
Ret int `json:"ret"`
Msg string `json:"msg"`
Data interface{} `json:"data"`
}
type GetCommunityListResp struct {
CommunityList []Community `json:"community_list"` // 社区列表
}
@@ -63,6 +74,17 @@ type GetNftListReq struct {
WalletAddress string `form:"wallet_address"`
}
type GetStakeLevelListReq struct {
RoleID int64 `form:"role_id"` // 角色id
}
type GetStakeLevelListResp struct {
State int `json:"state"` // 状态1表示已开启可质押 0表示不可质押
Staking *StakeLevel `json:"staking,optional"` // 质押中的档位信息
RenewLevel *StakeLevel `json:"renew_level,optional"` // 已续约的档位信息
Levels []PointStakeLevel `json:"levels"` // 档位列表
}
type GetTaskListReq struct {
CommunityId uint `form:"community_id,optional"` // 所属社区ID
}
@@ -108,6 +130,15 @@ type PioneerReward struct {
Total float64 `json:"total"` // 总额
}
type PointStakeLevel struct {
Id int `json:"id"` // 档位id
Title string `json:"title"` // 档位标题
Level int `json:"level"` // 精灵等级
Points int `json:"points"` // 积分数量
Days float64 `json:"days"` // 质押天数
RenewDays float64 `json:"renew_days"` // 续期天数
}
type Result struct {
IsValid bool `json:"isValid"`
}
@@ -116,11 +147,29 @@ type StakeByAddressReq struct {
Address []string `json:"address"`
}
type StakeLevel struct {
Id int `json:"id"`
Title string `json:"title"` // 档位标题
Level int `json:"level"` // 精灵等级
Points int `json:"points"` // 积分数量
Days float64 `json:"days"` // 质押天数
RenewDays float64 `json:"renew_days"` // 续期天数
StartTime string `json:"start_time"` // 开始时间
EndTime string `json:"end_time"` // 结束时间
CanRenew bool `json:"can_renew"` // 是否可续约
}
type StakeNftList struct {
RoleId uint64 `json:"role_id,optional"` // 角色id
TokenIds []string `json:"token_ids"` // nft列表
}
type StakePointReq struct {
RoleID int64 `json:"role_id"` // 角色id
LevelId int `json:"level_id"` // 档位id
Action int `json:"action"` // 操作类型1表示质押2表示升级质押 3表示续约
}
type StakeReward struct {
Date string `json:"date"` // 日期
Reward float64 `json:"reward"` // 当日发放奖励