Commit e6f8bbe0 authored by kzkzzzz's avatar kzkzzzz

feat: 增加wallet和member服务

parent e679899a
This diff is collapsed.
......@@ -37,7 +37,9 @@ func NewMemberEndpoints() []*api.Endpoint {
// Client API for Member service
type MemberService interface {
CheckLoginStatus(ctx context.Context, in *CheckLoginReq, opts ...client.CallOption) (*CheckLoginResp, error)
GetMemberInfo(ctx context.Context, in *MemberInfoReq, opts ...client.CallOption) (*MemberInfoResp, error)
SetCredit1(ctx context.Context, in *SetCredit1Req, opts ...client.CallOption) (*SetCredit1Resp, error)
}
type memberService struct {
......@@ -52,6 +54,16 @@ func NewMemberService(name string, c client.Client) MemberService {
}
}
func (c *memberService) CheckLoginStatus(ctx context.Context, in *CheckLoginReq, opts ...client.CallOption) (*CheckLoginResp, error) {
req := c.c.NewRequest(c.name, "Member.CheckLoginStatus", in)
out := new(CheckLoginResp)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *memberService) GetMemberInfo(ctx context.Context, in *MemberInfoReq, opts ...client.CallOption) (*MemberInfoResp, error) {
req := c.c.NewRequest(c.name, "Member.GetMemberInfo", in)
out := new(MemberInfoResp)
......@@ -62,15 +74,29 @@ func (c *memberService) GetMemberInfo(ctx context.Context, in *MemberInfoReq, op
return out, nil
}
func (c *memberService) SetCredit1(ctx context.Context, in *SetCredit1Req, opts ...client.CallOption) (*SetCredit1Resp, error) {
req := c.c.NewRequest(c.name, "Member.SetCredit1", in)
out := new(SetCredit1Resp)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Member service
type MemberHandler interface {
CheckLoginStatus(context.Context, *CheckLoginReq, *CheckLoginResp) error
GetMemberInfo(context.Context, *MemberInfoReq, *MemberInfoResp) error
SetCredit1(context.Context, *SetCredit1Req, *SetCredit1Resp) error
}
func RegisterMemberHandler(s server.Server, hdlr MemberHandler, opts ...server.HandlerOption) error {
type member interface {
CheckLoginStatus(ctx context.Context, in *CheckLoginReq, out *CheckLoginResp) error
GetMemberInfo(ctx context.Context, in *MemberInfoReq, out *MemberInfoResp) error
SetCredit1(ctx context.Context, in *SetCredit1Req, out *SetCredit1Resp) error
}
type Member struct {
member
......@@ -83,6 +109,14 @@ type memberHandler struct {
MemberHandler
}
func (h *memberHandler) CheckLoginStatus(ctx context.Context, in *CheckLoginReq, out *CheckLoginResp) error {
return h.MemberHandler.CheckLoginStatus(ctx, in, out)
}
func (h *memberHandler) GetMemberInfo(ctx context.Context, in *MemberInfoReq, out *MemberInfoResp) error {
return h.MemberHandler.GetMemberInfo(ctx, in, out)
}
func (h *memberHandler) SetCredit1(ctx context.Context, in *SetCredit1Req, out *SetCredit1Resp) error {
return h.MemberHandler.SetCredit1(ctx, in, out)
}
......@@ -7,7 +7,6 @@ option go_package = "./;member";
message MemberInfoReq {
int64 userId = 1; // @gotags: validate:"required"
string token = 2; // @gotags: validate:"required"
}
message MemberInfoResp {
......@@ -20,7 +19,27 @@ message MemberInfoResp {
string roomId = 7;
}
message SetCredit1Req{
int64 userId = 1; // @gotags: validate:"required"
float goldNum = 2; // @gotags: validate:"required,gt=0"
}
message SetCredit1Resp{
}
message CheckLoginReq {
int64 userId = 1; // @gotags: validate:"required"
string token = 2; // @gotags: validate:"required"
}
message CheckLoginResp {
}
service Member {
rpc CheckLoginStatus(CheckLoginReq) returns (CheckLoginResp){};
rpc GetMemberInfo(MemberInfoReq) returns (MemberInfoResp){};
rpc SetCredit1(SetCredit1Req) returns (SetCredit1Resp){};
}
This diff is collapsed.
......@@ -37,8 +37,8 @@ func NewWalletEndpoints() []*api.Endpoint {
// Client API for Wallet service
type WalletService interface {
GetWallet(ctx context.Context, in *WalletReq, opts ...client.CallOption) (*WalletResp, error)
ListWallet(ctx context.Context, in *ListWalletReq, opts ...client.CallOption) (*ListWalletResp, error)
AddGold(ctx context.Context, in *AddGoldReq, opts ...client.CallOption) (*AddGoldResp, error)
ChargeOne(ctx context.Context, in *ChargeOneReq, opts ...client.CallOption) (*ChargeOneResp, error)
}
type walletService struct {
......@@ -53,9 +53,9 @@ func NewWalletService(name string, c client.Client) WalletService {
}
}
func (c *walletService) GetWallet(ctx context.Context, in *WalletReq, opts ...client.CallOption) (*WalletResp, error) {
req := c.c.NewRequest(c.name, "Wallet.GetWallet", in)
out := new(WalletResp)
func (c *walletService) AddGold(ctx context.Context, in *AddGoldReq, opts ...client.CallOption) (*AddGoldResp, error) {
req := c.c.NewRequest(c.name, "Wallet.AddGold", in)
out := new(AddGoldResp)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
......@@ -63,9 +63,9 @@ func (c *walletService) GetWallet(ctx context.Context, in *WalletReq, opts ...cl
return out, nil
}
func (c *walletService) ListWallet(ctx context.Context, in *ListWalletReq, opts ...client.CallOption) (*ListWalletResp, error) {
req := c.c.NewRequest(c.name, "Wallet.ListWallet", in)
out := new(ListWalletResp)
func (c *walletService) ChargeOne(ctx context.Context, in *ChargeOneReq, opts ...client.CallOption) (*ChargeOneResp, error) {
req := c.c.NewRequest(c.name, "Wallet.ChargeOne", in)
out := new(ChargeOneResp)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
......@@ -76,14 +76,14 @@ func (c *walletService) ListWallet(ctx context.Context, in *ListWalletReq, opts
// Server API for Wallet service
type WalletHandler interface {
GetWallet(context.Context, *WalletReq, *WalletResp) error
ListWallet(context.Context, *ListWalletReq, *ListWalletResp) error
AddGold(context.Context, *AddGoldReq, *AddGoldResp) error
ChargeOne(context.Context, *ChargeOneReq, *ChargeOneResp) error
}
func RegisterWalletHandler(s server.Server, hdlr WalletHandler, opts ...server.HandlerOption) error {
type wallet interface {
GetWallet(ctx context.Context, in *WalletReq, out *WalletResp) error
ListWallet(ctx context.Context, in *ListWalletReq, out *ListWalletResp) error
AddGold(ctx context.Context, in *AddGoldReq, out *AddGoldResp) error
ChargeOne(ctx context.Context, in *ChargeOneReq, out *ChargeOneResp) error
}
type Wallet struct {
wallet
......@@ -96,10 +96,10 @@ type walletHandler struct {
WalletHandler
}
func (h *walletHandler) GetWallet(ctx context.Context, in *WalletReq, out *WalletResp) error {
return h.WalletHandler.GetWallet(ctx, in, out)
func (h *walletHandler) AddGold(ctx context.Context, in *AddGoldReq, out *AddGoldResp) error {
return h.WalletHandler.AddGold(ctx, in, out)
}
func (h *walletHandler) ListWallet(ctx context.Context, in *ListWalletReq, out *ListWalletResp) error {
return h.WalletHandler.ListWallet(ctx, in, out)
func (h *walletHandler) ChargeOne(ctx context.Context, in *ChargeOneReq, out *ChargeOneResp) error {
return h.WalletHandler.ChargeOne(ctx, in, out)
}
......@@ -4,32 +4,36 @@ import "google/protobuf/timestamp.proto";
option go_package = "./;wallet";
message WalletReq {
string id = 1; // @gotags: validate:"required"
enum GoldType {
typeNone = 0;
typeCharge = 59;
typeAdd = 60;
}
message AddGoldReq {
int64 userId = 1; // @gotags: validate:"required"
float goldNum = 2; // @gotags: validate:"required,gt=0"
GoldType type = 3;
int64 adminUserId = 4;
string remark = 5;
}
message ListWalletReq {
string id = 1; // @gotags: validate:"required"
int32 limit = 2;
message AddGoldResp {
}
message WalletResp {
string id = 1;
string username = 2;
string email = 3;
string avatar = 4;
int32 status = 5;
google.protobuf.Timestamp created_at = 6;
google.protobuf.Timestamp updated_at = 7;
message ChargeOneReq {
int64 userId = 1; // @gotags: validate:"required"
float goldNum = 2; // @gotags: validate:"required,gt=0"
GoldType type = 3;
}
message ListWalletResp {
repeated WalletResp list = 1;
int32 limit = 2;
message ChargeOneResp {
}
service Wallet {
rpc GetWallet(WalletReq) returns (WalletResp){};
rpc ListWallet(ListWalletReq) returns (ListWalletResp){};
rpc AddGold(AddGoldReq) returns (AddGoldResp){};
rpc ChargeOne(ChargeOneReq) returns (ChargeOneResp){};
}
package errorm
package errm
import (
"fmt"
......@@ -27,10 +27,12 @@ type ResponseError struct {
var _ error = &ResponseError{}
// 实现error接口
func (c *ResponseError) Error() string {
return fmt.Sprintf("[%d]%s", c.Code, c.Msg)
}
// NewMicroError 构造go-micro错误响应
func NewMicroError(detail string, code ...int32) error {
var c = DefaultErrorCode
if len(code) > 0 {
......@@ -43,10 +45,12 @@ func NewMicroError(detail string, code ...int32) error {
}
}
// TransParamsError 翻译go-validate验证错误信息
func TransParamsError(err error) error {
return NewMicroError(validate.TransError(err), ParamsErrorCode)
}
// NotFound 未找到错误
func NotFound(detail string) error {
return NewMicroError(detail, NotFoundErrorCode)
}
......@@ -13,6 +13,12 @@ var (
trans ut.Translator
)
// 初始化验证器和翻译
func init() {
vt = validator.New()
trans = newTranslate(vt)
}
func newTranslate(v *validator.Validate) ut.Translator {
zhT := zh.New()
enT := en.New()
......@@ -23,19 +29,17 @@ func newTranslate(v *validator.Validate) ut.Translator {
return tr
}
func init() {
vt = validator.New()
trans = newTranslate(vt)
}
// GrtTrans 获取翻译实例
func GrtTrans() ut.Translator {
return trans
}
// Struct 验证结构体
func Struct(data interface{}) error {
return vt.Struct(data)
}
// TransError 翻译错误信息
func TransError(err error) (msg string) {
switch v := err.(type) {
case validator.ValidationErrors:
......
......@@ -67,6 +67,7 @@ require (
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sergi/go-diff v1.2.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/spf13/afero v1.8.2 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
......
......@@ -625,6 +625,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
......
......@@ -8,10 +8,11 @@ Server:
Addr: ""
Mysql:
Dsn: remote:admin666@tcp(127.0.0.1:3306)/test?loc=Local&charset=utf8mb4&writeTimeout=3s&readTimeout=3s&timeout=1s&parseTime=true
MaxConn: 8
MaxIdleConn: 2
MaxLifetime: 1800 # 连接有效时间,单位秒
# Dsn: remote:admin666@tcp(127.0.0.1:3306)/test?loc=Local&charset=utf8mb4&writeTimeout=3s&readTimeout=3s&timeout=1s&parseTime=true
Dsn: master:Xt6fW2rNRvYZjtYW@tcp(rm-j6c982j8ih8x3d2yz2o.mysql.rds.aliyuncs.com:3306)/master?loc=Local&charset=utf8mb4&writeTimeout=3s&readTimeout=3s&timeout=2s&parseTime=true
MaxConn: 16 # 连接池最大连接数
MaxIdleConn: 4 # 连接池最小连接数
MaxLifetime: 1800 # 连接池内连接有效时间,单位秒
Debug: true
Redis:
......
......@@ -5,6 +5,7 @@ import (
"gomicro-base/common/conf"
"gomicro-base/common/logz"
"gomicro-base/common/mysql"
"gomicro-base/common/redis"
)
func init() {
......@@ -19,6 +20,7 @@ var (
type Config struct {
Server *Server
Mysql *mysql.Config
Redis *redis.Config
Log *logz.Config
}
......
package dao
import (
"context"
"encoding/json"
"fmt"
"gomicro-base/common/logz"
"gomicro-base/common/mysql"
"gomicro-base/common/redis"
"gomicro-base/service/member/internal/conf"
"gomicro-base/service/member/internal/model"
"gorm.io/gorm"
......@@ -9,25 +14,30 @@ import (
// Dao 查询数据库
type Dao struct {
DB *gorm.DB
DB *gorm.DB
Redis *redis.WrapClient
}
func New(c *conf.Config) (d *Dao) {
d = &Dao{
DB: mysql.NewDB(c.Mysql),
DB: mysql.NewDB(c.Mysql),
Redis: redis.NewRedis(c.Redis),
}
return
}
// GetMemberById 根据id查询用户
func (d *Dao) GetMemberById(id int, token string, column []string) (res *model.ImsDbPlayMember, err error) {
res = &model.ImsDbPlayMember{}
err = d.DB.Model(&model.ImsDbPlayMember{}).
Select(column).
Where(map[string]interface{}{
"id": id,
"token": token,
}).
Take(res).Error
return
func (d *Dao) FindCacheByPk(ctx context.Context, userIdKey string) (*model.CacheUser, error) {
b, err := d.Redis.Get(ctx, userIdKey).Bytes()
if err != nil {
logz.Errorf("token error -1: %s", err)
return nil, fmt.Errorf("token error -1")
}
cs := &model.CacheUser{}
err = json.Unmarshal(b, cs)
if err != nil {
logz.Errorf("token error -2: %s", err)
return nil, fmt.Errorf("token error -2")
}
return cs, nil
}
package model
import "github.com/shopspring/decimal"
type ImsDbPlayPaylog struct {
Id int `json:"id"` // Id
PayMoney decimal.Decimal `json:"pay_money"` // 付款金额(金币)
PayTime int `json:"pay_time"` // PayTime
UserId int `json:"user_id"` // 支付者id
Type int `json:"type"` // 支付类型:1:充值金币2:礼物消费3:猜拳消费4:猜拳退货5:兑换增加6:免费赠送7:全服喇叭8:会员收益9:会员消费10:任务奖励11:其他消费12召唤粉丝13召唤会员14房间上锁15置顶16创建房间17创建家族18道具消耗19背景消费20转盘消耗21转盘退款22创建活动消耗23pk消费24活动奖励25房间扶持26背景返还27竞拍定金28竞拍余额支付29定金返还30分组发放金币31pk奖励32召唤成员33H5活动消费34ludo消费35ludo收入36ludo退款37游戏罚金 38特殊关系退款39房间转盘消耗40房间转盘收入41房间红包消耗42房间红包获得43红包退款44 砸金蛋45ludo退款46domino退款47okey退款48drum退款49活动退款50-水果机下注51水果机赢取52房间抽奖消耗53房间抽奖获得54房间抽奖退款55 房间认证获得 56luck_box消耗 57luck_box获得58房间任务奖励 59大富翁消耗60大富翁获胜61充值奖励62banner申请63banner拒绝返回
FamilyId int `json:"family_id"` // FamilyId
GoldLog int `json:"gold_log"` // 是否已经导入gold_log表,1导入,0为导入
Remark int `json:"remark"` // 备注信息
AuctionId int `json:"auction_id"` // 竞拍ID
GoldConsumption int `json:"gold_consumption"` // 是否已经导入gold_log表,1导入,0为导入
}
func (i *ImsDbPlayPaylog) TableName() string {
return "ims_db_play_paylog"
}
package model
import (
"time"
)
type User struct {
Id int `json:"id"` // Id
Username string `json:"username"` // Username
IsEmailVerified int `json:"is_email_verified"` // IsEmailVerified
Email string `json:"email"` // Email
Password string `json:"password"` // Password
PasswordHash string `json:"password_hash"` // PasswordHash
Avatar string `json:"avatar"` // Avatar
Role string `json:"role"` // Role
Status int `json:"status"` // Status
LastSpace int `json:"last_space"` // LastSpace
CreatedAt time.Time `json:"created_at"` // CreatedAt
UpdatedAt time.Time `json:"updated_at"` // UpdatedAt
}
func (u *User) TableName() string {
return "users"
}
......@@ -3,7 +3,7 @@ package server
import (
"context"
"gomicro-base/api/member"
"gomicro-base/common/errorm"
"gomicro-base/common/errm"
"gomicro-base/common/hashutil"
"gomicro-base/common/validate"
"gomicro-base/service/member/internal/model"
......@@ -18,16 +18,24 @@ type handler struct {
svc *service.MemberService
}
func (h *handler) CheckLoginStatus(ctx context.Context, req *member.CheckLoginReq, resp *member.CheckLoginResp) error {
return h.svc.CheckLoginStatus(ctx, req)
}
func (h *handler) SetCredit1(ctx context.Context, req *member.SetCredit1Req, resp *member.SetCredit1Resp) error {
return h.svc.SetCredit1(ctx, req)
}
func (h *handler) GetMemberInfo(ctx context.Context, req *member.MemberInfoReq, resp *member.MemberInfoResp) error {
err := validate.Struct(req)
if err != nil {
return errorm.TransParamsError(err)
return errm.TransParamsError(err)
}
m, err := h.svc.GetMemberInfo(ctx, req)
if err != nil {
if err == gorm.ErrRecordNotFound {
return errorm.NotFound(err.Error())
return errm.NotFound(err.Error())
}
return err
}
......@@ -40,7 +48,7 @@ func (h *handler) convertMemberModel(m *model.ImsDbPlayMember) (resp *member.Mem
UserId: int64(m.Id),
UserNo: int64(m.UserNo),
Avatar: hashutil.Base64Decode(m.Nickname),
Coins: int64(m.Credit1),
Coins: m.Credit1.IntPart(),
CoinIcon: "https://image.whoisamy.shop/attachment/2022/02/15/ca8515b15ad91375537e4c6b67dbfbbbdb30c95b.png",
RoomId: "10001",
}
......
......@@ -2,7 +2,11 @@ package service
import (
"context"
"fmt"
"github.com/shopspring/decimal"
"github.com/spf13/cast"
"gomicro-base/api/member"
"gomicro-base/common/errm"
"gomicro-base/service/member/internal/dao"
"gomicro-base/service/member/internal/model"
)
......@@ -18,10 +22,36 @@ func New(d *dao.Dao) *MemberService {
}
}
func (s *MemberService) GetMemberInfo(ctx context.Context, req *member.MemberInfoReq) (*model.ImsDbPlayMember, error) {
m, err := s.dao.GetMemberById(int(req.UserId), req.Token, []string{"*"})
// CheckLoginStatus 检查登录状态
func (m *MemberService) CheckLoginStatus(ctx context.Context, req *member.CheckLoginReq) error {
cacheUser, err := m.dao.FindCacheByPk(ctx, cast.ToString(req.UserId))
if err != nil {
return nil, err
return errm.NewMicroError(err.Error(), 400)
}
return m, err
if cacheUser.Token != req.Token {
return errm.NewMicroError("token error -3", 400)
}
return nil
}
// SetCredit1 调整余额
func (m *MemberService) SetCredit1(ctx context.Context, req *member.SetCredit1Req) error {
sql := fmt.Sprintf(
"update ims_db_play_member set credit1 = credit1 + %s where id = %d",
decimal.NewFromFloat32(req.GoldNum).String(),
req.UserId,
)
return m.dao.DB.Exec(sql).Error
}
// GetMemberInfo 获取用户信息
func (m *MemberService) GetMemberInfo(ctx context.Context, req *member.MemberInfoReq) (*model.ImsDbPlayMember, error) {
res := &model.ImsDbPlayMember{}
err := m.dao.DB.Model(&model.ImsDbPlayMember{}).
Select([]string{"*"}).
Where(map[string]interface{}{
"id": req.UserId,
}).
Take(&res).Error
return res, err
}
......@@ -7,12 +7,13 @@ import (
"go-micro.dev/v4/client"
"go-micro.dev/v4/registry"
"go-micro.dev/v4/selector"
"gomicro-base/api/member"
"gomicro-base/service/wallet/internal/conf"
)
var (
microClient client.Client
cf *conf.Config
microService micro.Service
cf *conf.Config
)
func NewMicroClient(c *conf.Config) {
......@@ -24,19 +25,26 @@ func NewMicroClient(c *conf.Config) {
selector.SetStrategy(selector.RoundRobin),
)
service := micro.NewService(
microService = micro.NewService(
micro.Client(grpc.NewClient()),
micro.Selector(newSelector),
micro.WrapClient(NewTimeoutWrapper),
//micro.WrapClient(NewLogWrapper),
)
microClient = service.Client()
}
func GetService() micro.Service {
return microService
}
func GetClient() client.Client {
return microClient
return microService.Client()
}
func Reconnect() {
NewMicroClient(cf)
}
func GetMemberSvc() member.MemberService {
return member.NewMemberService(conf.Conf.Client.Member, microService.Client())
}
......@@ -8,10 +8,10 @@ Server:
Addr: ""
Client:
MemberName: "service.member"
Member: "service.member"
Mysql:
Dsn: remote:admin666@tcp(127.0.0.1:3306)/test?loc=Local&charset=utf8mb4&writeTimeout=3s&readTimeout=3s&timeout=1s&parseTime=true
Dsn: master:Xt6fW2rNRvYZjtYW@tcp(rm-j6c982j8ih8x3d2yz2o.mysql.rds.aliyuncs.com:3306)/master?loc=Local&charset=utf8mb4&writeTimeout=3s&readTimeout=3s&timeout=2s&parseTime=true
MaxConn: 8
MaxIdleConn: 2
MaxLifetime: 1800 # 连接有效时间,单位秒
......
......@@ -5,6 +5,7 @@ import (
"gomicro-base/common/conf"
"gomicro-base/common/logz"
"gomicro-base/common/mysql"
"gomicro-base/common/redis"
)
func init() {
......@@ -20,6 +21,7 @@ type Config struct {
Server *Server
Client *Client
Mysql *mysql.Config
Redis *redis.Config
Log *logz.Config
}
......@@ -36,7 +38,7 @@ type Server struct {
}
type Client struct {
MemberName string
Member string
}
func LoadConfig() {
......
......@@ -2,38 +2,21 @@ package dao
import (
"gomicro-base/common/mysql"
"gomicro-base/common/redis"
"gomicro-base/service/wallet/internal/conf"
"gomicro-base/service/wallet/internal/model"
"gorm.io/gorm"
)
// Dao 查询数据库
type Dao struct {
DB *gorm.DB
DB *gorm.DB
Redis *redis.WrapClient
}
func New(c *conf.Config) (d *Dao) {
d = &Dao{
DB: mysql.NewDB(c.Mysql),
DB: mysql.NewDB(c.Mysql),
Redis: redis.NewRedis(c.Redis),
}
return
}
// GetUserById 根据id查询用户
func (d *Dao) GetUserById(id int, column []string) (res *model.User, err error) {
res = &model.User{}
err = d.DB.Model(&model.User{}).
Select(column).
Where("id = ?", id).Take(res).Error
return
}
// ListUserGtId 查询大于该id的用户列表
func (d *Dao) ListUserGtId(id int, limit int) (res []*model.User, err error) {
res = make([]*model.User, 0)
err = d.DB.Model(&model.User{}).
Where("id > ?", id).
Limit(limit).Order("id desc").
Find(&res).Error
return
}
package model
type ImsDbPlayFreezeMoney struct {
Id int `json:"id"` // Id
UserId int `json:"user_id"` // UserId
CreateTime int `json:"create_time"` // CreateTime
Uid int `json:"uid"` // Uid
}
func (i *ImsDbPlayFreezeMoney) TableName() string {
return "ims_db_play_freeze_money"
}
package model
import (
"github.com/shopspring/decimal"
)
type ImsDbPlayPaylog struct {
Id int `json:"id"` // Id
PayMoney decimal.Decimal `json:"pay_money"` // 付款金额(金币)
PayTime int `json:"pay_time"` // PayTime
UserId int `json:"user_id"` // 支付者id
Type int `json:"type"` // 支付类型:1:充值金币2:礼物消费3:猜拳消费4:猜拳退货5:兑换增加6:免费赠送7:全服喇叭8:会员收益9:会员消费10:任务奖励11:其他消费12召唤粉丝13召唤会员14房间上锁15置顶16创建房间17创建家族18道具消耗19背景消费20转盘消耗21转盘退款22创建活动消耗23pk消费24活动奖励25房间扶持26背景返还27竞拍定金28竞拍余额支付29定金返还30分组发放金币31pk奖励32召唤成员33H5活动消费34ludo消费35ludo收入36ludo退款37游戏罚金 38特殊关系退款39房间转盘消耗40房间转盘收入41房间红包消耗42房间红包获得43红包退款44 砸金蛋45ludo退款46domino退款47okey退款48drum退款49活动退款50-水果机下注51水果机赢取52房间抽奖消耗53房间抽奖获得54房间抽奖退款55 房间认证获得 56luck_box消耗 57luck_box获得58房间任务奖励 59大富翁消耗60大富翁获胜61充值奖励62banner申请63banner拒绝返回
FamilyId int `json:"family_id"` // FamilyId
GoldLog int `json:"gold_log"` // 是否已经导入gold_log表,1导入,0为导入
Remark int `json:"remark"` // 备注信息
AuctionId int `json:"auction_id"` // 竞拍ID
GoldConsumption int `json:"gold_consumption"` // 是否已经导入gold_log表,1导入,0为导入
}
func (i *ImsDbPlayPaylog) TableName() string {
return "ims_db_play_paylog"
}
package model
import ()
type ImsDbPlayPaylogRemark struct {
Id int64 `json:"id"` // 主键id
UserId int `json:"user_id"` // 用户id
Gold int `json:"gold"` // 金币
PayTime int `json:"pay_time"` // 时间
Remark string `json:"remark"` // 备注
}
func (i *ImsDbPlayPaylogRemark) TableName() string {
return "ims_db_play_paylog_remark"
}
package model
type ImMessage struct {
Content ImMessageContent `json:"content"`
UserId int `json:"user_id"`
SendId int `json:"send_id"`
SysType string `json:"sys_type"`
}
type ImMessageContent struct {
Money string `json:"money"`
}
package model
import (
"time"
)
type User struct {
Id int `json:"id"` // Id
Username string `json:"username"` // Username
IsEmailVerified int `json:"is_email_verified"` // IsEmailVerified
Email string `json:"email"` // Email
Password string `json:"password"` // Password
PasswordHash string `json:"password_hash"` // PasswordHash
Avatar string `json:"avatar"` // Avatar
Role string `json:"role"` // Role
Status int `json:"status"` // Status
LastSpace int `json:"last_space"` // LastSpace
CreatedAt time.Time `json:"created_at"` // CreatedAt
UpdatedAt time.Time `json:"updated_at"` // UpdatedAt
}
func (u *User) TableName() string {
return "users"
}
......@@ -2,11 +2,8 @@ package server
import (
"context"
"github.com/spf13/cast"
"gomicro-base/api/wallet"
"gomicro-base/service/wallet/internal/model"
"gomicro-base/service/wallet/internal/service"
"google.golang.org/protobuf/types/known/timestamppb"
)
// 检查接口实现
......@@ -17,44 +14,10 @@ type handler struct {
svc *service.WalletService
}
func (h *handler) GetWallet(ctx context.Context, req *wallet.WalletReq, resp *wallet.WalletResp) error {
getWallet, err := h.svc.GetWallet(ctx, req)
if err != nil {
return err
}
*resp = *h.convertUserModel(getWallet)
return nil
func (h *handler) ChargeOne(ctx context.Context, req *wallet.ChargeOneReq, resp *wallet.ChargeOneResp) error {
return h.svc.ChargeOne(ctx, req)
}
func (h *handler) ListWallet(ctx context.Context, req *wallet.ListWalletReq, resp *wallet.ListWalletResp) error {
if req.Limit <= 0 {
req.Limit = 15
}
listWallet, err := h.svc.ListWallet(ctx, req)
if err != nil {
return err
}
list := make([]*wallet.WalletResp, 0)
for _, v := range listWallet {
c := *h.convertUserModel(v)
list = append(list, &c)
}
resp.List = list
resp.Limit = req.Limit
return nil
}
func (h *handler) convertUserModel(users *model.User) (resp *wallet.WalletResp) {
r := &wallet.WalletResp{
Id: cast.ToString(users.Id),
Username: users.Username,
Email: users.Email,
Avatar: users.Avatar,
Status: int32(users.Status),
CreatedAt: timestamppb.New(users.CreatedAt),
UpdatedAt: timestamppb.New(users.UpdatedAt),
}
return r
func (h *handler) AddGold(ctx context.Context, req *wallet.AddGoldReq, resp *wallet.AddGoldResp) error {
return h.svc.AddGold(ctx, req)
}
......@@ -2,14 +2,21 @@ package service
import (
"context"
"encoding/json"
"fmt"
"github.com/shopspring/decimal"
"github.com/spf13/cast"
"go-micro.dev/v4/errors"
"gomicro-base/api/member"
"gomicro-base/api/wallet"
"gomicro-base/common/errm"
"gomicro-base/common/logz"
"gomicro-base/common/validate"
"gomicro-base/service/wallet/client"
"gomicro-base/service/wallet/internal/conf"
"gomicro-base/service/wallet/internal/dao"
"gomicro-base/service/wallet/internal/model"
"gorm.io/gorm"
"time"
)
// WalletService 服务层处理逻辑
......@@ -23,30 +30,100 @@ func New(d *dao.Dao) *WalletService {
}
}
func (s *WalletService) GetWallet(ctx context.Context, req *wallet.WalletReq) (*model.User, error) {
getClient := client.GetClient()
service := member.NewMemberService(conf.Conf.Client.MemberName, getClient)
info, err := service.GetMemberInfo(ctx, &member.MemberInfoReq{
UserId: 100027,
Token: "WErvu0OLJZ3Mq6dTw8HhQ4bnNsReIoFK",
})
// ChargeOne 单向扣除金币
func (w *WalletService) ChargeOne(ctx context.Context, req *wallet.ChargeOneReq) error {
err := validate.Struct(req)
if err != nil {
return nil, err
return errm.TransParamsError(err)
}
// 判断是否冻结
fm := model.ImsDbPlayFreezeMoney{}
err = w.dao.DB.Table(fm.TableName()).Where("user_id = ?", req.UserId).Select("id").Take(&fm).Error
if err != nil && err != gorm.ErrRecordNotFound {
return err
}
// 存在记录
if fm.Id > 0 {
return errm.NewMicroError("Gold coin account locked", 401)
}
logz.Println(info)
// 调用用户服务修改金额
_, err = client.GetMemberSvc().SetCredit1(ctx, &member.SetCredit1Req{
UserId: req.UserId,
GoldNum: req.GoldNum * -1, // 减
})
if err != nil {
logz.Error(err)
return errm.NewMicroError("Insufficient gold coin balance", 403)
}
user, err := s.dao.GetUserById(cast.ToInt(req.Id), []string{"*"})
// 写入日志
payLog := model.ImsDbPlayPaylog{
UserId: int(req.UserId),
PayTime: int(time.Now().Unix()),
PayMoney: decimal.NewFromFloat32(req.GoldNum),
Type: int(wallet.GoldType_typeCharge),
}
err = w.dao.DB.Table(payLog.TableName()).Create(&payLog).Error
if err != nil {
return nil, err
logz.Errorf("charge 写入日志失败: %s", err)
return nil
}
return user, err
return nil
}
func (s *WalletService) ListWallet(ctx context.Context, req *wallet.ListWalletReq) ([]*model.User, error) {
list, err := s.dao.ListUserGtId(cast.ToInt(req.Id), int(req.Limit))
// AddGold 发放金币
func (w *WalletService) AddGold(ctx context.Context, req *wallet.AddGoldReq) error {
// 通过validate tag标签验证参数
err := validate.Struct(req)
if err != nil {
return errm.TransParamsError(err)
}
// 调用用户服务修改金额
_, err = client.GetMemberSvc().SetCredit1(ctx, &member.SetCredit1Req{
UserId: req.UserId,
GoldNum: req.GoldNum, // 加
})
if err != nil {
return errm.NewMicroError(fmt.Sprintf("更新金额失败: %s", errors.FromError(err).Detail))
}
nowTime := time.Now().Unix()
// 写入日志
payLog := model.ImsDbPlayPaylog{
UserId: int(req.UserId),
PayTime: int(nowTime),
PayMoney: decimal.NewFromFloat32(req.GoldNum),
Type: int(wallet.GoldType_typeAdd),
}
err = w.dao.DB.Table(payLog.TableName()).Create(&payLog).Error
if err != nil {
return nil, err
return err
}
// 发金币IM消息
im := model.ImMessage{
Content: model.ImMessageContent{Money: cast.ToString(req.GoldNum)},
UserId: int(req.UserId),
SendId: int(req.AdminUserId),
SysType: "RechargeResult",
}
marshal, _ := json.Marshal(im)
_, err = w.dao.Redis.RPush(ctx, "rongyun_queue", marshal).Result()
if err != nil {
return err
}
// 写入备注
r := model.ImsDbPlayPaylogRemark{
UserId: int(req.UserId),
Gold: cast.ToInt(req.GoldNum),
PayTime: int(nowTime),
Remark: req.Remark,
}
return list, nil
return w.dao.DB.Table(r.TableName()).Create(&r).Error
}
......@@ -10,6 +10,7 @@ import (
"github.com/spf13/cobra"
"go-micro.dev/v4"
"go-micro.dev/v4/client"
"go-micro.dev/v4/errors"
"go-micro.dev/v4/registry"
"go-micro.dev/v4/selector"
"net/http"
......@@ -28,8 +29,9 @@ var (
// http响应对象
type response struct {
Code int32 `json:"code"`
Message string `json:"message"`
Result interface{} `json:"result"`
Data interface{} `json:"data"`
}
// 超时控制
......@@ -141,7 +143,7 @@ func listService(ctx *gin.Context) {
services[v.Name] = append(services[v.Name], v)
}
ctx.JSON(http.StatusOK, &response{Message: "ok", Result: services})
ctx.JSON(http.StatusOK, &response{Message: "ok", Data: services})
}
// 调用服务
......@@ -157,16 +159,19 @@ func callService(ctx *gin.Context) {
req := microClient.NewRequest(ctx.Param("service"), ctx.Param("endpoint"), requestData, client.WithContentType("application/json"))
var res map[string]interface{}
err = microClient.Call(context.Background(), req, &res)
fromError := errors.FromError(err)
if err != nil {
ctx.JSON(http.StatusOK, &response{
Message: "grpc响应异常",
Result: err,
Code: fromError.Code,
Message: fromError.Detail,
Data: err,
})
return
}
ctx.JSON(http.StatusOK, &response{
Message: "ok",
Result: res,
Data: res,
})
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment