refactor: 粮草版,添加称号,精英单位。
parent
93ecc6b393
commit
f5f2bc166f
@ -0,0 +1,5 @@
|
||||
protoc --go_opt=paths=source_relative ^
|
||||
--go-grpc_opt=paths=source_relative ^
|
||||
--go-grpc_opt=require_unimplemented_servers=false ^
|
||||
--go_out=. --go-grpc_out=. --proto_path=. ^
|
||||
./vars/*.proto ./mq/*.proto
|
@ -1 +0,0 @@
|
||||
protoc --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative --go-grpc_opt=require_unimplemented_servers=false --go_out=. --go-grpc_out=. --proto_path=. mq.proto
|
@ -0,0 +1,312 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.19.4
|
||||
// source: vars/vars.proto
|
||||
|
||||
package pbVars
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type UserCoinChangedReason int32
|
||||
|
||||
const (
|
||||
///// 消费
|
||||
UserCoinChangedReason_Pay UserCoinChangedReason = 0 // 通用消费
|
||||
UserCoinChangedReason_BuyBattleFood UserCoinChangedReason = 1 // 购买粮草
|
||||
UserCoinChangedReason_BuyEliteUnit UserCoinChangedReason = 2 // 购买精英单位
|
||||
UserCoinChangedReason_BuyTitle UserCoinChangedReason = 3 // 购买称号
|
||||
///// 礼物
|
||||
UserCoinChangedReason_SendGift UserCoinChangedReason = 4 // 赠送礼物
|
||||
UserCoinChangedReason_BuyNobility UserCoinChangedReason = 5 // 购买贵族
|
||||
///// 领取
|
||||
UserCoinChangedReason_DrawGiftPack UserCoinChangedReason = 10 // 领取礼包
|
||||
UserCoinChangedReason_CheckIn UserCoinChangedReason = 11 // 签到打卡
|
||||
///// 游戏事件
|
||||
UserCoinChangedReason_EventRankSubmit UserCoinChangedReason = 20 // 排行榜结算变动
|
||||
UserCoinChangedReason_EventBattleEnd UserCoinChangedReason = 21 // 战局结束奖励
|
||||
///// 其它事件
|
||||
UserCoinChangedReason_Transfer UserCoinChangedReason = 30 // 转账
|
||||
)
|
||||
|
||||
// Enum value maps for UserCoinChangedReason.
|
||||
var (
|
||||
UserCoinChangedReason_name = map[int32]string{
|
||||
0: "Pay",
|
||||
1: "BuyBattleFood",
|
||||
2: "BuyEliteUnit",
|
||||
3: "BuyTitle",
|
||||
4: "SendGift",
|
||||
5: "BuyNobility",
|
||||
10: "DrawGiftPack",
|
||||
11: "CheckIn",
|
||||
20: "EventRankSubmit",
|
||||
21: "EventBattleEnd",
|
||||
30: "Transfer",
|
||||
}
|
||||
UserCoinChangedReason_value = map[string]int32{
|
||||
"Pay": 0,
|
||||
"BuyBattleFood": 1,
|
||||
"BuyEliteUnit": 2,
|
||||
"BuyTitle": 3,
|
||||
"SendGift": 4,
|
||||
"BuyNobility": 5,
|
||||
"DrawGiftPack": 10,
|
||||
"CheckIn": 11,
|
||||
"EventRankSubmit": 20,
|
||||
"EventBattleEnd": 21,
|
||||
"Transfer": 30,
|
||||
}
|
||||
)
|
||||
|
||||
func (x UserCoinChangedReason) Enum() *UserCoinChangedReason {
|
||||
p := new(UserCoinChangedReason)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x UserCoinChangedReason) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (UserCoinChangedReason) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_vars_vars_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (UserCoinChangedReason) Type() protoreflect.EnumType {
|
||||
return &file_vars_vars_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x UserCoinChangedReason) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use UserCoinChangedReason.Descriptor instead.
|
||||
func (UserCoinChangedReason) EnumDescriptor() ([]byte, []int) {
|
||||
return file_vars_vars_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type Goods int32
|
||||
|
||||
const (
|
||||
Goods_Title Goods = 0 // 称号
|
||||
Goods_Elite Goods = 1 // 精英单位
|
||||
)
|
||||
|
||||
// Enum value maps for Goods.
|
||||
var (
|
||||
Goods_name = map[int32]string{
|
||||
0: "Title",
|
||||
1: "Elite",
|
||||
}
|
||||
Goods_value = map[string]int32{
|
||||
"Title": 0,
|
||||
"Elite": 1,
|
||||
}
|
||||
)
|
||||
|
||||
func (x Goods) Enum() *Goods {
|
||||
p := new(Goods)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x Goods) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (Goods) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_vars_vars_proto_enumTypes[1].Descriptor()
|
||||
}
|
||||
|
||||
func (Goods) Type() protoreflect.EnumType {
|
||||
return &file_vars_vars_proto_enumTypes[1]
|
||||
}
|
||||
|
||||
func (x Goods) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Goods.Descriptor instead.
|
||||
func (Goods) EnumDescriptor() ([]byte, []int) {
|
||||
return file_vars_vars_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
type RankType int32
|
||||
|
||||
const (
|
||||
RankType_Unknown RankType = 0
|
||||
RankType_Damage RankType = 1 // 伤害榜
|
||||
RankType_DeDamage RankType = 2 // 受伤榜
|
||||
RankType_General RankType = 3 // 名将榜
|
||||
RankType_DeGeneral RankType = 4 // 落马榜
|
||||
RankType_KillUnit RankType = 5 // 小兵击杀
|
||||
RankType_DeKillUnit RankType = 6 // 小兵被杀
|
||||
RankType_KillPlayer RankType = 7 // 击杀玩家
|
||||
RankType_DeKillPlayer RankType = 8 // 被杀榜
|
||||
RankType_Win RankType = 9 // 获胜榜
|
||||
RankType_Lost RankType = 10 // 战败榜
|
||||
RankType_FirstBlood RankType = 11 // 一血榜
|
||||
RankType_DeFirstBlood RankType = 12 // 被拿一血榜
|
||||
)
|
||||
|
||||
// Enum value maps for RankType.
|
||||
var (
|
||||
RankType_name = map[int32]string{
|
||||
0: "Unknown",
|
||||
1: "Damage",
|
||||
2: "DeDamage",
|
||||
3: "General",
|
||||
4: "DeGeneral",
|
||||
5: "KillUnit",
|
||||
6: "DeKillUnit",
|
||||
7: "KillPlayer",
|
||||
8: "DeKillPlayer",
|
||||
9: "Win",
|
||||
10: "Lost",
|
||||
11: "FirstBlood",
|
||||
12: "DeFirstBlood",
|
||||
}
|
||||
RankType_value = map[string]int32{
|
||||
"Unknown": 0,
|
||||
"Damage": 1,
|
||||
"DeDamage": 2,
|
||||
"General": 3,
|
||||
"DeGeneral": 4,
|
||||
"KillUnit": 5,
|
||||
"DeKillUnit": 6,
|
||||
"KillPlayer": 7,
|
||||
"DeKillPlayer": 8,
|
||||
"Win": 9,
|
||||
"Lost": 10,
|
||||
"FirstBlood": 11,
|
||||
"DeFirstBlood": 12,
|
||||
}
|
||||
)
|
||||
|
||||
func (x RankType) Enum() *RankType {
|
||||
p := new(RankType)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x RankType) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (RankType) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_vars_vars_proto_enumTypes[2].Descriptor()
|
||||
}
|
||||
|
||||
func (RankType) Type() protoreflect.EnumType {
|
||||
return &file_vars_vars_proto_enumTypes[2]
|
||||
}
|
||||
|
||||
func (x RankType) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use RankType.Descriptor instead.
|
||||
func (RankType) EnumDescriptor() ([]byte, []int) {
|
||||
return file_vars_vars_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
var File_vars_vars_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_vars_vars_proto_rawDesc = []byte{
|
||||
0x0a, 0x0f, 0x76, 0x61, 0x72, 0x73, 0x2f, 0x76, 0x61, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x12, 0x07, 0x70, 0x62, 0x2e, 0x76, 0x61, 0x72, 0x73, 0x2a, 0xc8, 0x01, 0x0a, 0x15, 0x55,
|
||||
0x73, 0x65, 0x72, 0x43, 0x6f, 0x69, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x52, 0x65,
|
||||
0x61, 0x73, 0x6f, 0x6e, 0x12, 0x07, 0x0a, 0x03, 0x50, 0x61, 0x79, 0x10, 0x00, 0x12, 0x11, 0x0a,
|
||||
0x0d, 0x42, 0x75, 0x79, 0x42, 0x61, 0x74, 0x74, 0x6c, 0x65, 0x46, 0x6f, 0x6f, 0x64, 0x10, 0x01,
|
||||
0x12, 0x10, 0x0a, 0x0c, 0x42, 0x75, 0x79, 0x45, 0x6c, 0x69, 0x74, 0x65, 0x55, 0x6e, 0x69, 0x74,
|
||||
0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x42, 0x75, 0x79, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x10, 0x03,
|
||||
0x12, 0x0c, 0x0a, 0x08, 0x53, 0x65, 0x6e, 0x64, 0x47, 0x69, 0x66, 0x74, 0x10, 0x04, 0x12, 0x0f,
|
||||
0x0a, 0x0b, 0x42, 0x75, 0x79, 0x4e, 0x6f, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x10, 0x05, 0x12,
|
||||
0x10, 0x0a, 0x0c, 0x44, 0x72, 0x61, 0x77, 0x47, 0x69, 0x66, 0x74, 0x50, 0x61, 0x63, 0x6b, 0x10,
|
||||
0x0a, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x6e, 0x10, 0x0b, 0x12, 0x13,
|
||||
0x0a, 0x0f, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x61, 0x6e, 0x6b, 0x53, 0x75, 0x62, 0x6d, 0x69,
|
||||
0x74, 0x10, 0x14, 0x12, 0x12, 0x0a, 0x0e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x74, 0x74,
|
||||
0x6c, 0x65, 0x45, 0x6e, 0x64, 0x10, 0x15, 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x72, 0x61, 0x6e, 0x73,
|
||||
0x66, 0x65, 0x72, 0x10, 0x1e, 0x2a, 0x1d, 0x0a, 0x05, 0x47, 0x6f, 0x6f, 0x64, 0x73, 0x12, 0x09,
|
||||
0x0a, 0x05, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x6c, 0x69,
|
||||
0x74, 0x65, 0x10, 0x01, 0x2a, 0xc2, 0x01, 0x0a, 0x08, 0x52, 0x61, 0x6e, 0x6b, 0x54, 0x79, 0x70,
|
||||
0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x0a,
|
||||
0x0a, 0x06, 0x44, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x65,
|
||||
0x44, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x47, 0x65, 0x6e, 0x65,
|
||||
0x72, 0x61, 0x6c, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x44, 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72,
|
||||
0x61, 0x6c, 0x10, 0x04, 0x12, 0x0c, 0x0a, 0x08, 0x4b, 0x69, 0x6c, 0x6c, 0x55, 0x6e, 0x69, 0x74,
|
||||
0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x65, 0x4b, 0x69, 0x6c, 0x6c, 0x55, 0x6e, 0x69, 0x74,
|
||||
0x10, 0x06, 0x12, 0x0e, 0x0a, 0x0a, 0x4b, 0x69, 0x6c, 0x6c, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72,
|
||||
0x10, 0x07, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x65, 0x4b, 0x69, 0x6c, 0x6c, 0x50, 0x6c, 0x61, 0x79,
|
||||
0x65, 0x72, 0x10, 0x08, 0x12, 0x07, 0x0a, 0x03, 0x57, 0x69, 0x6e, 0x10, 0x09, 0x12, 0x08, 0x0a,
|
||||
0x04, 0x4c, 0x6f, 0x73, 0x74, 0x10, 0x0a, 0x12, 0x0e, 0x0a, 0x0a, 0x46, 0x69, 0x72, 0x73, 0x74,
|
||||
0x42, 0x6c, 0x6f, 0x6f, 0x64, 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x65, 0x46, 0x69, 0x72,
|
||||
0x73, 0x74, 0x42, 0x6c, 0x6f, 0x6f, 0x64, 0x10, 0x0c, 0x42, 0x21, 0x5a, 0x1f, 0x6c, 0x69, 0x76,
|
||||
0x65, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x70, 0x62,
|
||||
0x2f, 0x76, 0x61, 0x72, 0x73, 0x3b, 0x70, 0x62, 0x56, 0x61, 0x72, 0x73, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_vars_vars_proto_rawDescOnce sync.Once
|
||||
file_vars_vars_proto_rawDescData = file_vars_vars_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_vars_vars_proto_rawDescGZIP() []byte {
|
||||
file_vars_vars_proto_rawDescOnce.Do(func() {
|
||||
file_vars_vars_proto_rawDescData = protoimpl.X.CompressGZIP(file_vars_vars_proto_rawDescData)
|
||||
})
|
||||
return file_vars_vars_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_vars_vars_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
|
||||
var file_vars_vars_proto_goTypes = []interface{}{
|
||||
(UserCoinChangedReason)(0), // 0: pb.vars.UserCoinChangedReason
|
||||
(Goods)(0), // 1: pb.vars.Goods
|
||||
(RankType)(0), // 2: pb.vars.RankType
|
||||
}
|
||||
var file_vars_vars_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_vars_vars_proto_init() }
|
||||
func file_vars_vars_proto_init() {
|
||||
if File_vars_vars_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_vars_vars_proto_rawDesc,
|
||||
NumEnums: 3,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_vars_vars_proto_goTypes,
|
||||
DependencyIndexes: file_vars_vars_proto_depIdxs,
|
||||
EnumInfos: file_vars_vars_proto_enumTypes,
|
||||
}.Build()
|
||||
File_vars_vars_proto = out.File
|
||||
file_vars_vars_proto_rawDesc = nil
|
||||
file_vars_vars_proto_goTypes = nil
|
||||
file_vars_vars_proto_depIdxs = nil
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package pb.vars;
|
||||
|
||||
option go_package = "live-service/app/pb/vars;pbVars";
|
||||
|
||||
enum UserCoinChangedReason {
|
||||
///// 消费
|
||||
Pay = 0; // 通用消费
|
||||
BuyBattleFood = 1; // 购买粮草
|
||||
BuyEliteUnit = 2; // 购买精英单位
|
||||
BuyTitle = 3; // 购买称号
|
||||
///// 礼物
|
||||
SendGift = 4; // 赠送礼物
|
||||
BuyNobility = 5; // 购买贵族
|
||||
///// 领取
|
||||
DrawGiftPack = 10; // 领取礼包
|
||||
CheckIn = 11; // 签到打卡
|
||||
///// 游戏事件
|
||||
EventRankSubmit = 20; // 排行榜结算变动
|
||||
EventBattleEnd = 21; // 战局结束奖励
|
||||
///// 其它事件
|
||||
Transfer = 30; // 转账
|
||||
}
|
||||
|
||||
enum Goods {
|
||||
Title = 0; // 称号
|
||||
Elite = 1; // 精英单位
|
||||
}
|
||||
|
||||
enum RankType {
|
||||
Unknown = 0;
|
||||
Damage = 1; // 伤害榜
|
||||
DeDamage = 2; // 受伤榜
|
||||
General = 3; // 名将榜
|
||||
DeGeneral = 4; // 落马榜
|
||||
KillUnit = 5; // 小兵击杀
|
||||
DeKillUnit = 6; // 小兵被杀
|
||||
KillPlayer = 7; // 击杀玩家
|
||||
DeKillPlayer = 8; // 被杀榜
|
||||
Win = 9; // 获胜榜
|
||||
Lost = 10; // 战败榜
|
||||
FirstBlood = 11; // 一血榜
|
||||
DeFirstBlood = 12; // 被拿一血榜
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.noahlan.cn/northlan/ntools-go/gorm-zero/gormx"
|
||||
"git.noahlan.cn/northlan/ntools-go/uuid"
|
||||
"github.com/jinzhu/now"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
"live-service/common/nerr"
|
||||
"live-service/common/timex"
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ UserEliteModel = (*customUserEliteModel)(nil)
|
||||
|
||||
type (
|
||||
// UserEliteModel is an interface to be customized, add more methods here,
|
||||
// and implement the added methods in customUserEliteModel.
|
||||
UserEliteModel interface {
|
||||
userEliteModel
|
||||
// FindMaxSort 寻找当前用户精英单位的最大Sort 最小值2
|
||||
FindMaxSort(ctx context.Context, tx *gorm.DB, userId int64) int64
|
||||
// FindOneByUserIdSort 通过用户和排序号找寻精英单位
|
||||
FindOneByUserIdSort(ctx context.Context, tx *gorm.DB, userId int64, sort int64) (*UserElite, error)
|
||||
// FindByUserId 查找用户所有列表,按sort升序排列
|
||||
FindByUserId(ctx context.Context, tx *gorm.DB, userId int64) ([]UserElite, error)
|
||||
// Addon 添加新的或延长时间
|
||||
Addon(ctx context.Context, tx *gorm.DB, userId, eliteId int64, duration time.Duration, forever bool) error
|
||||
}
|
||||
|
||||
customUserEliteModel struct {
|
||||
*defaultUserEliteModel
|
||||
}
|
||||
)
|
||||
|
||||
// NewUserEliteModel returns a model for the database table.
|
||||
func NewUserEliteModel(conn *gorm.DB) UserEliteModel {
|
||||
return &customUserEliteModel{
|
||||
defaultUserEliteModel: newUserEliteModel(conn),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *customUserEliteModel) FindMaxSort(ctx context.Context, tx *gorm.DB, userId int64) int64 {
|
||||
db := gormx.WithTx(ctx, m.DB, tx)
|
||||
var resp int64 = 1
|
||||
|
||||
db.Table(m.table).
|
||||
Select("MAX(sort)").
|
||||
Where("user_id = ?", userId).
|
||||
Where("end_time > ?", now.BeginningOfDay()).Take(&resp)
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
func (m *customUserEliteModel) FindOneByUserIdSort(ctx context.Context, tx *gorm.DB, userId int64, sort int64) (*UserElite, error) {
|
||||
db := gormx.WithTx(ctx, m.DB, tx)
|
||||
var resp UserElite
|
||||
err := db.Model(&UserElite{}).
|
||||
Where("user_id = ? and sort = ?", userId, sort).Take(&resp).Error
|
||||
err = gormx.WrapSelectErr(err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (m *customUserEliteModel) FindByUserId(ctx context.Context, tx *gorm.DB, userId int64) ([]UserElite, error) {
|
||||
var resp []UserElite
|
||||
err := gormx.WithTx(ctx, m.DB, tx).Table(m.table).
|
||||
Where("user_id = ?", userId).
|
||||
Order("sort asc").Find(&resp).Error
|
||||
err = gormx.WrapSelectErr(err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (m *customUserEliteModel) Addon(ctx context.Context, tx *gorm.DB, userId, eliteId int64, duration time.Duration, forever bool) error {
|
||||
return m.TransactCtx(ctx, tx, func(tx *gorm.DB) error {
|
||||
userElite, err := m.FindOneByUserIdEliteId(ctx, tx, userId, eliteId)
|
||||
if err != nil {
|
||||
if !errors.Is(err, gormx.ErrNotFound) {
|
||||
return nerr.NewWithCode(nerr.DBError)
|
||||
}
|
||||
}
|
||||
today := now.BeginningOfDay()
|
||||
|
||||
if userElite == nil {
|
||||
// sort
|
||||
maxSort := m.FindMaxSort(ctx, tx, userId)
|
||||
err = m.Insert(ctx, tx, &UserElite{
|
||||
Id: uuid.NextId(),
|
||||
UserId: userId,
|
||||
EliteId: eliteId,
|
||||
Sort: maxSort + 1,
|
||||
Forever: BitBool(forever),
|
||||
StartTime: today,
|
||||
EndTime: today.Add(duration),
|
||||
})
|
||||
if err != nil {
|
||||
return nerr.NewWithCode(nerr.DBError)
|
||||
}
|
||||
} else {
|
||||
// update
|
||||
if !timex.DayExpire(today, userElite.EndTime, bool(userElite.Forever)) {
|
||||
// 未过期,endTime直接添加1day
|
||||
userElite.EndTime = userElite.EndTime.Add(duration)
|
||||
err = m.Update(ctx, tx, userElite)
|
||||
if err != nil {
|
||||
return nerr.NewWithCode(nerr.DBError)
|
||||
}
|
||||
} else {
|
||||
// 过期,更新日期
|
||||
err = m.Update(ctx, tx, &UserElite{
|
||||
Id: userElite.Id,
|
||||
UserId: userId,
|
||||
EliteId: eliteId,
|
||||
Sort: userElite.Sort,
|
||||
Forever: BitBool(forever),
|
||||
StartTime: today,
|
||||
EndTime: today.Add(duration),
|
||||
})
|
||||
if err != nil {
|
||||
return nerr.NewWithCode(nerr.DBError)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
// Code generated by goctl. DO NOT EDIT!
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.noahlan.cn/northlan/ntools-go/gorm-zero/gormx"
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var (
|
||||
userEliteFieldNames = builder.RawFieldNames(&UserElite{})
|
||||
userEliteRows = strings.Join(userEliteFieldNames, ",")
|
||||
userEliteRowsExpectAutoSet = strings.Join(stringx.Remove(userEliteFieldNames, "`create_time`", "`update_time`"), ",")
|
||||
userEliteRowsWithPlaceHolder = strings.Join(stringx.Remove(userEliteFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?"
|
||||
)
|
||||
|
||||
type (
|
||||
userEliteModel interface {
|
||||
gormx.TxModel
|
||||
Insert(ctx context.Context, tx *gorm.DB, data *UserElite) error
|
||||
FindOne(ctx context.Context, tx *gorm.DB, id int64) (*UserElite, error)
|
||||
FindOneByUserIdEliteId(ctx context.Context, tx *gorm.DB, userId int64, eliteId int64) (*UserElite, error)
|
||||
Update(ctx context.Context, tx *gorm.DB, data *UserElite) error
|
||||
Delete(ctx context.Context, tx *gorm.DB, id int64) error
|
||||
}
|
||||
|
||||
defaultUserEliteModel struct {
|
||||
gormx.GormConn
|
||||
table string
|
||||
}
|
||||
|
||||
UserElite struct {
|
||||
Id int64 `gorm:"column:id;primaryKey"` // 主键ID
|
||||
UserId int64 `gorm:"column:user_id"` // 用户ID
|
||||
EliteId int64 `gorm:"column:elite_id"` // 精英单位ID
|
||||
Sort int64 `gorm:"column:sort"` // 排序号
|
||||
Forever BitBool `gorm:"forever"` // 永久
|
||||
StartTime time.Time `gorm:"column:start_time;default:null"` // 开始时间
|
||||
EndTime time.Time `gorm:"column:end_time;default:null"` // 结束时间
|
||||
}
|
||||
)
|
||||
|
||||
var UserEliteTableName = "`user_elite`"
|
||||
|
||||
func newUserEliteModel(conn *gorm.DB) *defaultUserEliteModel {
|
||||
return &defaultUserEliteModel{
|
||||
GormConn: gormx.NewConn(conn),
|
||||
table: UserEliteTableName,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultUserEliteModel) Insert(ctx context.Context, tx *gorm.DB, data *UserElite) error {
|
||||
err := gormx.WithTx(ctx, m.DB, tx).Create(&data).Error
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultUserEliteModel) FindOne(ctx context.Context, tx *gorm.DB, id int64) (*UserElite, error) {
|
||||
var resp UserElite
|
||||
err := gormx.WithTx(ctx, m.DB, tx).Model(&UserElite{}).Where("`id` = ?", id).Take(&resp).Error
|
||||
if err = gormx.WrapSelectErr(err); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (m *defaultUserEliteModel) FindOneByUserIdEliteId(ctx context.Context, tx *gorm.DB, userId int64, eliteId int64) (*UserElite, error) {
|
||||
var resp UserElite
|
||||
err := gormx.WithTx(ctx, m.DB, tx).Model(&UserElite{}).Where("`user_id` = ? and `elite_id` = ?", userId, eliteId).Take(&resp).Error
|
||||
if err = gormx.WrapSelectErr(err); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (m *defaultUserEliteModel) Update(ctx context.Context, tx *gorm.DB, data *UserElite) error {
|
||||
|
||||
result := gormx.WithTx(ctx, m.DB, tx).Save(data)
|
||||
return gormx.WrapUpdateErr(result.Error, result.RowsAffected)
|
||||
|
||||
}
|
||||
|
||||
func (m *defaultUserEliteModel) Delete(ctx context.Context, tx *gorm.DB, id int64) error {
|
||||
err := gormx.WithTx(ctx, m.DB, tx).Delete(&UserElite{}, id).Error
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultUserEliteModel) tableName() string {
|
||||
return m.table
|
||||
}
|
||||
|
||||
func (UserElite) TableName() string {
|
||||
return UserEliteTableName
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.noahlan.cn/northlan/ntools-go/gorm-zero/gormx"
|
||||
"git.noahlan.cn/northlan/ntools-go/uuid"
|
||||
"github.com/jinzhu/now"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
"live-service/common/nerr"
|
||||
"live-service/common/timex"
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ UserTitleModel = (*customUserTitleModel)(nil)
|
||||
|
||||
const (
|
||||
TitleTypeDefault = "default" // 默认类型 可购买
|
||||
TitleTypeRank = "rank" // 排行榜类型 不可购买
|
||||
TitleTypeCustom = "custom" // 自定义类型 不可购买
|
||||
)
|
||||
|
||||
type (
|
||||
// UserTitleModel is an interface to be customized, add more methods here,
|
||||
// and implement the added methods in customUserTitleModel.
|
||||
UserTitleModel interface {
|
||||
userTitleModel
|
||||
// FindMaxSort 寻找当前用户的最大Sort 最小值2
|
||||
FindMaxSort(ctx context.Context, tx *gorm.DB, userId int64) int64
|
||||
// FindOneByUserIdSort 通过用户和排序号找寻称号
|
||||
FindOneByUserIdSort(ctx context.Context, tx *gorm.DB, userId int64, sort int64) (*UserTitle, error)
|
||||
// FindByUserId 查找用户所有列表,按sort升序排列
|
||||
FindByUserId(ctx context.Context, tx *gorm.DB, userId int64) ([]UserTitle, error)
|
||||
// Addon 添加新的或延长时间
|
||||
Addon(ctx context.Context, tx *gorm.DB, userId, titleId int64, titleType string, duration time.Duration, forever bool) error
|
||||
}
|
||||
|
||||
customUserTitleModel struct {
|
||||
*defaultUserTitleModel
|
||||
}
|
||||
)
|
||||
|
||||
// NewUserTitleModel returns a model for the database table.
|
||||
func NewUserTitleModel(conn *gorm.DB) UserTitleModel {
|
||||
return &customUserTitleModel{
|
||||
defaultUserTitleModel: newUserTitleModel(conn),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *customUserTitleModel) FindMaxSort(ctx context.Context, tx *gorm.DB, userId int64) int64 {
|
||||
db := gormx.WithTx(ctx, m.DB, tx)
|
||||
var resp int64 = 1
|
||||
|
||||
db.Table(m.table).
|
||||
Select("MAX(sort)").
|
||||
Where("user_id = ?", userId).
|
||||
Where("end_time > ?", now.BeginningOfDay()).Take(&resp)
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
func (m *customUserTitleModel) FindOneByUserIdSort(ctx context.Context, tx *gorm.DB, userId int64, sort int64) (*UserTitle, error) {
|
||||
db := gormx.WithTx(ctx, m.DB, tx)
|
||||
var resp UserTitle
|
||||
err := db.Model(&UserTitle{}).
|
||||
Where("user_id = ? and sort = ?", userId, sort).Take(&resp).Error
|
||||
err = gormx.WrapSelectErr(err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (m *customUserTitleModel) FindByUserId(ctx context.Context, tx *gorm.DB, userId int64) ([]UserTitle, error) {
|
||||
var resp []UserTitle
|
||||
err := gormx.WithTx(ctx, m.DB, tx).Table(m.table).
|
||||
Where("user_id = ?", userId).
|
||||
Order("sort asc").Find(&resp).Error
|
||||
err = gormx.WrapSelectErr(err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (m *customUserTitleModel) Addon(ctx context.Context, tx *gorm.DB, userId, titleId int64, titleType string, duration time.Duration, forever bool) error {
|
||||
return m.TransactCtx(ctx, tx, func(tx *gorm.DB) error {
|
||||
userTitle, err := m.FindOneByUserIdTitleId(ctx, tx, userId, titleId)
|
||||
if err != nil {
|
||||
if !errors.Is(err, gormx.ErrNotFound) {
|
||||
return nerr.NewWithCode(nerr.DBError)
|
||||
}
|
||||
}
|
||||
today := now.BeginningOfDay()
|
||||
|
||||
if userTitle == nil {
|
||||
// sort
|
||||
maxSort := m.FindMaxSort(ctx, tx, userId)
|
||||
err = m.Insert(ctx, tx, &UserTitle{
|
||||
Id: uuid.NextId(),
|
||||
UserId: userId,
|
||||
TitleId: titleId,
|
||||
Sort: maxSort + 1,
|
||||
Type: titleType,
|
||||
Forever: BitBool(forever),
|
||||
StartTime: today,
|
||||
EndTime: today.Add(duration),
|
||||
})
|
||||
if err != nil {
|
||||
return nerr.NewWithCode(nerr.DBError)
|
||||
}
|
||||
} else {
|
||||
// update
|
||||
if !timex.DayExpire(today, userTitle.EndTime, bool(userTitle.Forever)) {
|
||||
// 未过期,endTime直接添加1day
|
||||
userTitle.EndTime = userTitle.EndTime.Add(duration)
|
||||
err = m.Update(ctx, tx, userTitle)
|
||||
if err != nil {
|
||||
return nerr.NewWithCode(nerr.DBError)
|
||||
}
|
||||
} else {
|
||||
// 过期,更新日期
|
||||
err = m.Update(ctx, tx, &UserTitle{
|
||||
Id: userTitle.Id,
|
||||
UserId: userId,
|
||||
TitleId: titleId,
|
||||
Sort: userTitle.Sort,
|
||||
Type: titleType,
|
||||
Forever: BitBool(forever),
|
||||
StartTime: today,
|
||||
EndTime: today.Add(duration),
|
||||
})
|
||||
if err != nil {
|
||||
return nerr.NewWithCode(nerr.DBError)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
// Code generated by goctl. DO NOT EDIT!
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.noahlan.cn/northlan/ntools-go/gorm-zero/gormx"
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var (
|
||||
userTitleFieldNames = builder.RawFieldNames(&UserTitle{})
|
||||
userTitleRows = strings.Join(userTitleFieldNames, ",")
|
||||
userTitleRowsExpectAutoSet = strings.Join(stringx.Remove(userTitleFieldNames, "`create_time`", "`update_time`"), ",")
|
||||
userTitleRowsWithPlaceHolder = strings.Join(stringx.Remove(userTitleFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?"
|
||||
)
|
||||
|
||||
type (
|
||||
userTitleModel interface {
|
||||
gormx.TxModel
|
||||
Insert(ctx context.Context, tx *gorm.DB, data *UserTitle) error
|
||||
FindOne(ctx context.Context, tx *gorm.DB, id int64) (*UserTitle, error)
|
||||
FindOneByUserIdTitleId(ctx context.Context, tx *gorm.DB, userId int64, titleId int64) (*UserTitle, error)
|
||||
Update(ctx context.Context, tx *gorm.DB, data *UserTitle) error
|
||||
Delete(ctx context.Context, tx *gorm.DB, id int64) error
|
||||
}
|
||||
|
||||
defaultUserTitleModel struct {
|
||||
gormx.GormConn
|
||||
table string
|
||||
}
|
||||
|
||||
UserTitle struct {
|
||||
Id int64 `gorm:"column:id;primaryKey"` // 主键ID
|
||||
UserId int64 `gorm:"column:user_id"` // 用户ID
|
||||
TitleId int64 `gorm:"column:title_id"` // 称号ID
|
||||
Sort int64 `gorm:"column:sort"` // 排序号
|
||||
Type string `gorm:"type"` // 称号类型
|
||||
Forever BitBool `gorm:"forever"` // 永久
|
||||
StartTime time.Time `gorm:"column:start_time;default:null"` // 开始时间
|
||||
EndTime time.Time `gorm:"column:end_time;default:null"` // 结束时间
|
||||
}
|
||||
)
|
||||
|
||||
var UserTitleTableName = "`user_title`"
|
||||
|
||||
func newUserTitleModel(conn *gorm.DB) *defaultUserTitleModel {
|
||||
return &defaultUserTitleModel{
|
||||
GormConn: gormx.NewConn(conn),
|
||||
table: UserTitleTableName,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultUserTitleModel) Insert(ctx context.Context, tx *gorm.DB, data *UserTitle) error {
|
||||
err := gormx.WithTx(ctx, m.DB, tx).Create(&data).Error
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultUserTitleModel) FindOne(ctx context.Context, tx *gorm.DB, id int64) (*UserTitle, error) {
|
||||
var resp UserTitle
|
||||
err := gormx.WithTx(ctx, m.DB, tx).Model(&UserTitle{}).Where("`id` = ?", id).Take(&resp).Error
|
||||
if err = gormx.WrapSelectErr(err); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (m *defaultUserTitleModel) FindOneByUserIdTitleId(ctx context.Context, tx *gorm.DB, userId int64, titleId int64) (*UserTitle, error) {
|
||||
var resp UserTitle
|
||||
err := gormx.WithTx(ctx, m.DB, tx).Model(&UserTitle{}).Where("`user_id` = ? and `title_id` = ?", userId, titleId).Take(&resp).Error
|
||||
if err = gormx.WrapSelectErr(err); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (m *defaultUserTitleModel) Update(ctx context.Context, tx *gorm.DB, data *UserTitle) error {
|
||||
|
||||
result := gormx.WithTx(ctx, m.DB, tx).Save(data)
|
||||
return gormx.WrapUpdateErr(result.Error, result.RowsAffected)
|
||||
|
||||
}
|
||||
|
||||
func (m *defaultUserTitleModel) Delete(ctx context.Context, tx *gorm.DB, id int64) error {
|
||||
err := gormx.WithTx(ctx, m.DB, tx).Delete(&UserTitle{}, id).Error
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultUserTitleModel) tableName() string {
|
||||
return m.table
|
||||
}
|
||||
|
||||
func (UserTitle) TableName() string {
|
||||
return UserTitleTableName
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
// Code generated by goctl. DO NOT EDIT!
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"git.noahlan.cn/northlan/ntools-go/gorm-zero/gormx"
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var (
|
||||
zhgUserDetailsFieldNames = builder.RawFieldNames(&ZhgUserDetails{})
|
||||
zhgUserDetailsRows = strings.Join(zhgUserDetailsFieldNames, ",")
|
||||
zhgUserDetailsRowsExpectAutoSet = strings.Join(stringx.Remove(zhgUserDetailsFieldNames, "`create_time`", "`update_time`"), ",")
|
||||
zhgUserDetailsRowsWithPlaceHolder = strings.Join(stringx.Remove(zhgUserDetailsFieldNames, "`user_id`", "`create_time`", "`update_time`"), "=?,") + "=?"
|
||||
)
|
||||
|
||||
type (
|
||||
zhgUserDetailsModel interface {
|
||||
gormx.TxModel
|
||||
Insert(ctx context.Context, tx *gorm.DB, data *ZhgUserDetails) error
|
||||
FindOne(ctx context.Context, tx *gorm.DB, userId int64) (*ZhgUserDetails, error)
|
||||
Update(ctx context.Context, tx *gorm.DB, data *ZhgUserDetails) error
|
||||
Delete(ctx context.Context, tx *gorm.DB, userId int64) error
|
||||
}
|
||||
|
||||
defaultZhgUserDetailsModel struct {
|
||||
gormx.GormConn
|
||||
table string
|
||||
}
|
||||
|
||||
ZhgUserDetails struct {
|
||||
UserId int64 `gorm:"column:user_id;primaryKey"` // 用户ID
|
||||
Elite int64 `gorm:"column:elite"` // 当前使用的精英单位ID
|
||||
Title int64 `gorm:"column:title"` // 当前佩戴的称号ID
|
||||
}
|
||||
)
|
||||
|
||||
var ZhgUserDetailsTableName = "`zhg_user_details`"
|
||||
|
||||
func newZhgUserDetailsModel(conn *gorm.DB) *defaultZhgUserDetailsModel {
|
||||
return &defaultZhgUserDetailsModel{
|
||||
GormConn: gormx.NewConn(conn),
|
||||
table: ZhgUserDetailsTableName,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultZhgUserDetailsModel) Insert(ctx context.Context, tx *gorm.DB, data *ZhgUserDetails) error {
|
||||
err := gormx.WithTx(ctx, m.DB, tx).Create(&data).Error
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultZhgUserDetailsModel) FindOne(ctx context.Context, tx *gorm.DB, userId int64) (*ZhgUserDetails, error) {
|
||||
var resp ZhgUserDetails
|
||||
err := gormx.WithTx(ctx, m.DB, tx).Model(&ZhgUserDetails{}).Where("`user_id` = ?", userId).Take(&resp).Error
|
||||
if err = gormx.WrapSelectErr(err); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
func (m *defaultZhgUserDetailsModel) Update(ctx context.Context, tx *gorm.DB, data *ZhgUserDetails) error {
|
||||
|
||||
result := gormx.WithTx(ctx, m.DB, tx).Save(data)
|
||||
return gormx.WrapUpdateErr(result.Error, result.RowsAffected)
|
||||
|
||||
}
|
||||
|
||||
func (m *defaultZhgUserDetailsModel) Delete(ctx context.Context, tx *gorm.DB, userId int64) error {
|
||||
err := gormx.WithTx(ctx, m.DB, tx).Delete(&ZhgUserDetails{}, userId).Error
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultZhgUserDetailsModel) tableName() string {
|
||||
return m.table
|
||||
}
|
||||
|
||||
func (ZhgUserDetails) TableName() string {
|
||||
return ZhgUserDetailsTableName
|
||||
}
|
@ -0,0 +1,153 @@
|
||||
package coin_manager
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"gorm.io/gorm"
|
||||
pbMq "live-service/app/pb/mq"
|
||||
pbVars "live-service/app/pb/vars"
|
||||
"live-service/app/user_center/model"
|
||||
"live-service/app/user_center/rpc/internal/mq"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
"live-service/common/nerr"
|
||||
)
|
||||
|
||||
type (
|
||||
Manager struct {
|
||||
userCoinModel model.UserCoinModel
|
||||
userMq *mq.UserMq
|
||||
|
||||
logx.Logger
|
||||
}
|
||||
ChangeCoinReq struct {
|
||||
BattleId int64 // 战局ID
|
||||
UserId int64 // 用户ID
|
||||
Change int64 // 变化量(负数为减扣)
|
||||
}
|
||||
ChangeCoinResp struct {
|
||||
BattleId int64 // 战局ID
|
||||
UserId int64 // 用户ID
|
||||
Change int64 // 变化量(负数为减扣)
|
||||
Current int64 // 当前量
|
||||
}
|
||||
)
|
||||
|
||||
func NewCoinManager(mod model.UserCoinModel, userMq *mq.UserMq) *Manager {
|
||||
return &Manager{
|
||||
userCoinModel: mod,
|
||||
userMq: userMq,
|
||||
Logger: logx.WithContext(context.Background()),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) GetUserCoin(ctx context.Context, userId int64) (int64, error) {
|
||||
resp, err := m.userCoinModel.FindOne(ctx, nil, userId)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return resp.Coin, err
|
||||
}
|
||||
|
||||
func (m *Manager) TransferCoin(ctx context.Context, req *pb.TransferUserCoinReq) (*pb.TransferUserCoinResp, error) {
|
||||
if req.Transfer < 0 {
|
||||
req.Transfer = -req.Transfer
|
||||
}
|
||||
resp := &pb.TransferUserCoinResp{
|
||||
UserId: req.UserId,
|
||||
TargetUserId: req.TargetUserId,
|
||||
}
|
||||
if err := m.userCoinModel.TransactCtx(ctx, nil, func(tx *gorm.DB) error {
|
||||
if req.UserId == 0 {
|
||||
return nerr.NewError(nerr.RequestParamError, "源用户ID为空")
|
||||
}
|
||||
if req.TargetUserId == 0 {
|
||||
return nerr.NewError(nerr.RequestParamError, "目标用户ID为空")
|
||||
}
|
||||
coin, err := m.userCoinModel.ChangeCoin(ctx, tx, req.UserId, -req.Transfer)
|
||||
if err != nil {
|
||||
return nerr.NewWithErr(err)
|
||||
}
|
||||
targetCoin, err := m.userCoinModel.ChangeCoin(ctx, tx, req.TargetUserId, req.Transfer)
|
||||
if err != nil {
|
||||
return nerr.NewWithErr(err)
|
||||
}
|
||||
resp.UserCoin = coin
|
||||
resp.TargetUserCoin = targetCoin
|
||||
|
||||
// 通知
|
||||
go func() {
|
||||
m.userMq.NotifyUserCoinChanged(&pbMq.MqUserCoinChanged{
|
||||
UserId: req.UserId,
|
||||
Change: -req.Transfer,
|
||||
Current: coin,
|
||||
Reason: pbVars.UserCoinChangedReason_Transfer,
|
||||
})
|
||||
m.userMq.NotifyUserCoinChanged(&pbMq.MqUserCoinChanged{
|
||||
UserId: req.TargetUserId,
|
||||
Change: req.Transfer,
|
||||
Current: targetCoin,
|
||||
Reason: pbVars.UserCoinChangedReason_Transfer,
|
||||
})
|
||||
}()
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (m *Manager) ChangeCoin(ctx context.Context, tx *gorm.DB, req *ChangeCoinReq, reason pbVars.UserCoinChangedReason) (*ChangeCoinResp, error) {
|
||||
coin, err := m.userCoinModel.ChangeCoin(ctx, tx, req.UserId, req.Change)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 通知
|
||||
go m.userMq.NotifyUserCoinChanged(&pbMq.MqUserCoinChanged{
|
||||
UserId: req.UserId,
|
||||
Change: req.Change,
|
||||
Current: coin,
|
||||
Reason: reason,
|
||||
})
|
||||
|
||||
return &ChangeCoinResp{
|
||||
UserId: req.UserId,
|
||||
Change: req.Change,
|
||||
Current: coin,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *Manager) ChangeCoinBatch(ctx context.Context, req []ChangeCoinReq, reason pbVars.UserCoinChangedReason) (map[int64]ChangeCoinResp, error) {
|
||||
resp := make(map[int64]ChangeCoinResp)
|
||||
if err := m.userCoinModel.TransactCtx(ctx, nil, func(tx *gorm.DB) error {
|
||||
for _, item := range req {
|
||||
coin, err := m.userCoinModel.ChangeCoin(ctx, tx, item.UserId, item.Change)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp[item.UserId] = ChangeCoinResp{
|
||||
BattleId: item.BattleId,
|
||||
UserId: item.UserId,
|
||||
Change: item.Change,
|
||||
Current: coin,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
go func() {
|
||||
for _, coinResp := range resp {
|
||||
m.userMq.NotifyUserCoinChanged(&pbMq.MqUserCoinChanged{
|
||||
UserId: coinResp.UserId,
|
||||
Change: coinResp.Change,
|
||||
Current: coinResp.Current,
|
||||
Reason: reason,
|
||||
})
|
||||
}
|
||||
}()
|
||||
|
||||
return resp, nil
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
package integral_manager
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"gorm.io/gorm"
|
||||
"live-service/app/user_center/model"
|
||||
"live-service/app/user_center/rpc/internal/common/reward_pool"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
"live-service/common/nerr"
|
||||
)
|
||||
|
||||
type (
|
||||
Manager struct {
|
||||
cfg Config // 配置
|
||||
userIntegralModel model.UserIntegralModel
|
||||
rewardPoolManager *reward_pool.PoolManager
|
||||
|
||||
logx.Logger
|
||||
}
|
||||
Config struct {
|
||||
GiftRatio float64
|
||||
}
|
||||
ChangeIntegralReq struct {
|
||||
BattleId int64 // 战局ID
|
||||
UserId int64 // 用户ID
|
||||
Change int64 // 变化量(负数为减扣)
|
||||
Type pb.IntegralType // 积分类型
|
||||
}
|
||||
ChangeIntegralResp struct {
|
||||
BattleId int64 // 战局ID
|
||||
UserId int64 // 用户ID
|
||||
Change int64 // 变化量(负数为减扣)
|
||||
Integral int64 // 剩余积分
|
||||
}
|
||||
)
|
||||
|
||||
func NewIntegralManager(userIntegralModel model.UserIntegralModel, rewardPoolManager *reward_pool.PoolManager) *Manager {
|
||||
return &Manager{
|
||||
userIntegralModel: userIntegralModel,
|
||||
rewardPoolManager: rewardPoolManager,
|
||||
Logger: logx.WithContext(context.Background()),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) GetUserIntegral(ctx context.Context, userId int64) (int64, error) {
|
||||
resp, err := m.userIntegralModel.FindOne(ctx, nil, userId)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return resp.Integral, err
|
||||
}
|
||||
|
||||
func (m *Manager) TransferIntegral(ctx context.Context, req *pb.TransferUserIntegralReq) *pb.TransferUserIntegralResp {
|
||||
resp := &pb.TransferUserIntegralResp{
|
||||
UserId: req.UserId,
|
||||
TargetUserId: req.TargetUserId,
|
||||
}
|
||||
if err := m.userIntegralModel.TransactCtx(ctx, nil, func(tx *gorm.DB) error {
|
||||
if req.UserId == 0 {
|
||||
return nerr.NewError(nerr.RequestParamError, "源用户ID为空")
|
||||
}
|
||||
if req.TargetUserId == 0 {
|
||||
return nerr.NewError(nerr.RequestParamError, "目标用户ID为空")
|
||||
}
|
||||
integral, err := m.userIntegralModel.ChangeIntegral(ctx, tx, req.UserId, -req.Transfer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
targetIntegral, err := m.userIntegralModel.ChangeIntegral(ctx, tx, req.TargetUserId, req.Transfer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp.Code = int32(nerr.OK)
|
||||
resp.Msg = "转移成功"
|
||||
resp.UserIntegral = integral
|
||||
resp.TargetUserIntegral = targetIntegral
|
||||
return nil
|
||||
}); err != nil {
|
||||
if e, ok := err.(*nerr.Error); ok {
|
||||
resp.Code = int32(e.Code)
|
||||
resp.Msg = e.Msg
|
||||
} else {
|
||||
resp.Code = int32(nerr.ServerCommonError)
|
||||
resp.Msg = "转移失败,未知原因"
|
||||
}
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
func (m *Manager) ChangeIntegral(ctx context.Context, req *ChangeIntegralReq, rewardPool bool) (*ChangeIntegralResp, error) {
|
||||
integral, err := m.userIntegralModel.ChangeIntegral(ctx, nil, req.UserId, req.Change)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if req.BattleId != 0 && rewardPool {
|
||||
m.rewardPoolManager.Pool(req.BattleId).Add(req.UserId, req.Change, req.Type)
|
||||
}
|
||||
return &ChangeIntegralResp{
|
||||
UserId: req.UserId,
|
||||
Change: req.Change,
|
||||
Integral: integral,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *Manager) ChangeIntegralBatch(ctx context.Context, req []ChangeIntegralReq, rewardPool bool) (map[int64]ChangeIntegralResp, error) {
|
||||
resp := make(map[int64]ChangeIntegralResp)
|
||||
if err := m.userIntegralModel.TransactCtx(ctx, nil, func(tx *gorm.DB) error {
|
||||
for _, item := range req {
|
||||
integral, err := m.userIntegralModel.ChangeIntegral(ctx, tx, item.UserId, item.Change)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp[item.UserId] = ChangeIntegralResp{
|
||||
BattleId: item.BattleId,
|
||||
UserId: item.UserId,
|
||||
Change: item.Change,
|
||||
Integral: integral,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return resp, err
|
||||
}
|
||||
// 奖池
|
||||
for _, item := range req {
|
||||
if item.BattleId != 0 && rewardPool {
|
||||
m.rewardPoolManager.Pool(item.BattleId).Add(item.UserId, item.Change, item.Type)
|
||||
}
|
||||
}
|
||||
return resp, nil
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
package config
|
||||
|
||||
import "github.com/pkg/errors"
|
||||
|
||||
type (
|
||||
Elite struct {
|
||||
LiveDict map[int32]int64 // 直播间序号对应ID
|
||||
Default struct {
|
||||
Id int64
|
||||
Sort int32
|
||||
} // 默认
|
||||
Items []EliteItem
|
||||
}
|
||||
// EliteItem 精英单位
|
||||
EliteItem struct {
|
||||
Id int64 // 单位ID
|
||||
PriceDay int64 // 每天价格(弹币)
|
||||
PriceForever int64 // 永久价格
|
||||
}
|
||||
Title struct {
|
||||
LiveDict map[int32]int64 // 直播间序号对应ID
|
||||
Items []TitleItem
|
||||
}
|
||||
// TitleItem 称号
|
||||
TitleItem struct {
|
||||
Id int64 // 称号ID
|
||||
Name string // 称号名
|
||||
Type string // 称号类型
|
||||
RankType int32 // 作用的排行榜类型
|
||||
PriceDay int64 // 每天价格(弹币)
|
||||
PriceForever int64 // 永久价格(弹币)
|
||||
}
|
||||
GiftPack struct {
|
||||
PackType string // 礼包类型
|
||||
PackName string // 礼包名称
|
||||
// Condition 领取条件
|
||||
Condition struct {
|
||||
UserLimit int32 // 单人可领取数量
|
||||
UserResetType string // 用户礼包重置类型: 不重置(unset)|每天(daily)|每周(weekly)|每月(monthly)
|
||||
StartTime string // 可领取时间(开始) 两个时间相等则不限期领取
|
||||
EndTime string // 可领取时间(结束)
|
||||
}
|
||||
// Content 礼包内容
|
||||
Content struct {
|
||||
Coin int64 // 积分数
|
||||
Coins []int64 // 积分数(多次领取,每次不同)
|
||||
|
||||
// Title 奖励称号列表
|
||||
Title []struct {
|
||||
Id int64 // 称号ID
|
||||
Duration int64 // 持续时长,单位: 秒 -1无限
|
||||
}
|
||||
}
|
||||
}
|
||||
GameConfig struct {
|
||||
UserRetriever struct {
|
||||
Enabled bool // 是否开启
|
||||
UpdateDuration int64 // 用户信息更新最短间隔 单位 h
|
||||
NobilityPlatforms []string // 需要获取贵族的平台
|
||||
Cron struct {
|
||||
PlatformUser string
|
||||
Nobility string
|
||||
}
|
||||
Bilibili struct {
|
||||
RoomId int64 // 直播房间号
|
||||
Mid int64 // 主播UID 不输入就通过API获取
|
||||
RoomShortInfoApi string // 房间简短信息API
|
||||
TopListApi string
|
||||
}
|
||||
}
|
||||
Rank struct {
|
||||
Enabled bool // 是否开启
|
||||
Cron struct {
|
||||
Update string // 更新榜单
|
||||
Persistence string // 持久化
|
||||
}
|
||||
}
|
||||
GiftCollector struct {
|
||||
Enabled bool // 是否开启
|
||||
Platforms []string // 需搜集的平台
|
||||
Cron struct {
|
||||
CollectGift string
|
||||
}
|
||||
}
|
||||
// 弹币
|
||||
Coin struct {
|
||||
// CheckIn 签到
|
||||
CheckIn struct {
|
||||
Points []int64 // 签到积分 次数分数
|
||||
Critical float32 // 暴击率(百分比)
|
||||
CriticalRadio []float32 // 暴击倍数
|
||||
}
|
||||
RMBToCoin float64 // RMB到弹币的转换
|
||||
GiftToRMB map[string]float64 // 平台礼物到RMB的转换
|
||||
FreeToCoin map[string]float64 // 平台免费礼物到弹币的转换
|
||||
}
|
||||
// 精英单位
|
||||
Elite Elite
|
||||
// 称号
|
||||
Title Title
|
||||
// GiftPack 礼包配置
|
||||
GiftPackMap []GiftPack
|
||||
}
|
||||
)
|
||||
|
||||
func (c *Title) FindTitleCfg(id int64) (*TitleItem, error) {
|
||||
for _, item := range c.Items {
|
||||
if id == item.Id {
|
||||
return &item, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("未找到ID对应的称号配置")
|
||||
}
|
||||
|
||||
func (c *Title) FindTitleCfgByLive(sort int32) (*TitleItem, error) {
|
||||
if id, ok := c.LiveDict[sort]; ok {
|
||||
return c.FindTitleCfg(id)
|
||||
}
|
||||
return nil, errors.New("未找到sort对应的称号配置")
|
||||
}
|
||||
|
||||
func (c *Elite) FindEliteCfg(id int64) (*EliteItem, error) {
|
||||
for _, item := range c.Items {
|
||||
if id == item.Id {
|
||||
return &item, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("未找到ID对应的精英单位配置")
|
||||
}
|
||||
|
||||
func (c *Elite) FindEliteCfgByLive(sort int32) (*EliteItem, error) {
|
||||
if id, ok := c.LiveDict[sort]; ok {
|
||||
return c.FindEliteCfg(id)
|
||||
}
|
||||
return nil, errors.New("未找到sort对应的精英单位配置")
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package coin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/pkg/errors"
|
||||
"live-service/app/user_center/rpc/internal/common/coin_manager"
|
||||
"live-service/common/nerr"
|
||||
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ChangeCoinLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewChangeCoinLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ChangeCoinLogic {
|
||||
return &ChangeCoinLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
// changeCoin 新增或扣减用户弹币
|
||||
func (l *ChangeCoinLogic) ChangeCoin(in *pb.ChangeCoinReq) (*pb.Empty, error) {
|
||||
_, err := l.svcCtx.CoinManager.ChangeCoin(l.ctx, nil, &coin_manager.ChangeCoinReq{
|
||||
BattleId: in.BattleId,
|
||||
UserId: in.UserId,
|
||||
Change: in.Change,
|
||||
}, in.Reason)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(nerr.NewWithErr(err), "记录弹币失败, err:%+v", err)
|
||||
}
|
||||
|
||||
return &pb.Empty{}, nil
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package coin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/pkg/errors"
|
||||
"live-service/common/nerr"
|
||||
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetUserCoinLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewGetUserCoinLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserCoinLogic {
|
||||
return &GetUserCoinLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
// getUserCoin 获取用户弹币
|
||||
func (l *GetUserCoinLogic) GetUserCoin(in *pb.UserIdReq) (*pb.GetUserCoinResp, error) {
|
||||
// 查询当前用户积分
|
||||
coin, err := l.svcCtx.CoinManager.GetUserCoin(l.ctx, in.UserId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(nerr.NewWithCode(nerr.DBError), "查询用户弹币失败, err:%+v", err)
|
||||
}
|
||||
|
||||
return &pb.GetUserCoinResp{
|
||||
UserId: in.UserId,
|
||||
Current: coin,
|
||||
}, nil
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package coin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/pkg/errors"
|
||||
"live-service/common/nerr"
|
||||
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type TransferUserCoinLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewTransferUserCoinLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TransferUserCoinLogic {
|
||||
return &TransferUserCoinLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
// transferUserCoin 转移用户弹币
|
||||
func (l *TransferUserCoinLogic) TransferUserCoin(in *pb.TransferUserCoinReq) (*pb.TransferUserCoinResp, error) {
|
||||
transResp, err := l.svcCtx.CoinManager.TransferCoin(l.ctx, in)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(nerr.NewWithErr(err), "转移弹币失败")
|
||||
}
|
||||
// 获取 username
|
||||
if tmp, err := l.svcCtx.UserPlatformModel.FindDisplayOneByUserId(l.ctx, transResp.UserId); err == nil {
|
||||
transResp.Uname = tmp.PUname
|
||||
transResp.Avatar = tmp.PAvatar
|
||||
}
|
||||
if tmp, err := l.svcCtx.UserPlatformModel.FindDisplayOneByUserId(l.ctx, transResp.TargetUserId); err == nil {
|
||||
transResp.TargetUname = tmp.PUname
|
||||
transResp.TargetAvatar = tmp.PAvatar
|
||||
}
|
||||
return transResp, nil
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package draw_pool
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type IncreaseWelfareLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewIncreaseWelfareLogic(ctx context.Context, svcCtx *svc.ServiceContext) *IncreaseWelfareLogic {
|
||||
return &IncreaseWelfareLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *IncreaseWelfareLogic) IncreaseWelfare(in *pb.IncreaseWelfareReq) (*pb.Empty, error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return &pb.Empty{}, nil
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package integral
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/pkg/errors"
|
||||
"live-service/app/user_center/rpc/internal/common/integral_manager"
|
||||
"live-service/common/nerr"
|
||||
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ChangeIntegralLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewChangeIntegralLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ChangeIntegralLogic {
|
||||
return &ChangeIntegralLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
// ChangeIntegral 更改用户积分
|
||||
func (l *ChangeIntegralLogic) ChangeIntegral(in *pb.ChangeIntegralReq) (*pb.ChangeIntegralResp, error) {
|
||||
integral, err := l.svcCtx.IntegralManager.ChangeIntegral(l.ctx, &integral_manager.ChangeIntegralReq{
|
||||
BattleId: in.BattleId,
|
||||
UserId: in.UserId,
|
||||
Change: in.Change,
|
||||
Type: in.IntegralType,
|
||||
}, true)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(nerr.NewWithErr(err), "记录积分失败, err:%+v", err)
|
||||
}
|
||||
|
||||
return &pb.ChangeIntegralResp{
|
||||
UserId: in.UserId,
|
||||
Change: in.Change,
|
||||
Integral: integral.Integral,
|
||||
}, nil
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package integral
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/pkg/errors"
|
||||
"live-service/common/nerr"
|
||||
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetUserIntegralLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewGetUserIntegralLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserIntegralLogic {
|
||||
return &GetUserIntegralLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
// GetUserIntegral 获取用户积分
|
||||
func (l *GetUserIntegralLogic) GetUserIntegral(in *pb.UserIdReq) (*pb.UserIntegralResp, error) {
|
||||
// 查询当前用户积分
|
||||
integral, err := l.svcCtx.UserIntegralModel.FindOne(l.ctx, nil, in.UserId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(nerr.NewWithCode(nerr.DBError), "查询用户积分失败, err:%+v", err)
|
||||
}
|
||||
|
||||
return &pb.UserIntegralResp{
|
||||
UserId: in.UserId,
|
||||
Integral: integral.Integral,
|
||||
}, nil
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package integral
|
||||
|
||||
import (
|
||||
"context"
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
"live-service/common/nerr"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type TransferUserIntegralLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewTransferUserIntegralLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TransferUserIntegralLogic {
|
||||
return &TransferUserIntegralLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
// TransferUserIntegral 转移积分
|
||||
func (l *TransferUserIntegralLogic) TransferUserIntegral(in *pb.TransferUserIntegralReq) (*pb.TransferUserIntegralResp, error) {
|
||||
transResp := l.svcCtx.IntegralManager.TransferIntegral(l.ctx, in)
|
||||
if transResp.Code == int32(nerr.OK) {
|
||||
// 获取 username
|
||||
if tmp, err := l.svcCtx.UserPlatformModel.FindDisplayOneByUserId(l.ctx, transResp.UserId); err == nil {
|
||||
transResp.Uname = tmp.PUname
|
||||
transResp.Avatar = tmp.PAvatar
|
||||
}
|
||||
if tmp, err := l.svcCtx.UserPlatformModel.FindDisplayOneByUserId(l.ctx, transResp.TargetUserId); err == nil {
|
||||
transResp.TargetUname = tmp.PUname
|
||||
transResp.TargetAvatar = tmp.PAvatar
|
||||
}
|
||||
}
|
||||
return transResp, nil
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
package statistics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.noahlan.cn/northlan/ntools-go/gorm-zero/gormx"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
"live-service/app/user_center/model"
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
"live-service/common/nerr"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type StatPvpFirstBloodLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewStatPvpFirstBloodLogic(ctx context.Context, svcCtx *svc.ServiceContext) *StatPvpFirstBloodLogic {
|
||||
return &StatPvpFirstBloodLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
TypeFirstBlood = 1
|
||||
TypeDeFirstBlood = 2
|
||||
)
|
||||
|
||||
func (l *StatPvpFirstBloodLogic) StatPvpFirstBlood(in *pb.StatPvPFirstBloodReq) (*pb.Empty, error) {
|
||||
// 虚拟UID
|
||||
if in.Uid <= 0 {
|
||||
return &pb.Empty{}, nil
|
||||
}
|
||||
err := l.svcCtx.StatisticsPvpModel.TransactCtx(l.ctx, nil, func(tx *gorm.DB) error {
|
||||
// 直接更新,提高效率
|
||||
props := model.UpdateRecordProps{}
|
||||
if in.Type == TypeFirstBlood {
|
||||
props.FirstBlood = true
|
||||
} else if in.Type == TypeDeFirstBlood {
|
||||
props.DeFirstBlood = true
|
||||
}
|
||||
|
||||
if err := l.svcCtx.StatisticsPvpModel.UpdateRecord(l.ctx, tx, in.Uid,
|
||||
&props); err != nil {
|
||||
if errors.Is(err, gormx.ErrRowsAffectedZero) {
|
||||
// insert
|
||||
dbModel := model.StatisticsPvp{
|
||||
UserId: in.Uid,
|
||||
}
|
||||
if in.Type == TypeFirstBlood {
|
||||
dbModel.FirstBloodCount = 1
|
||||
} else if in.Type == TypeDeFirstBlood {
|
||||
dbModel.DeFirstBloodCount = 1
|
||||
}
|
||||
if err = l.svcCtx.StatisticsPvpModel.Insert(l.ctx, tx, &dbModel); err != nil {
|
||||
return errors.Wrapf(err, ErrInsertErr, err)
|
||||
}
|
||||
} else {
|
||||
return errors.Wrapf(err, ErrUpdateErr, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(nerr.NewWithCode(nerr.DBError), "一血报送-事务执行失败, err:%+v", err)
|
||||
}
|
||||
return &pb.Empty{}, nil
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
package statistics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.noahlan.cn/northlan/ntools-go/gorm-zero/gormx"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
"live-service/app/user_center/model"
|
||||
"live-service/common/nerr"
|
||||
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type StatPvpKillLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewStatPvpKillLogic(ctx context.Context, svcCtx *svc.ServiceContext) *StatPvpKillLogic {
|
||||
return &StatPvpKillLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *StatPvpKillLogic) StatPvpKill(in *pb.StatPvPKillReq) (*pb.Empty, error) {
|
||||
// 虚拟UID
|
||||
if in.Uid <= 0 {
|
||||
return &pb.Empty{}, nil
|
||||
}
|
||||
|
||||
err := l.svcCtx.StatisticsPvpModel.TransactCtx(l.ctx, nil, func(tx *gorm.DB) error {
|
||||
// 击杀
|
||||
props := model.UpdateRecordProps{
|
||||
KillPlayer: true,
|
||||
}
|
||||
if err := l.svcCtx.StatisticsPvpModel.UpdateRecord(l.ctx, tx, in.Uid, &props); err != nil {
|
||||
if errors.Is(err, gormx.ErrRowsAffectedZero) {
|
||||
dbModel := &model.StatisticsPvp{
|
||||
UserId: in.Uid,
|
||||
KillPlayerCount: 1,
|
||||
}
|
||||
if err := l.svcCtx.StatisticsPvpModel.Insert(l.ctx, tx, dbModel); err != nil {
|
||||
return errors.Wrapf(err, ErrInsertErr, err)
|
||||
}
|
||||
} else {
|
||||
return errors.Wrapf(err, ErrUpdateErr, err)
|
||||
}
|
||||
}
|
||||
// 被杀 + 落马否
|
||||
// 虚拟UID
|
||||
if in.TargetUid <= 0 {
|
||||
return nil
|
||||
}
|
||||
props = model.UpdateRecordProps{
|
||||
DeKillPlayer: true,
|
||||
DeGeneral: in.IsGeneral,
|
||||
}
|
||||
if err := l.svcCtx.StatisticsPvpModel.UpdateRecord(l.ctx, tx, in.TargetUid, &props); err != nil {
|
||||
if errors.Is(err, gormx.ErrRowsAffectedZero) {
|
||||
dbModel := &model.StatisticsPvp{
|
||||
UserId: in.TargetUid,
|
||||
DeKillUnitCount: 1,
|
||||
}
|
||||
if in.IsGeneral {
|
||||
dbModel.DeGeneralCount = 1
|
||||
}
|
||||
if err := l.svcCtx.StatisticsPvpModel.Insert(l.ctx, tx, dbModel); err != nil {
|
||||
return errors.Wrapf(err, ErrInsertErr, err)
|
||||
}
|
||||
} else {
|
||||
return errors.Wrapf(err, ErrUpdateErr, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(nerr.NewWithCode(nerr.DBError), "击杀玩家-事务执行失败, err:%+v", err)
|
||||
}
|
||||
return &pb.Empty{}, nil
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"gorm.io/gorm"
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
"live-service/common/timex"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetUserDetailsLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewGetUserDetailsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserDetailsLogic {
|
||||
return &GetUserDetailsLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
// getUserDetails 获取用户详细信息
|
||||
func (l *GetUserDetailsLogic) GetUserDetails(in *pb.UserIdReq) (*pb.UserDetailsResp, error) {
|
||||
resp := &pb.UserDetailsResp{
|
||||
UserId: in.UserId,
|
||||
}
|
||||
// 贵族
|
||||
var nobilityLevel int32
|
||||
if dbNobility, err := l.svcCtx.UserNobilityModel.FindOne(l.ctx, nil, in.UserId); err == nil {
|
||||
nobilityLevel = int32(dbNobility.NobilityLevel)
|
||||
// 判断过期
|
||||
if time.Now().After(dbNobility.EndTime) {
|
||||
if !dbNobility.Forever {
|
||||
nobilityLevel = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
resp.NobilityLevel = nobilityLevel
|
||||
// 金币
|
||||
var coin int64
|
||||
if dbCoin, err := l.svcCtx.CoinManager.GetUserCoin(l.ctx, in.UserId); err == nil {
|
||||
coin = dbCoin
|
||||
}
|
||||
resp.Coin = coin
|
||||
|
||||
nowTime := time.Now()
|
||||
// 当前佩戴 称号/精英单位
|
||||
var currentTitle pb.UserDetailsResp_TitleItem
|
||||
var currentElite pb.UserDetailsResp_EliteItem
|
||||
|
||||
_ = l.svcCtx.Db.Transaction(func(tx *gorm.DB) error {
|
||||
if zhgUserDetails, err := l.svcCtx.ZhgUserDetailsModel.FindOne(l.ctx, tx, in.UserId); err == nil {
|
||||
if dbTitle, err := l.svcCtx.UserTitleModel.FindOneByUserIdTitleId(l.ctx, tx, in.UserId, zhgUserDetails.Title); err == nil {
|
||||
if !timex.DayExpire(nowTime, dbTitle.EndTime, bool(dbTitle.Forever)) {
|
||||
var name string
|
||||
if cfg, err := l.svcCtx.GameConfig.Title.FindTitleCfg(dbTitle.TitleId); err == nil {
|
||||
name = cfg.Name
|
||||
}
|
||||
currentTitle = pb.UserDetailsResp_TitleItem{
|
||||
Id: dbTitle.TitleId,
|
||||
Name: name,
|
||||
Sort: int32(dbTitle.Sort),
|
||||
Remain: timex.DayRemain(nowTime, dbTitle.EndTime, bool(dbTitle.Forever)),
|
||||
}
|
||||
}
|
||||
}
|
||||
if dbElite, err := l.svcCtx.UserEliteModel.FindOneByUserIdEliteId(l.ctx, tx, in.UserId, zhgUserDetails.Elite); err == nil {
|
||||
if !timex.DayExpire(nowTime, dbElite.EndTime, bool(dbElite.Forever)) {
|
||||
currentElite = pb.UserDetailsResp_EliteItem{
|
||||
Id: dbElite.EliteId,
|
||||
Sort: int32(dbElite.Sort),
|
||||
Remain: timex.DayRemain(nowTime, dbElite.EndTime, bool(dbElite.Forever)),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
resp.CurrentTitle = ¤tTitle
|
||||
resp.CurrentElite = ¤tElite
|
||||
|
||||
// 拥有 称号/精英单位 列表
|
||||
elites := make([]*pb.UserDetailsResp_EliteItem, 0)
|
||||
if dbElites, err := l.svcCtx.UserEliteModel.FindByUserId(l.ctx, nil, in.UserId); err == nil {
|
||||
for _, item := range dbElites {
|
||||
if !timex.DayExpire(nowTime, item.EndTime, bool(item.Forever)) {
|
||||
elites = append(elites, &pb.UserDetailsResp_EliteItem{
|
||||
Id: item.EliteId,
|
||||
Sort: int32(item.Sort),
|
||||
Remain: timex.DayRemain(nowTime, item.EndTime, bool(item.Forever)),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
resp.Elites = elites
|
||||
|
||||
titles := make([]*pb.UserDetailsResp_TitleItem, 0)
|
||||
if dbTitles, err := l.svcCtx.UserTitleModel.FindByUserId(l.ctx, nil, in.UserId); err == nil {
|
||||
for _, item := range dbTitles {
|
||||
if !timex.DayExpire(nowTime, item.EndTime, bool(item.Forever)) {
|
||||
var name string
|
||||
if cfg, err := l.svcCtx.GameConfig.Title.FindTitleCfg(item.TitleId); err == nil {
|
||||
name = cfg.Name
|
||||
}
|
||||
titles = append(titles, &pb.UserDetailsResp_TitleItem{
|
||||
Id: item.TitleId,
|
||||
Name: name,
|
||||
Sort: int32(item.Sort),
|
||||
Remain: timex.DayRemain(nowTime, item.EndTime, bool(item.Forever)),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
resp.Titles = titles
|
||||
|
||||
return resp, nil
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package zhg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"gorm.io/gorm"
|
||||
pbVars "live-service/app/pb/vars"
|
||||
"live-service/app/user_center/rpc/internal/common/coin_manager"
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
"live-service/common/nerr"
|
||||
"time"
|
||||
)
|
||||
|
||||
type BuyEliteLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewBuyEliteLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BuyEliteLogic {
|
||||
return &BuyEliteLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *BuyEliteLogic) BuyElite(in *pb.EliteReq) (*pb.BuyEliteResp, error) {
|
||||
elite, err := l.svcCtx.GameConfig.Elite.FindEliteCfgByLive(in.Sort)
|
||||
if err != nil {
|
||||
// 待购买的精英单位不存在
|
||||
return nil, errors.Wrapf(nerr.NewError(nerr.EliteConfigNotFoundErr, err.Error()), err.Error())
|
||||
}
|
||||
resp := &pb.BuyEliteResp{
|
||||
UserId: in.UserId,
|
||||
EliteId: elite.Id,
|
||||
Cost: elite.PriceDay,
|
||||
Duration: 1,
|
||||
}
|
||||
if err = l.svcCtx.Db.Transaction(func(tx *gorm.DB) error {
|
||||
// 扣减弹币
|
||||
if _, err = l.svcCtx.CoinManager.ChangeCoin(l.ctx, tx, &coin_manager.ChangeCoinReq{
|
||||
UserId: in.UserId,
|
||||
Change: -elite.PriceDay,
|
||||
}, pbVars.UserCoinChangedReason_BuyEliteUnit); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = l.svcCtx.UserEliteModel.Addon(l.ctx, nil, in.UserId, elite.Id, 24*time.Hour, false); err != nil {
|
||||
return errors.Wrapf(nerr.NewWithErr(err), "兑换精英单位失败 err:%v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package zhg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
pbVars "live-service/app/pb/vars"
|
||||
"live-service/app/user_center/model"
|
||||
"live-service/app/user_center/rpc/internal/common/coin_manager"
|
||||
"live-service/common/nerr"
|
||||
"time"
|
||||
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type BuyTitleLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewBuyTitleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BuyTitleLogic {
|
||||
return &BuyTitleLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *BuyTitleLogic) BuyTitle(in *pb.TitleReq) (*pb.BuyTitleResp, error) {
|
||||
titleCfg, err := l.svcCtx.GameConfig.Title.FindTitleCfgByLive(in.Sort)
|
||||
if err != nil {
|
||||
return nil, nerr.NewError(nerr.TitleConfigNotFoundErr, err.Error())
|
||||
}
|
||||
if titleCfg.Type != model.TitleTypeDefault {
|
||||
return nil, nerr.NewError(nerr.TitleCannotBuyErr, "该称号禁止兑换")
|
||||
}
|
||||
|
||||
resp := &pb.BuyTitleResp{
|
||||
UserId: in.UserId,
|
||||
TitleId: titleCfg.Id,
|
||||
Name: titleCfg.Name,
|
||||
Cost: titleCfg.PriceDay,
|
||||
Duration: 1,
|
||||
}
|
||||
if err = l.svcCtx.Db.Transaction(func(tx *gorm.DB) error {
|
||||
// 扣减弹币
|
||||
if _, err = l.svcCtx.CoinManager.ChangeCoin(l.ctx, tx, &coin_manager.ChangeCoinReq{
|
||||
UserId: in.UserId,
|
||||
Change: -titleCfg.PriceDay,
|
||||
}, pbVars.UserCoinChangedReason_BuyEliteUnit); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = l.svcCtx.UserTitleModel.Addon(l.ctx, nil, in.UserId, titleCfg.Id, titleCfg.Type, 24*time.Hour, false); err != nil {
|
||||
return errors.Wrapf(nerr.NewWithErr(err), "兑换称号失败 err:%v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package zhg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"live-service/common/nerr"
|
||||
"time"
|
||||
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GiveEliteLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewGiveEliteLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GiveEliteLogic {
|
||||
return &GiveEliteLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GiveEliteLogic) GiveElite(in *pb.GiveEliteReq) (*pb.BuyEliteResp, error) {
|
||||
elite, err := l.svcCtx.GameConfig.Elite.FindEliteCfg(in.EliteId)
|
||||
if err != nil {
|
||||
return nil, nerr.NewError(nerr.EliteConfigNotFoundErr, err.Error())
|
||||
}
|
||||
|
||||
duration := in.Duration
|
||||
if in.Forever {
|
||||
duration = -1
|
||||
}
|
||||
resp := &pb.BuyEliteResp{
|
||||
UserId: in.UserId,
|
||||
EliteId: elite.Id,
|
||||
Cost: 0,
|
||||
Duration: duration,
|
||||
}
|
||||
if duration < 0 {
|
||||
duration = -duration
|
||||
} else if duration == 0 {
|
||||
duration = 1
|
||||
}
|
||||
err = l.svcCtx.UserEliteModel.Addon(l.ctx, nil, in.UserId, elite.Id, time.Duration(duration)*24*time.Hour, in.Forever)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package zhg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"live-service/common/nerr"
|
||||
"time"
|
||||
|
||||
"live-service/app/user_center/rpc/internal/svc"
|
||||
"live-service/app/user_center/rpc/pb"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GiveTitleLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewGiveTitleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GiveTitleLogic {
|
||||
return &GiveTitleLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GiveTitleLogic) GiveTitle(in *pb.GiveTitleReq) (*pb.BuyTitleResp, error) {
|
||||
cfg, err := l.svcCtx.GameConfig.Title.FindTitleCfg(in.TitleId)
|
||||
if err != nil {
|
||||
return nil, nerr.NewError(nerr.EliteConfigNotFoundErr, err.Error())
|
||||
}
|
||||
|
||||
duration := in.Duration
|
||||
if in.Forever {
|
||||
duration = -1
|
||||
}
|
||||
resp := &pb.BuyTitleResp{
|
||||
UserId: in.UserId,
|
||||
TitleId: cfg.Id,
|
||||
Name: cfg.Name,
|
||||
Cost: 0,
|
||||
Duration: duration,
|
||||
}
|
||||
if duration < 0 {
|
||||
duration = -duration
|
||||
} else if duration == 0 {
|
||||
duration = 1
|
||||
}
|
||||
err = l.svcCtx.UserTitleModel.Addon(l.ctx, nil, in.UserId, cfg.Id, cfg.Type, time.Duration(duration)*24*time.Hour, in.Forever)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package mq
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.noahlan.cn/northlan/ntools-go/kafka"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
pbMq "live-service/app/pb/mq"
|
||||
"live-service/app/user_center/rpc/internal/config"
|
||||
kfk "live-service/common/kafka"
|
||||
)
|
||||
|
||||
type (
|
||||
RewardPool struct {
|
||||
producer *kafka.Producer // kafka
|
||||
|
||||
logx.Logger
|
||||
}
|
||||
)
|
||||
|
||||
func NewRewardPoolMq(cfg config.KafkaProducer) *RewardPool {
|
||||
return &RewardPool{
|
||||
producer: kafka.NewKafkaProducer(kfk.DefaultProducerConfig, cfg.RewardPool.Addr, cfg.RewardPool.Topic),
|
||||
Logger: logx.WithContext(context.Background()),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *RewardPool) RewardPoolChanged(req *pbMq.MqRewardPool) {
|
||||
err := m.producer.SendMessageAsync(req)
|
||||
if err != nil {
|
||||
m.Logger.Error("发送通知奖池变更消息失败")
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package mq
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.noahlan.cn/northlan/ntools-go/kafka"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
pbMq "live-service/app/pb/mq"
|
||||
"live-service/app/user_center/model"
|
||||
"live-service/app/user_center/rpc/internal/config"
|
||||
kfk "live-service/common/kafka"
|
||||
)
|
||||
|
||||
type (
|
||||
UserMq struct {
|
||||
userPlatformModel model.UserPlatformModel
|
||||
coinChangedKfk *kafka.Producer
|
||||
|
||||
logx.Logger
|
||||
}
|
||||
)
|
||||
|
||||
func NewUserMq(userPlatformModel model.UserPlatformModel, cfg config.KafkaProducer) *UserMq {
|
||||
return &UserMq{
|
||||
userPlatformModel: userPlatformModel,
|
||||
coinChangedKfk: kafka.NewKafkaProducer(kfk.DefaultProducerConfig, cfg.UserCoinNotify.Addr, cfg.UserCoinNotify.Topic),
|
||||
Logger: logx.WithContext(context.Background()),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *UserMq) NotifyUserCoinChanged(req *pbMq.MqUserCoinChanged) {
|
||||
if req.Username == "" || req.Avatar == "" {
|
||||
// 读取用户数据
|
||||
if dbModel, err := m.userPlatformModel.FindDisplayOneByUserId(context.Background(), req.UserId); err == nil {
|
||||
req.Username = dbModel.PUname
|
||||
req.Avatar = dbModel.PAvatar
|
||||
}
|
||||
}
|
||||
err := m.coinChangedKfk.SendMessageAsync(req)
|
||||
if err != nil {
|
||||
m.Logger.Error("发送通知用户金币变更消息失败")
|
||||
}
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
package pb
|
||||
|
||||
//go:generate goctl rpc protoc user_center.proto --style=go_zero --go_out=../ --go-grpc_out=../ --zrpc_out=../
|
||||
//go:generate goctl rpc protoc user_center.proto --proto_path=. --proto_path=../../../pb/ --style=go_zero --go_out=../ --go-grpc_out=../ --zrpc_out=../
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,28 @@
|
||||
package timex
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/now"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DayExpire 日期是否过期
|
||||
// 使用 BeginningOfDay 判断
|
||||
func DayExpire(nowTime time.Time, src time.Time, forever bool) bool {
|
||||
if forever {
|
||||
return false
|
||||
}
|
||||
today := now.With(nowTime).BeginningOfDay()
|
||||
return !today.Before(now.With(src).BeginningOfDay())
|
||||
}
|
||||
|
||||
// DayRemain 剩余天数(包括今天)
|
||||
func DayRemain(nowTime time.Time, src time.Time, forever bool) int32 {
|
||||
if forever {
|
||||
return -1
|
||||
}
|
||||
resp := int32(src.YearDay() - nowTime.YearDay())
|
||||
if resp < 0 {
|
||||
resp = 0
|
||||
}
|
||||
return resp
|
||||
}
|
Loading…
Reference in New Issue