Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7a12a9e702 | |||
| fe84f68648 | |||
| a3c7c013c5 | |||
| c523ebcf89 | |||
| bbccb3e05e | |||
| 4bdd040e91 | |||
| 590e5b0cd2 | |||
| ad5bff534c | |||
| 13eb299316 | |||
| a3518d20f1 | |||
| 9654147054 | |||
| 44c73e787f | |||
| 164f98cf33 | |||
| 60a3530609 | |||
| d19cb53f24 | |||
| b08a3a51e0 | |||
| 9a32850030 | |||
| 776ecc479f | |||
| 631469a713 | |||
| 22c7c4e7d9 | |||
| d1031f48b3 | |||
| 429a1df32a | |||
| 87bf86a410 | |||
| 227f5814df | |||
| cf639f1bca | |||
| 83fa982749 | |||
| 41890ddd33 | |||
| 2341284f6c | |||
| 585417c07a | |||
| fbb4d12f63 | |||
| cdc85ce7dd | |||
| bd07075cfe |
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "frontend"]
|
||||||
|
path = frontend
|
||||||
|
url = http://103.236.53.208:3000/juwan/juwan-frontend.git
|
||||||
@@ -20,7 +20,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var c config.Config
|
var c config.Config
|
||||||
conf.MustLoad(*configFile, &c)
|
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||||
svcCtx := svc.NewServiceContext(c)
|
svcCtx := svc.NewServiceContext(c)
|
||||||
|
|
||||||
handler := chathandler.NewHandler(svcCtx)
|
handler := chathandler.NewHandler(svcCtx)
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ Hybrid:
|
|||||||
Wt:
|
Wt:
|
||||||
Addr: :8443
|
Addr: :8443
|
||||||
Path: /wt/chat
|
Path: /wt/chat
|
||||||
CertFile: /etc/certs/tls.crt
|
CertFile: "${CHAT_WT_CERT_FILE}"
|
||||||
KeyFile: /etc/certs/tls.key
|
KeyFile: "${CHAT_WT_KEY_FILE}"
|
||||||
Auth:
|
Auth:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
FallbackStrategy: auto
|
FallbackStrategy: auto
|
||||||
@@ -29,18 +29,18 @@ Hybrid:
|
|||||||
WsHeaderName: x-auth-user-id
|
WsHeaderName: x-auth-user-id
|
||||||
WtTokenSource: cookie
|
WtTokenSource: cookie
|
||||||
WtTokenName: JToken
|
WtTokenName: JToken
|
||||||
WtJWTSecret: MGUyMWE3ZDhjMTQ5ZDg1MWViOWU0MGM3OTE2NWVkYTBlOTE5ZWRkZDU1YjYzOGJjOWRiNzM0NTc4NDIyMjlkZQ
|
WtJWTSecret: "${JWT_SECRET_KEY}"
|
||||||
|
|
||||||
Stateless:
|
Stateless:
|
||||||
PollInterval: 100ms
|
PollInterval: 100ms
|
||||||
BatchSize: 100
|
BatchSize: 100
|
||||||
|
|
||||||
Mongo:
|
Mongo:
|
||||||
URI: mongodb://mongo:27017
|
URI: "${MONGO_URI}"
|
||||||
Database: juwan_chat
|
Database: "${MONGO_DATABASE}"
|
||||||
|
|
||||||
Redis:
|
Redis:
|
||||||
Addr: redis:6379
|
Addr: "${REDIS_HOST}:${REDIS_PORT}"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
Level: info
|
Level: info
|
||||||
|
|||||||
@@ -1,114 +0,0 @@
|
|||||||
package chatservice
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"juwan-backend/app/chat/rpc/pb"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/zrpc"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
ChatSessions = pb.ChatSessions
|
|
||||||
AddChatSessionsReq = pb.AddChatSessionsReq
|
|
||||||
AddChatSessionsResp = pb.AddChatSessionsResp
|
|
||||||
UpdateChatSessionsReq = pb.UpdateChatSessionsReq
|
|
||||||
UpdateChatSessionsResp = pb.UpdateChatSessionsResp
|
|
||||||
DelChatSessionsReq = pb.DelChatSessionsReq
|
|
||||||
DelChatSessionsResp = pb.DelChatSessionsResp
|
|
||||||
GetChatSessionsByIdReq = pb.GetChatSessionsByIdReq
|
|
||||||
GetChatSessionsByIdResp = pb.GetChatSessionsByIdResp
|
|
||||||
SearchChatSessionsReq = pb.SearchChatSessionsReq
|
|
||||||
SearchChatSessionsResp = pb.SearchChatSessionsResp
|
|
||||||
AddParticipantReq = pb.AddParticipantReq
|
|
||||||
AddParticipantResp = pb.AddParticipantResp
|
|
||||||
RemoveParticipantReq = pb.RemoveParticipantReq
|
|
||||||
RemoveParticipantResp = pb.RemoveParticipantResp
|
|
||||||
ChatMessages = pb.ChatMessages
|
|
||||||
AddChatMessagesReq = pb.AddChatMessagesReq
|
|
||||||
AddChatMessagesResp = pb.AddChatMessagesResp
|
|
||||||
DelChatMessagesReq = pb.DelChatMessagesReq
|
|
||||||
DelChatMessagesResp = pb.DelChatMessagesResp
|
|
||||||
GetChatMessagesByIdReq = pb.GetChatMessagesByIdReq
|
|
||||||
GetChatMessagesByIdResp = pb.GetChatMessagesByIdResp
|
|
||||||
SearchChatMessagesReq = pb.SearchChatMessagesReq
|
|
||||||
SearchChatMessagesResp = pb.SearchChatMessagesResp
|
|
||||||
|
|
||||||
ChatService interface {
|
|
||||||
AddChatSessions(ctx context.Context, in *AddChatSessionsReq, opts ...grpc.CallOption) (*AddChatSessionsResp, error)
|
|
||||||
UpdateChatSessions(ctx context.Context, in *UpdateChatSessionsReq, opts ...grpc.CallOption) (*UpdateChatSessionsResp, error)
|
|
||||||
DelChatSessions(ctx context.Context, in *DelChatSessionsReq, opts ...grpc.CallOption) (*DelChatSessionsResp, error)
|
|
||||||
GetChatSessionsById(ctx context.Context, in *GetChatSessionsByIdReq, opts ...grpc.CallOption) (*GetChatSessionsByIdResp, error)
|
|
||||||
SearchChatSessions(ctx context.Context, in *SearchChatSessionsReq, opts ...grpc.CallOption) (*SearchChatSessionsResp, error)
|
|
||||||
AddParticipant(ctx context.Context, in *AddParticipantReq, opts ...grpc.CallOption) (*AddParticipantResp, error)
|
|
||||||
RemoveParticipant(ctx context.Context, in *RemoveParticipantReq, opts ...grpc.CallOption) (*RemoveParticipantResp, error)
|
|
||||||
AddChatMessages(ctx context.Context, in *AddChatMessagesReq, opts ...grpc.CallOption) (*AddChatMessagesResp, error)
|
|
||||||
DelChatMessages(ctx context.Context, in *DelChatMessagesReq, opts ...grpc.CallOption) (*DelChatMessagesResp, error)
|
|
||||||
GetChatMessagesById(ctx context.Context, in *GetChatMessagesByIdReq, opts ...grpc.CallOption) (*GetChatMessagesByIdResp, error)
|
|
||||||
SearchChatMessages(ctx context.Context, in *SearchChatMessagesReq, opts ...grpc.CallOption) (*SearchChatMessagesResp, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultChatService struct {
|
|
||||||
cli zrpc.Client
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewChatService(cli zrpc.Client) ChatService {
|
|
||||||
return &defaultChatService{cli: cli}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *defaultChatService) AddChatSessions(ctx context.Context, in *AddChatSessionsReq, opts ...grpc.CallOption) (*AddChatSessionsResp, error) {
|
|
||||||
client := pb.NewChatServiceClient(m.cli.Conn())
|
|
||||||
return client.AddChatSessions(ctx, in, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *defaultChatService) UpdateChatSessions(ctx context.Context, in *UpdateChatSessionsReq, opts ...grpc.CallOption) (*UpdateChatSessionsResp, error) {
|
|
||||||
client := pb.NewChatServiceClient(m.cli.Conn())
|
|
||||||
return client.UpdateChatSessions(ctx, in, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *defaultChatService) DelChatSessions(ctx context.Context, in *DelChatSessionsReq, opts ...grpc.CallOption) (*DelChatSessionsResp, error) {
|
|
||||||
client := pb.NewChatServiceClient(m.cli.Conn())
|
|
||||||
return client.DelChatSessions(ctx, in, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *defaultChatService) GetChatSessionsById(ctx context.Context, in *GetChatSessionsByIdReq, opts ...grpc.CallOption) (*GetChatSessionsByIdResp, error) {
|
|
||||||
client := pb.NewChatServiceClient(m.cli.Conn())
|
|
||||||
return client.GetChatSessionsById(ctx, in, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *defaultChatService) SearchChatSessions(ctx context.Context, in *SearchChatSessionsReq, opts ...grpc.CallOption) (*SearchChatSessionsResp, error) {
|
|
||||||
client := pb.NewChatServiceClient(m.cli.Conn())
|
|
||||||
return client.SearchChatSessions(ctx, in, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *defaultChatService) AddParticipant(ctx context.Context, in *AddParticipantReq, opts ...grpc.CallOption) (*AddParticipantResp, error) {
|
|
||||||
client := pb.NewChatServiceClient(m.cli.Conn())
|
|
||||||
return client.AddParticipant(ctx, in, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *defaultChatService) RemoveParticipant(ctx context.Context, in *RemoveParticipantReq, opts ...grpc.CallOption) (*RemoveParticipantResp, error) {
|
|
||||||
client := pb.NewChatServiceClient(m.cli.Conn())
|
|
||||||
return client.RemoveParticipant(ctx, in, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *defaultChatService) AddChatMessages(ctx context.Context, in *AddChatMessagesReq, opts ...grpc.CallOption) (*AddChatMessagesResp, error) {
|
|
||||||
client := pb.NewChatServiceClient(m.cli.Conn())
|
|
||||||
return client.AddChatMessages(ctx, in, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *defaultChatService) DelChatMessages(ctx context.Context, in *DelChatMessagesReq, opts ...grpc.CallOption) (*DelChatMessagesResp, error) {
|
|
||||||
client := pb.NewChatServiceClient(m.cli.Conn())
|
|
||||||
return client.DelChatMessages(ctx, in, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *defaultChatService) GetChatMessagesById(ctx context.Context, in *GetChatMessagesByIdReq, opts ...grpc.CallOption) (*GetChatMessagesByIdResp, error) {
|
|
||||||
client := pb.NewChatServiceClient(m.cli.Conn())
|
|
||||||
return client.GetChatMessagesById(ctx, in, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *defaultChatService) SearchChatMessages(ctx context.Context, in *SearchChatMessagesReq, opts ...grpc.CallOption) (*SearchChatMessagesResp, error) {
|
|
||||||
client := pb.NewChatServiceClient(m.cli.Conn())
|
|
||||||
return client.SearchChatMessages(ctx, in, opts...)
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
Name: pb.rpc
|
|
||||||
ListenOn: 0.0.0.0:8080
|
|
||||||
|
|
||||||
Log:
|
|
||||||
Level: debug
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import "github.com/zeromicro/go-zero/zrpc"
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
zrpc.RpcServerConf
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"juwan-backend/app/chat/rpc/internal/svc"
|
|
||||||
"juwan-backend/app/chat/rpc/pb"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type AddChatMessagesLogic struct {
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
logx.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewAddChatMessagesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddChatMessagesLogic {
|
|
||||||
return &AddChatMessagesLogic{
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *AddChatMessagesLogic) AddChatMessages(in *pb.AddChatMessagesReq) (*pb.AddChatMessagesResp, error) {
|
|
||||||
if in.GetSessionId() <= 0 {
|
|
||||||
return nil, errors.New("sessionId is required")
|
|
||||||
}
|
|
||||||
if in.GetSenderId() <= 0 {
|
|
||||||
return nil, errors.New("senderId is required")
|
|
||||||
}
|
|
||||||
if in.GetContent() == "" {
|
|
||||||
return nil, errors.New("content is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
store := l.svcCtx.Store
|
|
||||||
store.Mu.Lock()
|
|
||||||
defer store.Mu.Unlock()
|
|
||||||
|
|
||||||
if _, ok := store.Sessions[in.GetSessionId()]; !ok {
|
|
||||||
return nil, errors.New("session not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
now := nowUnix(0)
|
|
||||||
msgType := in.GetType()
|
|
||||||
if msgType == "" {
|
|
||||||
msgType = "text"
|
|
||||||
}
|
|
||||||
|
|
||||||
msg := &pb.ChatMessages{
|
|
||||||
Id: store.NextMessage(),
|
|
||||||
SessionId: in.GetSessionId(),
|
|
||||||
SenderId: in.GetSenderId(),
|
|
||||||
Type: msgType,
|
|
||||||
Content: in.GetContent(),
|
|
||||||
CreatedAt: now,
|
|
||||||
}
|
|
||||||
store.Messages[msg.Id] = msg
|
|
||||||
store.SessionMessages[in.GetSessionId()] = append(store.SessionMessages[in.GetSessionId()], msg.Id)
|
|
||||||
|
|
||||||
session := store.Sessions[in.GetSessionId()]
|
|
||||||
session.LastMessage = in.GetContent()
|
|
||||||
session.LastMessageAt = now
|
|
||||||
session.UpdatedAt = now
|
|
||||||
|
|
||||||
return &pb.AddChatMessagesResp{Id: msg.Id}, nil
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"juwan-backend/app/chat/rpc/internal/svc"
|
|
||||||
"juwan-backend/app/chat/rpc/pb"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type AddChatSessionsLogic struct {
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
logx.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewAddChatSessionsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddChatSessionsLogic {
|
|
||||||
return &AddChatSessionsLogic{
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *AddChatSessionsLogic) AddChatSessions(in *pb.AddChatSessionsReq) (*pb.AddChatSessionsResp, error) {
|
|
||||||
if in.GetType() == "" {
|
|
||||||
return nil, errors.New("type is required")
|
|
||||||
}
|
|
||||||
if in.GetCreatorId() <= 0 {
|
|
||||||
return nil, errors.New("creatorId is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
store := l.svcCtx.Store
|
|
||||||
store.Mu.Lock()
|
|
||||||
defer store.Mu.Unlock()
|
|
||||||
|
|
||||||
now := nowUnix(0)
|
|
||||||
participants := append([]int64(nil), in.GetParticipants()...)
|
|
||||||
hasCreator := false
|
|
||||||
for _, p := range participants {
|
|
||||||
if p == in.GetCreatorId() {
|
|
||||||
hasCreator = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !hasCreator {
|
|
||||||
participants = append(participants, in.GetCreatorId())
|
|
||||||
}
|
|
||||||
|
|
||||||
session := &pb.ChatSessions{
|
|
||||||
Id: store.NextSession(),
|
|
||||||
Type: in.GetType(),
|
|
||||||
Name: in.GetName(),
|
|
||||||
CreatorId: in.GetCreatorId(),
|
|
||||||
Participants: participants,
|
|
||||||
CreatedAt: now,
|
|
||||||
UpdatedAt: now,
|
|
||||||
}
|
|
||||||
store.Sessions[session.Id] = session
|
|
||||||
|
|
||||||
return &pb.AddChatSessionsResp{Id: session.Id}, nil
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"juwan-backend/app/chat/rpc/internal/svc"
|
|
||||||
"juwan-backend/app/chat/rpc/pb"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type AddParticipantLogic struct {
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
logx.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewAddParticipantLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddParticipantLogic {
|
|
||||||
return &AddParticipantLogic{
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *AddParticipantLogic) AddParticipant(in *pb.AddParticipantReq) (*pb.AddParticipantResp, error) {
|
|
||||||
store := l.svcCtx.Store
|
|
||||||
store.Mu.Lock()
|
|
||||||
defer store.Mu.Unlock()
|
|
||||||
|
|
||||||
session, ok := store.Sessions[in.GetSessionId()]
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("session not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, p := range session.Participants {
|
|
||||||
if p == in.GetUserId() {
|
|
||||||
return &pb.AddParticipantResp{}, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
session.Participants = append(session.Participants, in.GetUserId())
|
|
||||||
session.UpdatedAt = nowUnix(0)
|
|
||||||
|
|
||||||
return &pb.AddParticipantResp{}, nil
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"juwan-backend/app/chat/rpc/internal/svc"
|
|
||||||
"juwan-backend/app/chat/rpc/pb"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DelChatMessagesLogic struct {
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
logx.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDelChatMessagesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DelChatMessagesLogic {
|
|
||||||
return &DelChatMessagesLogic{
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *DelChatMessagesLogic) DelChatMessages(in *pb.DelChatMessagesReq) (*pb.DelChatMessagesResp, error) {
|
|
||||||
store := l.svcCtx.Store
|
|
||||||
store.Mu.Lock()
|
|
||||||
defer store.Mu.Unlock()
|
|
||||||
|
|
||||||
msg, ok := store.Messages[in.GetId()]
|
|
||||||
if ok {
|
|
||||||
ids := store.SessionMessages[msg.SessionId]
|
|
||||||
filtered := make([]int64, 0, len(ids))
|
|
||||||
for _, id := range ids {
|
|
||||||
if id != in.GetId() {
|
|
||||||
filtered = append(filtered, id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
store.SessionMessages[msg.SessionId] = filtered
|
|
||||||
}
|
|
||||||
delete(store.Messages, in.GetId())
|
|
||||||
|
|
||||||
return &pb.DelChatMessagesResp{}, nil
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"juwan-backend/app/chat/rpc/internal/svc"
|
|
||||||
"juwan-backend/app/chat/rpc/pb"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DelChatSessionsLogic struct {
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
logx.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDelChatSessionsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DelChatSessionsLogic {
|
|
||||||
return &DelChatSessionsLogic{
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *DelChatSessionsLogic) DelChatSessions(in *pb.DelChatSessionsReq) (*pb.DelChatSessionsResp, error) {
|
|
||||||
store := l.svcCtx.Store
|
|
||||||
store.Mu.Lock()
|
|
||||||
defer store.Mu.Unlock()
|
|
||||||
|
|
||||||
delete(store.Sessions, in.GetId())
|
|
||||||
delete(store.SessionMessages, in.GetId())
|
|
||||||
|
|
||||||
return &pb.DelChatSessionsResp{}, nil
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"juwan-backend/app/chat/rpc/internal/svc"
|
|
||||||
"juwan-backend/app/chat/rpc/pb"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GetChatMessagesByIdLogic struct {
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
logx.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGetChatMessagesByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetChatMessagesByIdLogic {
|
|
||||||
return &GetChatMessagesByIdLogic{
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *GetChatMessagesByIdLogic) GetChatMessagesById(in *pb.GetChatMessagesByIdReq) (*pb.GetChatMessagesByIdResp, error) {
|
|
||||||
store := l.svcCtx.Store
|
|
||||||
store.Mu.RLock()
|
|
||||||
defer store.Mu.RUnlock()
|
|
||||||
|
|
||||||
msg, ok := store.Messages[in.GetId()]
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("message not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.GetChatMessagesByIdResp{ChatMessages: msg}, nil
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"juwan-backend/app/chat/rpc/internal/svc"
|
|
||||||
"juwan-backend/app/chat/rpc/pb"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GetChatSessionsByIdLogic struct {
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
logx.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGetChatSessionsByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetChatSessionsByIdLogic {
|
|
||||||
return &GetChatSessionsByIdLogic{
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *GetChatSessionsByIdLogic) GetChatSessionsById(in *pb.GetChatSessionsByIdReq) (*pb.GetChatSessionsByIdResp, error) {
|
|
||||||
store := l.svcCtx.Store
|
|
||||||
store.Mu.RLock()
|
|
||||||
defer store.Mu.RUnlock()
|
|
||||||
|
|
||||||
session, ok := store.Sessions[in.GetId()]
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("session not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.GetChatSessionsByIdResp{ChatSessions: session}, nil
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
func nowUnix(ts int64) int64 {
|
|
||||||
if ts > 0 {
|
|
||||||
return ts
|
|
||||||
}
|
|
||||||
return time.Now().Unix()
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"juwan-backend/app/chat/rpc/internal/svc"
|
|
||||||
"juwan-backend/app/chat/rpc/pb"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RemoveParticipantLogic struct {
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
logx.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRemoveParticipantLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RemoveParticipantLogic {
|
|
||||||
return &RemoveParticipantLogic{
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *RemoveParticipantLogic) RemoveParticipant(in *pb.RemoveParticipantReq) (*pb.RemoveParticipantResp, error) {
|
|
||||||
store := l.svcCtx.Store
|
|
||||||
store.Mu.Lock()
|
|
||||||
defer store.Mu.Unlock()
|
|
||||||
|
|
||||||
session, ok := store.Sessions[in.GetSessionId()]
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("session not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
filtered := make([]int64, 0, len(session.Participants))
|
|
||||||
for _, p := range session.Participants {
|
|
||||||
if p != in.GetUserId() {
|
|
||||||
filtered = append(filtered, p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
session.Participants = filtered
|
|
||||||
session.UpdatedAt = nowUnix(0)
|
|
||||||
|
|
||||||
return &pb.RemoveParticipantResp{}, nil
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"juwan-backend/app/chat/rpc/internal/svc"
|
|
||||||
"juwan-backend/app/chat/rpc/pb"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SearchChatMessagesLogic struct {
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
logx.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSearchChatMessagesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SearchChatMessagesLogic {
|
|
||||||
return &SearchChatMessagesLogic{
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *SearchChatMessagesLogic) SearchChatMessages(in *pb.SearchChatMessagesReq) (*pb.SearchChatMessagesResp, error) {
|
|
||||||
store := l.svcCtx.Store
|
|
||||||
store.Mu.RLock()
|
|
||||||
defer store.Mu.RUnlock()
|
|
||||||
|
|
||||||
msgIDs := store.SessionMessages[in.GetSessionId()]
|
|
||||||
var results []*pb.ChatMessages
|
|
||||||
for _, id := range msgIDs {
|
|
||||||
msg, ok := store.Messages[id]
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if in.SenderId != nil && msg.SenderId != *in.SenderId {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
results = append(results, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
limit := in.GetLimit()
|
|
||||||
if limit <= 0 {
|
|
||||||
limit = 20
|
|
||||||
}
|
|
||||||
offset := in.GetPage() * limit
|
|
||||||
if offset >= int64(len(results)) {
|
|
||||||
return &pb.SearchChatMessagesResp{}, nil
|
|
||||||
}
|
|
||||||
end := offset + limit
|
|
||||||
if end > int64(len(results)) {
|
|
||||||
end = int64(len(results))
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.SearchChatMessagesResp{ChatMessages: results[offset:end]}, nil
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"juwan-backend/app/chat/rpc/internal/svc"
|
|
||||||
"juwan-backend/app/chat/rpc/pb"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SearchChatSessionsLogic struct {
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
logx.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSearchChatSessionsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SearchChatSessionsLogic {
|
|
||||||
return &SearchChatSessionsLogic{
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *SearchChatSessionsLogic) SearchChatSessions(in *pb.SearchChatSessionsReq) (*pb.SearchChatSessionsResp, error) {
|
|
||||||
store := l.svcCtx.Store
|
|
||||||
store.Mu.RLock()
|
|
||||||
defer store.Mu.RUnlock()
|
|
||||||
|
|
||||||
var results []*pb.ChatSessions
|
|
||||||
for _, s := range store.Sessions {
|
|
||||||
if in.Type != nil && s.Type != *in.Type {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if in.UserId != nil {
|
|
||||||
found := false
|
|
||||||
for _, p := range s.Participants {
|
|
||||||
if p == *in.UserId {
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
results = append(results, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
limit := in.GetLimit()
|
|
||||||
if limit <= 0 {
|
|
||||||
limit = 20
|
|
||||||
}
|
|
||||||
offset := in.GetPage() * limit
|
|
||||||
if offset >= int64(len(results)) {
|
|
||||||
return &pb.SearchChatSessionsResp{}, nil
|
|
||||||
}
|
|
||||||
end := offset + limit
|
|
||||||
if end > int64(len(results)) {
|
|
||||||
end = int64(len(results))
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.SearchChatSessionsResp{ChatSessions: results[offset:end]}, nil
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"juwan-backend/app/chat/rpc/internal/svc"
|
|
||||||
"juwan-backend/app/chat/rpc/pb"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UpdateChatSessionsLogic struct {
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
logx.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewUpdateChatSessionsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateChatSessionsLogic {
|
|
||||||
return &UpdateChatSessionsLogic{
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *UpdateChatSessionsLogic) UpdateChatSessions(in *pb.UpdateChatSessionsReq) (*pb.UpdateChatSessionsResp, error) {
|
|
||||||
store := l.svcCtx.Store
|
|
||||||
store.Mu.Lock()
|
|
||||||
defer store.Mu.Unlock()
|
|
||||||
|
|
||||||
session, ok := store.Sessions[in.GetId()]
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("session not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
if in.Name != nil {
|
|
||||||
session.Name = *in.Name
|
|
||||||
}
|
|
||||||
if in.LastMessage != nil {
|
|
||||||
session.LastMessage = *in.LastMessage
|
|
||||||
}
|
|
||||||
if in.LastMessageAt != nil {
|
|
||||||
session.LastMessageAt = *in.LastMessageAt
|
|
||||||
}
|
|
||||||
session.UpdatedAt = nowUnix(0)
|
|
||||||
|
|
||||||
return &pb.UpdateChatSessionsResp{}, nil
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"juwan-backend/app/chat/rpc/internal/logic"
|
|
||||||
"juwan-backend/app/chat/rpc/internal/svc"
|
|
||||||
"juwan-backend/app/chat/rpc/pb"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ChatServiceServer struct {
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
pb.UnimplementedChatServiceServer
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewChatServiceServer(svcCtx *svc.ServiceContext) *ChatServiceServer {
|
|
||||||
return &ChatServiceServer{
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ChatServiceServer) AddChatSessions(ctx context.Context, in *pb.AddChatSessionsReq) (*pb.AddChatSessionsResp, error) {
|
|
||||||
l := logic.NewAddChatSessionsLogic(ctx, s.svcCtx)
|
|
||||||
return l.AddChatSessions(in)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ChatServiceServer) UpdateChatSessions(ctx context.Context, in *pb.UpdateChatSessionsReq) (*pb.UpdateChatSessionsResp, error) {
|
|
||||||
l := logic.NewUpdateChatSessionsLogic(ctx, s.svcCtx)
|
|
||||||
return l.UpdateChatSessions(in)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ChatServiceServer) DelChatSessions(ctx context.Context, in *pb.DelChatSessionsReq) (*pb.DelChatSessionsResp, error) {
|
|
||||||
l := logic.NewDelChatSessionsLogic(ctx, s.svcCtx)
|
|
||||||
return l.DelChatSessions(in)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ChatServiceServer) GetChatSessionsById(ctx context.Context, in *pb.GetChatSessionsByIdReq) (*pb.GetChatSessionsByIdResp, error) {
|
|
||||||
l := logic.NewGetChatSessionsByIdLogic(ctx, s.svcCtx)
|
|
||||||
return l.GetChatSessionsById(in)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ChatServiceServer) SearchChatSessions(ctx context.Context, in *pb.SearchChatSessionsReq) (*pb.SearchChatSessionsResp, error) {
|
|
||||||
l := logic.NewSearchChatSessionsLogic(ctx, s.svcCtx)
|
|
||||||
return l.SearchChatSessions(in)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ChatServiceServer) AddParticipant(ctx context.Context, in *pb.AddParticipantReq) (*pb.AddParticipantResp, error) {
|
|
||||||
l := logic.NewAddParticipantLogic(ctx, s.svcCtx)
|
|
||||||
return l.AddParticipant(in)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ChatServiceServer) RemoveParticipant(ctx context.Context, in *pb.RemoveParticipantReq) (*pb.RemoveParticipantResp, error) {
|
|
||||||
l := logic.NewRemoveParticipantLogic(ctx, s.svcCtx)
|
|
||||||
return l.RemoveParticipant(in)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ChatServiceServer) AddChatMessages(ctx context.Context, in *pb.AddChatMessagesReq) (*pb.AddChatMessagesResp, error) {
|
|
||||||
l := logic.NewAddChatMessagesLogic(ctx, s.svcCtx)
|
|
||||||
return l.AddChatMessages(in)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ChatServiceServer) DelChatMessages(ctx context.Context, in *pb.DelChatMessagesReq) (*pb.DelChatMessagesResp, error) {
|
|
||||||
l := logic.NewDelChatMessagesLogic(ctx, s.svcCtx)
|
|
||||||
return l.DelChatMessages(in)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ChatServiceServer) GetChatMessagesById(ctx context.Context, in *pb.GetChatMessagesByIdReq) (*pb.GetChatMessagesByIdResp, error) {
|
|
||||||
l := logic.NewGetChatMessagesByIdLogic(ctx, s.svcCtx)
|
|
||||||
return l.GetChatMessagesById(in)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ChatServiceServer) SearchChatMessages(ctx context.Context, in *pb.SearchChatMessagesReq) (*pb.SearchChatMessagesResp, error) {
|
|
||||||
l := logic.NewSearchChatMessagesLogic(ctx, s.svcCtx)
|
|
||||||
return l.SearchChatMessages(in)
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package svc
|
|
||||||
|
|
||||||
import "juwan-backend/app/chat/rpc/internal/config"
|
|
||||||
|
|
||||||
type ServiceContext struct {
|
|
||||||
Config config.Config
|
|
||||||
Store *ChatStore
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
|
||||||
return &ServiceContext{
|
|
||||||
Config: c,
|
|
||||||
Store: NewChatStore(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package svc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"juwan-backend/app/chat/rpc/pb"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ChatStore struct {
|
|
||||||
Mu sync.RWMutex
|
|
||||||
|
|
||||||
nextSessionID int64
|
|
||||||
nextMessageID int64
|
|
||||||
|
|
||||||
Sessions map[int64]*pb.ChatSessions
|
|
||||||
Messages map[int64]*pb.ChatMessages
|
|
||||||
SessionMessages map[int64][]int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewChatStore() *ChatStore {
|
|
||||||
return &ChatStore{
|
|
||||||
nextSessionID: 1000,
|
|
||||||
nextMessageID: 1000,
|
|
||||||
Sessions: make(map[int64]*pb.ChatSessions),
|
|
||||||
Messages: make(map[int64]*pb.ChatMessages),
|
|
||||||
SessionMessages: make(map[int64][]int64),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ChatStore) NextSession() int64 {
|
|
||||||
s.nextSessionID++
|
|
||||||
return s.nextSessionID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ChatStore) NextMessage() int64 {
|
|
||||||
s.nextMessageID++
|
|
||||||
return s.nextMessageID
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"juwan-backend/app/chat/rpc/internal/config"
|
|
||||||
"juwan-backend/app/chat/rpc/internal/server"
|
|
||||||
"juwan-backend/app/chat/rpc/internal/svc"
|
|
||||||
"juwan-backend/app/chat/rpc/pb"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/conf"
|
|
||||||
"github.com/zeromicro/go-zero/core/service"
|
|
||||||
"github.com/zeromicro/go-zero/zrpc"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
"google.golang.org/grpc/reflection"
|
|
||||||
)
|
|
||||||
|
|
||||||
var configFile = flag.String("f", "etc/pb.yaml", "the config file")
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
var c config.Config
|
|
||||||
conf.MustLoad(*configFile, &c)
|
|
||||||
ctx := svc.NewServiceContext(c)
|
|
||||||
|
|
||||||
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
|
|
||||||
pb.RegisterChatServiceServer(grpcServer, server.NewChatServiceServer(ctx))
|
|
||||||
|
|
||||||
if c.Mode == service.DevMode || c.Mode == service.TestMode {
|
|
||||||
reflection.Register(grpcServer)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
defer s.Stop()
|
|
||||||
|
|
||||||
fmt.Printf("Starting rpc server at %s...\n", c.ListenOn)
|
|
||||||
s.Start()
|
|
||||||
}
|
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
package pb
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ChatServiceServer interface {
|
|
||||||
AddChatSessions(context.Context, *AddChatSessionsReq) (*AddChatSessionsResp, error)
|
|
||||||
UpdateChatSessions(context.Context, *UpdateChatSessionsReq) (*UpdateChatSessionsResp, error)
|
|
||||||
DelChatSessions(context.Context, *DelChatSessionsReq) (*DelChatSessionsResp, error)
|
|
||||||
GetChatSessionsById(context.Context, *GetChatSessionsByIdReq) (*GetChatSessionsByIdResp, error)
|
|
||||||
SearchChatSessions(context.Context, *SearchChatSessionsReq) (*SearchChatSessionsResp, error)
|
|
||||||
AddParticipant(context.Context, *AddParticipantReq) (*AddParticipantResp, error)
|
|
||||||
RemoveParticipant(context.Context, *RemoveParticipantReq) (*RemoveParticipantResp, error)
|
|
||||||
AddChatMessages(context.Context, *AddChatMessagesReq) (*AddChatMessagesResp, error)
|
|
||||||
DelChatMessages(context.Context, *DelChatMessagesReq) (*DelChatMessagesResp, error)
|
|
||||||
GetChatMessagesById(context.Context, *GetChatMessagesByIdReq) (*GetChatMessagesByIdResp, error)
|
|
||||||
SearchChatMessages(context.Context, *SearchChatMessagesReq) (*SearchChatMessagesResp, error)
|
|
||||||
mustEmbedUnimplementedChatServiceServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
type UnimplementedChatServiceServer struct{}
|
|
||||||
|
|
||||||
func (UnimplementedChatServiceServer) AddChatSessions(context.Context, *AddChatSessionsReq) (*AddChatSessionsResp, error) {
|
|
||||||
return nil, grpc.Errorf(12, "method AddChatSessions not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedChatServiceServer) UpdateChatSessions(context.Context, *UpdateChatSessionsReq) (*UpdateChatSessionsResp, error) {
|
|
||||||
return nil, grpc.Errorf(12, "method UpdateChatSessions not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedChatServiceServer) DelChatSessions(context.Context, *DelChatSessionsReq) (*DelChatSessionsResp, error) {
|
|
||||||
return nil, grpc.Errorf(12, "method DelChatSessions not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedChatServiceServer) GetChatSessionsById(context.Context, *GetChatSessionsByIdReq) (*GetChatSessionsByIdResp, error) {
|
|
||||||
return nil, grpc.Errorf(12, "method GetChatSessionsById not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedChatServiceServer) SearchChatSessions(context.Context, *SearchChatSessionsReq) (*SearchChatSessionsResp, error) {
|
|
||||||
return nil, grpc.Errorf(12, "method SearchChatSessions not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedChatServiceServer) AddParticipant(context.Context, *AddParticipantReq) (*AddParticipantResp, error) {
|
|
||||||
return nil, grpc.Errorf(12, "method AddParticipant not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedChatServiceServer) RemoveParticipant(context.Context, *RemoveParticipantReq) (*RemoveParticipantResp, error) {
|
|
||||||
return nil, grpc.Errorf(12, "method RemoveParticipant not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedChatServiceServer) AddChatMessages(context.Context, *AddChatMessagesReq) (*AddChatMessagesResp, error) {
|
|
||||||
return nil, grpc.Errorf(12, "method AddChatMessages not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedChatServiceServer) DelChatMessages(context.Context, *DelChatMessagesReq) (*DelChatMessagesResp, error) {
|
|
||||||
return nil, grpc.Errorf(12, "method DelChatMessages not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedChatServiceServer) GetChatMessagesById(context.Context, *GetChatMessagesByIdReq) (*GetChatMessagesByIdResp, error) {
|
|
||||||
return nil, grpc.Errorf(12, "method GetChatMessagesById not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedChatServiceServer) SearchChatMessages(context.Context, *SearchChatMessagesReq) (*SearchChatMessagesResp, error) {
|
|
||||||
return nil, grpc.Errorf(12, "method SearchChatMessages not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedChatServiceServer) mustEmbedUnimplementedChatServiceServer() {}
|
|
||||||
|
|
||||||
type UnsafeChatServiceServer interface {
|
|
||||||
mustEmbedUnimplementedChatServiceServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChatServiceClient interface {
|
|
||||||
AddChatSessions(ctx context.Context, in *AddChatSessionsReq, opts ...grpc.CallOption) (*AddChatSessionsResp, error)
|
|
||||||
UpdateChatSessions(ctx context.Context, in *UpdateChatSessionsReq, opts ...grpc.CallOption) (*UpdateChatSessionsResp, error)
|
|
||||||
DelChatSessions(ctx context.Context, in *DelChatSessionsReq, opts ...grpc.CallOption) (*DelChatSessionsResp, error)
|
|
||||||
GetChatSessionsById(ctx context.Context, in *GetChatSessionsByIdReq, opts ...grpc.CallOption) (*GetChatSessionsByIdResp, error)
|
|
||||||
SearchChatSessions(ctx context.Context, in *SearchChatSessionsReq, opts ...grpc.CallOption) (*SearchChatSessionsResp, error)
|
|
||||||
AddParticipant(ctx context.Context, in *AddParticipantReq, opts ...grpc.CallOption) (*AddParticipantResp, error)
|
|
||||||
RemoveParticipant(ctx context.Context, in *RemoveParticipantReq, opts ...grpc.CallOption) (*RemoveParticipantResp, error)
|
|
||||||
AddChatMessages(ctx context.Context, in *AddChatMessagesReq, opts ...grpc.CallOption) (*AddChatMessagesResp, error)
|
|
||||||
DelChatMessages(ctx context.Context, in *DelChatMessagesReq, opts ...grpc.CallOption) (*DelChatMessagesResp, error)
|
|
||||||
GetChatMessagesById(ctx context.Context, in *GetChatMessagesByIdReq, opts ...grpc.CallOption) (*GetChatMessagesByIdResp, error)
|
|
||||||
SearchChatMessages(ctx context.Context, in *SearchChatMessagesReq, opts ...grpc.CallOption) (*SearchChatMessagesResp, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type chatServiceClient struct {
|
|
||||||
cc grpc.ClientConnInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewChatServiceClient(cc grpc.ClientConnInterface) ChatServiceClient {
|
|
||||||
return &chatServiceClient{cc}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chatServiceClient) AddChatSessions(ctx context.Context, in *AddChatSessionsReq, opts ...grpc.CallOption) (*AddChatSessionsResp, error) {
|
|
||||||
out := new(AddChatSessionsResp)
|
|
||||||
err := c.cc.Invoke(ctx, "/pb.chatService/AddChatSessions", in, out, opts...)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chatServiceClient) UpdateChatSessions(ctx context.Context, in *UpdateChatSessionsReq, opts ...grpc.CallOption) (*UpdateChatSessionsResp, error) {
|
|
||||||
out := new(UpdateChatSessionsResp)
|
|
||||||
err := c.cc.Invoke(ctx, "/pb.chatService/UpdateChatSessions", in, out, opts...)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chatServiceClient) DelChatSessions(ctx context.Context, in *DelChatSessionsReq, opts ...grpc.CallOption) (*DelChatSessionsResp, error) {
|
|
||||||
out := new(DelChatSessionsResp)
|
|
||||||
err := c.cc.Invoke(ctx, "/pb.chatService/DelChatSessions", in, out, opts...)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chatServiceClient) GetChatSessionsById(ctx context.Context, in *GetChatSessionsByIdReq, opts ...grpc.CallOption) (*GetChatSessionsByIdResp, error) {
|
|
||||||
out := new(GetChatSessionsByIdResp)
|
|
||||||
err := c.cc.Invoke(ctx, "/pb.chatService/GetChatSessionsById", in, out, opts...)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chatServiceClient) SearchChatSessions(ctx context.Context, in *SearchChatSessionsReq, opts ...grpc.CallOption) (*SearchChatSessionsResp, error) {
|
|
||||||
out := new(SearchChatSessionsResp)
|
|
||||||
err := c.cc.Invoke(ctx, "/pb.chatService/SearchChatSessions", in, out, opts...)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chatServiceClient) AddParticipant(ctx context.Context, in *AddParticipantReq, opts ...grpc.CallOption) (*AddParticipantResp, error) {
|
|
||||||
out := new(AddParticipantResp)
|
|
||||||
err := c.cc.Invoke(ctx, "/pb.chatService/AddParticipant", in, out, opts...)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chatServiceClient) RemoveParticipant(ctx context.Context, in *RemoveParticipantReq, opts ...grpc.CallOption) (*RemoveParticipantResp, error) {
|
|
||||||
out := new(RemoveParticipantResp)
|
|
||||||
err := c.cc.Invoke(ctx, "/pb.chatService/RemoveParticipant", in, out, opts...)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chatServiceClient) AddChatMessages(ctx context.Context, in *AddChatMessagesReq, opts ...grpc.CallOption) (*AddChatMessagesResp, error) {
|
|
||||||
out := new(AddChatMessagesResp)
|
|
||||||
err := c.cc.Invoke(ctx, "/pb.chatService/AddChatMessages", in, out, opts...)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chatServiceClient) DelChatMessages(ctx context.Context, in *DelChatMessagesReq, opts ...grpc.CallOption) (*DelChatMessagesResp, error) {
|
|
||||||
out := new(DelChatMessagesResp)
|
|
||||||
err := c.cc.Invoke(ctx, "/pb.chatService/DelChatMessages", in, out, opts...)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chatServiceClient) GetChatMessagesById(ctx context.Context, in *GetChatMessagesByIdReq, opts ...grpc.CallOption) (*GetChatMessagesByIdResp, error) {
|
|
||||||
out := new(GetChatMessagesByIdResp)
|
|
||||||
err := c.cc.Invoke(ctx, "/pb.chatService/GetChatMessagesById", in, out, opts...)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *chatServiceClient) SearchChatMessages(ctx context.Context, in *SearchChatMessagesReq, opts ...grpc.CallOption) (*SearchChatMessagesResp, error) {
|
|
||||||
out := new(SearchChatMessagesResp)
|
|
||||||
err := c.cc.Invoke(ctx, "/pb.chatService/SearchChatMessages", in, out, opts...)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var ChatService_ServiceDesc = grpc.ServiceDesc{
|
|
||||||
ServiceName: "pb.chatService",
|
|
||||||
HandlerType: (*ChatServiceServer)(nil),
|
|
||||||
Methods: []grpc.MethodDesc{
|
|
||||||
{MethodName: "AddChatSessions", Handler: _ChatService_AddChatSessions_Handler},
|
|
||||||
{MethodName: "UpdateChatSessions", Handler: _ChatService_UpdateChatSessions_Handler},
|
|
||||||
{MethodName: "DelChatSessions", Handler: _ChatService_DelChatSessions_Handler},
|
|
||||||
{MethodName: "GetChatSessionsById", Handler: _ChatService_GetChatSessionsById_Handler},
|
|
||||||
{MethodName: "SearchChatSessions", Handler: _ChatService_SearchChatSessions_Handler},
|
|
||||||
{MethodName: "AddParticipant", Handler: _ChatService_AddParticipant_Handler},
|
|
||||||
{MethodName: "RemoveParticipant", Handler: _ChatService_RemoveParticipant_Handler},
|
|
||||||
{MethodName: "AddChatMessages", Handler: _ChatService_AddChatMessages_Handler},
|
|
||||||
{MethodName: "DelChatMessages", Handler: _ChatService_DelChatMessages_Handler},
|
|
||||||
{MethodName: "GetChatMessagesById", Handler: _ChatService_GetChatMessagesById_Handler},
|
|
||||||
{MethodName: "SearchChatMessages", Handler: _ChatService_SearchChatMessages_Handler},
|
|
||||||
},
|
|
||||||
Streams: []grpc.StreamDesc{},
|
|
||||||
Metadata: "chat.proto",
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterChatServiceServer(s grpc.ServiceRegistrar, srv ChatServiceServer) {
|
|
||||||
s.RegisterService(&ChatService_ServiceDesc, srv)
|
|
||||||
}
|
|
||||||
@@ -1,161 +0,0 @@
|
|||||||
package pb
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
|
||||||
|
|
||||||
func _ChatService_AddChatSessions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(AddChatSessionsReq)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(ChatServiceServer).AddChatSessions(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/pb.chatService/AddChatSessions"}
|
|
||||||
return interceptor(ctx, in, info, func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(ChatServiceServer).AddChatSessions(ctx, req.(*AddChatSessionsReq))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func _ChatService_UpdateChatSessions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(UpdateChatSessionsReq)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(ChatServiceServer).UpdateChatSessions(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/pb.chatService/UpdateChatSessions"}
|
|
||||||
return interceptor(ctx, in, info, func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(ChatServiceServer).UpdateChatSessions(ctx, req.(*UpdateChatSessionsReq))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func _ChatService_DelChatSessions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(DelChatSessionsReq)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(ChatServiceServer).DelChatSessions(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/pb.chatService/DelChatSessions"}
|
|
||||||
return interceptor(ctx, in, info, func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(ChatServiceServer).DelChatSessions(ctx, req.(*DelChatSessionsReq))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func _ChatService_GetChatSessionsById_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(GetChatSessionsByIdReq)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(ChatServiceServer).GetChatSessionsById(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/pb.chatService/GetChatSessionsById"}
|
|
||||||
return interceptor(ctx, in, info, func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(ChatServiceServer).GetChatSessionsById(ctx, req.(*GetChatSessionsByIdReq))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func _ChatService_SearchChatSessions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(SearchChatSessionsReq)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(ChatServiceServer).SearchChatSessions(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/pb.chatService/SearchChatSessions"}
|
|
||||||
return interceptor(ctx, in, info, func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(ChatServiceServer).SearchChatSessions(ctx, req.(*SearchChatSessionsReq))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func _ChatService_AddParticipant_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(AddParticipantReq)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(ChatServiceServer).AddParticipant(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/pb.chatService/AddParticipant"}
|
|
||||||
return interceptor(ctx, in, info, func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(ChatServiceServer).AddParticipant(ctx, req.(*AddParticipantReq))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func _ChatService_RemoveParticipant_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(RemoveParticipantReq)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(ChatServiceServer).RemoveParticipant(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/pb.chatService/RemoveParticipant"}
|
|
||||||
return interceptor(ctx, in, info, func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(ChatServiceServer).RemoveParticipant(ctx, req.(*RemoveParticipantReq))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func _ChatService_AddChatMessages_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(AddChatMessagesReq)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(ChatServiceServer).AddChatMessages(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/pb.chatService/AddChatMessages"}
|
|
||||||
return interceptor(ctx, in, info, func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(ChatServiceServer).AddChatMessages(ctx, req.(*AddChatMessagesReq))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func _ChatService_DelChatMessages_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(DelChatMessagesReq)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(ChatServiceServer).DelChatMessages(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/pb.chatService/DelChatMessages"}
|
|
||||||
return interceptor(ctx, in, info, func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(ChatServiceServer).DelChatMessages(ctx, req.(*DelChatMessagesReq))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func _ChatService_GetChatMessagesById_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(GetChatMessagesByIdReq)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(ChatServiceServer).GetChatMessagesById(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/pb.chatService/GetChatMessagesById"}
|
|
||||||
return interceptor(ctx, in, info, func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(ChatServiceServer).GetChatMessagesById(ctx, req.(*GetChatMessagesByIdReq))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func _ChatService_SearchChatMessages_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(SearchChatMessagesReq)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(ChatServiceServer).SearchChatMessages(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{Server: srv, FullMethod: "/pb.chatService/SearchChatMessages"}
|
|
||||||
return interceptor(ctx, in, info, func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(ChatServiceServer).SearchChatMessages(ctx, req.(*SearchChatMessagesReq))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,179 +0,0 @@
|
|||||||
package pb
|
|
||||||
|
|
||||||
type ChatMessages struct {
|
|
||||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
|
||||||
SessionId int64 `protobuf:"varint,2,opt,name=sessionId,proto3" json:"sessionId,omitempty"`
|
|
||||||
SenderId int64 `protobuf:"varint,3,opt,name=senderId,proto3" json:"senderId,omitempty"`
|
|
||||||
Type string `protobuf:"bytes,4,opt,name=type,proto3" json:"type,omitempty"`
|
|
||||||
Content string `protobuf:"bytes,5,opt,name=content,proto3" json:"content,omitempty"`
|
|
||||||
CreatedAt int64 `protobuf:"varint,6,opt,name=createdAt,proto3" json:"createdAt,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ChatMessages) GetId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Id
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ChatMessages) GetSessionId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.SessionId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ChatMessages) GetSenderId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.SenderId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ChatMessages) GetType() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Type
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ChatMessages) GetContent() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Content
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ChatMessages) GetCreatedAt() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.CreatedAt
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type AddChatMessagesReq struct {
|
|
||||||
SessionId int64 `protobuf:"varint,1,opt,name=sessionId,proto3" json:"sessionId,omitempty"`
|
|
||||||
SenderId int64 `protobuf:"varint,2,opt,name=senderId,proto3" json:"senderId,omitempty"`
|
|
||||||
Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"`
|
|
||||||
Content string `protobuf:"bytes,4,opt,name=content,proto3" json:"content,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AddChatMessagesReq) GetSessionId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.SessionId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AddChatMessagesReq) GetSenderId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.SenderId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AddChatMessagesReq) GetType() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Type
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AddChatMessagesReq) GetContent() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Content
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
type AddChatMessagesResp struct {
|
|
||||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AddChatMessagesResp) GetId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Id
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type DelChatMessagesReq struct {
|
|
||||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *DelChatMessagesReq) GetId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Id
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type DelChatMessagesResp struct{}
|
|
||||||
|
|
||||||
type GetChatMessagesByIdReq struct {
|
|
||||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *GetChatMessagesByIdReq) GetId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Id
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetChatMessagesByIdResp struct {
|
|
||||||
ChatMessages *ChatMessages `protobuf:"bytes,1,opt,name=chatMessages,proto3" json:"chatMessages,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *GetChatMessagesByIdResp) GetChatMessages() *ChatMessages {
|
|
||||||
if x != nil {
|
|
||||||
return x.ChatMessages
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type SearchChatMessagesReq struct {
|
|
||||||
Page int64 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"`
|
|
||||||
Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"`
|
|
||||||
SessionId int64 `protobuf:"varint,3,opt,name=sessionId,proto3" json:"sessionId,omitempty"`
|
|
||||||
SenderId *int64 `protobuf:"varint,4,opt,name=senderId,proto3,oneof" json:"senderId,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SearchChatMessagesReq) GetPage() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Page
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SearchChatMessagesReq) GetLimit() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Limit
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SearchChatMessagesReq) GetSessionId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.SessionId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SearchChatMessagesReq) GetSenderId() *int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.SenderId
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type SearchChatMessagesResp struct {
|
|
||||||
ChatMessages []*ChatMessages `protobuf:"bytes,1,rep,name=chatMessages,proto3" json:"chatMessages,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SearchChatMessagesResp) GetChatMessages() []*ChatMessages {
|
|
||||||
if x != nil {
|
|
||||||
return x.ChatMessages
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,282 +0,0 @@
|
|||||||
package pb
|
|
||||||
|
|
||||||
type ChatSessions struct {
|
|
||||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
|
||||||
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
|
|
||||||
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
|
|
||||||
CreatorId int64 `protobuf:"varint,4,opt,name=creatorId,proto3" json:"creatorId,omitempty"`
|
|
||||||
Participants []int64 `protobuf:"varint,5,rep,packed,name=participants,proto3" json:"participants,omitempty"`
|
|
||||||
LastMessage string `protobuf:"bytes,6,opt,name=lastMessage,proto3" json:"lastMessage,omitempty"`
|
|
||||||
LastMessageAt int64 `protobuf:"varint,7,opt,name=lastMessageAt,proto3" json:"lastMessageAt,omitempty"`
|
|
||||||
CreatedAt int64 `protobuf:"varint,8,opt,name=createdAt,proto3" json:"createdAt,omitempty"`
|
|
||||||
UpdatedAt int64 `protobuf:"varint,9,opt,name=updatedAt,proto3" json:"updatedAt,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ChatSessions) GetId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Id
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ChatSessions) GetType() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Type
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ChatSessions) GetName() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Name
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ChatSessions) GetCreatorId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.CreatorId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ChatSessions) GetParticipants() []int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Participants
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ChatSessions) GetLastMessage() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.LastMessage
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ChatSessions) GetLastMessageAt() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.LastMessageAt
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ChatSessions) GetCreatedAt() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.CreatedAt
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *ChatSessions) GetUpdatedAt() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.UpdatedAt
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type AddChatSessionsReq struct {
|
|
||||||
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
|
|
||||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
|
||||||
CreatorId int64 `protobuf:"varint,3,opt,name=creatorId,proto3" json:"creatorId,omitempty"`
|
|
||||||
Participants []int64 `protobuf:"varint,4,rep,packed,name=participants,proto3" json:"participants,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AddChatSessionsReq) GetType() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Type
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AddChatSessionsReq) GetName() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Name
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AddChatSessionsReq) GetCreatorId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.CreatorId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AddChatSessionsReq) GetParticipants() []int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Participants
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type AddChatSessionsResp struct {
|
|
||||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AddChatSessionsResp) GetId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Id
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type UpdateChatSessionsReq struct {
|
|
||||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
|
||||||
Name *string `protobuf:"bytes,2,opt,name=name,proto3,oneof" json:"name,omitempty"`
|
|
||||||
LastMessage *string `protobuf:"bytes,3,opt,name=lastMessage,proto3,oneof" json:"lastMessage,omitempty"`
|
|
||||||
LastMessageAt *int64 `protobuf:"varint,4,opt,name=lastMessageAt,proto3,oneof" json:"lastMessageAt,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *UpdateChatSessionsReq) GetId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Id
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *UpdateChatSessionsReq) GetName() *string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Name
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *UpdateChatSessionsReq) GetLastMessage() *string {
|
|
||||||
if x != nil {
|
|
||||||
return x.LastMessage
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *UpdateChatSessionsReq) GetLastMessageAt() *int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.LastMessageAt
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type UpdateChatSessionsResp struct{}
|
|
||||||
|
|
||||||
type DelChatSessionsReq struct {
|
|
||||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *DelChatSessionsReq) GetId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Id
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type DelChatSessionsResp struct{}
|
|
||||||
|
|
||||||
type GetChatSessionsByIdReq struct {
|
|
||||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *GetChatSessionsByIdReq) GetId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Id
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetChatSessionsByIdResp struct {
|
|
||||||
ChatSessions *ChatSessions `protobuf:"bytes,1,opt,name=chatSessions,proto3" json:"chatSessions,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *GetChatSessionsByIdResp) GetChatSessions() *ChatSessions {
|
|
||||||
if x != nil {
|
|
||||||
return x.ChatSessions
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type SearchChatSessionsReq struct {
|
|
||||||
Page int64 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"`
|
|
||||||
Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"`
|
|
||||||
UserId *int64 `protobuf:"varint,3,opt,name=userId,proto3,oneof" json:"userId,omitempty"`
|
|
||||||
Type *string `protobuf:"bytes,4,opt,name=type,proto3,oneof" json:"type,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SearchChatSessionsReq) GetPage() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Page
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SearchChatSessionsReq) GetLimit() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.Limit
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SearchChatSessionsReq) GetUserId() *int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.UserId
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SearchChatSessionsReq) GetType() *string {
|
|
||||||
if x != nil {
|
|
||||||
return x.Type
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type SearchChatSessionsResp struct {
|
|
||||||
ChatSessions []*ChatSessions `protobuf:"bytes,1,rep,name=chatSessions,proto3" json:"chatSessions,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SearchChatSessionsResp) GetChatSessions() []*ChatSessions {
|
|
||||||
if x != nil {
|
|
||||||
return x.ChatSessions
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type AddParticipantReq struct {
|
|
||||||
SessionId int64 `protobuf:"varint,1,opt,name=sessionId,proto3" json:"sessionId,omitempty"`
|
|
||||||
UserId int64 `protobuf:"varint,2,opt,name=userId,proto3" json:"userId,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AddParticipantReq) GetSessionId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.SessionId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *AddParticipantReq) GetUserId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.UserId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type AddParticipantResp struct{}
|
|
||||||
|
|
||||||
type RemoveParticipantReq struct {
|
|
||||||
SessionId int64 `protobuf:"varint,1,opt,name=sessionId,proto3" json:"sessionId,omitempty"`
|
|
||||||
UserId int64 `protobuf:"varint,2,opt,name=userId,proto3" json:"userId,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RemoveParticipantReq) GetSessionId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.SessionId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *RemoveParticipantReq) GetUserId() int64 {
|
|
||||||
if x != nil {
|
|
||||||
return x.UserId
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
type RemoveParticipantResp struct{}
|
|
||||||
@@ -3,6 +3,8 @@ FROM golang:1.25-alpine AS builder
|
|||||||
RUN apk add --no-cache git
|
RUN apk add --no-cache git
|
||||||
|
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
|
ENV GOTOOLCHAIN=auto
|
||||||
|
ENV GOPROXY=https://goproxy.cn,direct
|
||||||
|
|
||||||
COPY go-wst/ go-wst/
|
COPY go-wst/ go-wst/
|
||||||
COPY juwan-backend/go.mod juwan-backend/go.sum juwan-backend/
|
COPY juwan-backend/go.mod juwan-backend/go.sum juwan-backend/
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
FROM golang:1.25-alpine AS builder
|
|
||||||
|
|
||||||
RUN apk add --no-cache git
|
|
||||||
|
|
||||||
WORKDIR /build
|
|
||||||
|
|
||||||
COPY go-wst/ go-wst/
|
|
||||||
COPY juwan-backend/go.mod juwan-backend/go.sum juwan-backend/
|
|
||||||
WORKDIR /build/juwan-backend
|
|
||||||
RUN go mod download
|
|
||||||
|
|
||||||
COPY juwan-backend/ /build/juwan-backend/
|
|
||||||
RUN CGO_ENABLED=0 go build -o /chat-rpc ./app/chat/rpc/
|
|
||||||
|
|
||||||
FROM alpine:latest
|
|
||||||
COPY --from=builder /chat-rpc /chat-rpc
|
|
||||||
COPY juwan-backend/app/chat/rpc/etc/pb.yaml /etc/pb.yaml
|
|
||||||
CMD ["/chat-rpc", "-f", "/etc/pb.yaml"]
|
|
||||||
@@ -7,13 +7,20 @@ Hybrid:
|
|||||||
Protocol: auto
|
Protocol: auto
|
||||||
Ws:
|
Ws:
|
||||||
Name: chat-ws
|
Name: chat-ws
|
||||||
Addr: :28888
|
Addr: :28889
|
||||||
Path: /ws/chat
|
Path: /ws/chat
|
||||||
MaxConnections: 10000
|
MaxConnections: 10000
|
||||||
Auth:
|
Auth:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
Source: envoy-header
|
Source: envoy-header
|
||||||
HeaderName: x-auth-user-id
|
HeaderName: x-auth-user-id
|
||||||
|
Wt:
|
||||||
|
Addr: :28443
|
||||||
|
Path: /wt/chat
|
||||||
|
CertFile: /Users/asadz/code/juwan/juwan-backend/app/chat/test/certs/tls.crt
|
||||||
|
KeyFile: /Users/asadz/code/juwan/juwan-backend/app/chat/test/certs/tls.key
|
||||||
|
Auth:
|
||||||
|
Enabled: true
|
||||||
FallbackStrategy: auto
|
FallbackStrategy: auto
|
||||||
MaxRetries: 3
|
MaxRetries: 3
|
||||||
MaxConnections: 10000
|
MaxConnections: 10000
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ Hybrid:
|
|||||||
KeyFile: /etc/certs/tls.key
|
KeyFile: /etc/certs/tls.key
|
||||||
Auth:
|
Auth:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
Auth:
|
||||||
|
Enabled: true
|
||||||
FallbackStrategy: auto
|
FallbackStrategy: auto
|
||||||
MaxRetries: 3
|
MaxRetries: 3
|
||||||
MaxConnections: 10000
|
MaxConnections: 10000
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
Name: pb.rpc
|
|
||||||
ListenOn: 0.0.0.0:28080
|
|
||||||
|
|
||||||
Log:
|
|
||||||
Level: debug
|
|
||||||
@@ -12,7 +12,6 @@ echo ""
|
|||||||
cleanup() {
|
cleanup() {
|
||||||
echo ""
|
echo ""
|
||||||
echo "=== Collecting container logs ==="
|
echo "=== Collecting container logs ==="
|
||||||
docker compose -f "$SCRIPT_DIR/docker-compose.yml" logs chat-rpc > "$LOG_DIR/chat-rpc.log" 2>&1 || true
|
|
||||||
docker compose -f "$SCRIPT_DIR/docker-compose.yml" logs chat-api > "$LOG_DIR/chat-api.log" 2>&1 || true
|
docker compose -f "$SCRIPT_DIR/docker-compose.yml" logs chat-api > "$LOG_DIR/chat-api.log" 2>&1 || true
|
||||||
echo "=== Stopping containers ==="
|
echo "=== Stopping containers ==="
|
||||||
docker compose -f "$SCRIPT_DIR/docker-compose.yml" down --remove-orphans 2>/dev/null || true
|
docker compose -f "$SCRIPT_DIR/docker-compose.yml" down --remove-orphans 2>/dev/null || true
|
||||||
@@ -23,6 +22,22 @@ echo "=== Step 1: Building Docker images ==="
|
|||||||
docker compose -f "$SCRIPT_DIR/docker-compose.yml" build 2>&1 | tee "$LOG_DIR/build.log"
|
docker compose -f "$SCRIPT_DIR/docker-compose.yml" build 2>&1 | tee "$LOG_DIR/build.log"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
echo "=== Step 1.5: Building test tools ==="
|
||||||
|
(cd "$SCRIPT_DIR" && GOTOOLCHAIN=local GOPROXY=https://goproxy.cn,direct go build -o "$SCRIPT_DIR/wt_client" ./wt_client.go 2>&1) | tee -a "$LOG_DIR/build.log"
|
||||||
|
(cd "$SCRIPT_DIR" && GOTOOLCHAIN=local GOPROXY=https://goproxy.cn,direct go build -o "$SCRIPT_DIR/gen_token" ./gen_token.go 2>&1) | tee -a "$LOG_DIR/build.log"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "=== Step 1.6: Generating JWT tokens ==="
|
||||||
|
JWT_SECRET="test-secret"
|
||||||
|
TOKEN_1001=$("$SCRIPT_DIR/gen_token" "$JWT_SECRET" 1001)
|
||||||
|
TOKEN_1002=$("$SCRIPT_DIR/gen_token" "$JWT_SECRET" 1002)
|
||||||
|
TOKEN_2001=$("$SCRIPT_DIR/gen_token" "$JWT_SECRET" 2001)
|
||||||
|
TOKEN_2002=$("$SCRIPT_DIR/gen_token" "$JWT_SECRET" 2002)
|
||||||
|
TOKEN_9001=$("$SCRIPT_DIR/gen_token" "$JWT_SECRET" 9001)
|
||||||
|
echo " user 1001 token: ${TOKEN_1001:0:30}..."
|
||||||
|
echo " user 1002 token: ${TOKEN_1002:0:30}..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
echo "=== Step 2: Starting services ==="
|
echo "=== Step 2: Starting services ==="
|
||||||
docker compose -f "$SCRIPT_DIR/docker-compose.yml" up -d 2>&1 | tee -a "$LOG_DIR/build.log"
|
docker compose -f "$SCRIPT_DIR/docker-compose.yml" up -d 2>&1 | tee -a "$LOG_DIR/build.log"
|
||||||
echo ""
|
echo ""
|
||||||
@@ -39,24 +54,37 @@ sleep 3
|
|||||||
echo "Services should be ready."
|
echo "Services should be ready."
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
VENV_PYTHON="$SCRIPT_DIR/.venv/bin/python3"
|
||||||
|
if [ ! -f "$VENV_PYTHON" ]; then
|
||||||
|
echo "=== Creating Python venv ==="
|
||||||
|
python3 -m venv "$SCRIPT_DIR/.venv"
|
||||||
|
"$VENV_PYTHON" -m pip install websockets -q
|
||||||
|
fi
|
||||||
|
|
||||||
echo "=== Step 4: Running WebSocket tests ==="
|
echo "=== Step 4: Running WebSocket tests ==="
|
||||||
cd "$SCRIPT_DIR"
|
cd "$SCRIPT_DIR"
|
||||||
python3 test_ws.py 2>&1 | tee "$LOG_DIR/ws_test_stdout.log"
|
ALL_PROXY= HTTP_PROXY= HTTPS_PROXY= NO_PROXY=* "$VENV_PYTHON" test_ws.py 2>&1 | tee "$LOG_DIR/ws_test_stdout.log"
|
||||||
WS_RC=${PIPESTATUS[0]}
|
WS_RC=${PIPESTATUS[0]}
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
echo "=== Step 5: Running WebTransport fallback tests ==="
|
echo "=== Step 5: Running WebTransport fallback tests (WS) ==="
|
||||||
python3 test_wt.py 2>&1 | tee "$LOG_DIR/wt_test_stdout.log"
|
ALL_PROXY= HTTP_PROXY= HTTPS_PROXY= NO_PROXY=* "$VENV_PYTHON" test_wt.py 2>&1 | tee "$LOG_DIR/wt_test_stdout.log"
|
||||||
WT_RC=${PIPESTATUS[0]}
|
WT_FALLBACK_RC=${PIPESTATUS[0]}
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "=== Step 6: Running WebTransport native tests (QUIC) ==="
|
||||||
|
ALL_PROXY= HTTP_PROXY= HTTPS_PROXY= NO_PROXY=* "$SCRIPT_DIR/wt_client" "https://localhost:28443/wt/chat?token=${TOKEN_9001}" 2>&1 | tee "$LOG_DIR/wt_native_stdout.log"
|
||||||
|
WT_NATIVE_RC=${PIPESTATUS[0]}
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
echo "=== Test Summary ==="
|
echo "=== Test Summary ==="
|
||||||
echo "WebSocket test: $([ $WS_RC -eq 0 ] && echo 'PASSED' || echo 'FAILED')"
|
echo "WebSocket test: $([ $WS_RC -eq 0 ] && echo 'PASSED' || echo 'FAILED')"
|
||||||
echo "WebTransport test: $([ $WT_RC -eq 0 ] && echo 'PASSED' || echo 'FAILED')"
|
echo "WT fallback test (WS): $([ $WT_FALLBACK_RC -eq 0 ] && echo 'PASSED' || echo 'FAILED')"
|
||||||
|
echo "WT native test (QUIC): $([ $WT_NATIVE_RC -eq 0 ] && echo 'PASSED' || echo 'FAILED')"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Logs saved to: $LOG_DIR/"
|
echo "Logs saved to: $LOG_DIR/"
|
||||||
ls -la "$LOG_DIR/"
|
ls -la "$LOG_DIR/"
|
||||||
|
|
||||||
if [ $WS_RC -ne 0 ] || [ $WT_RC -ne 0 ]; then
|
if [ $WS_RC -ne 0 ] || [ $WT_FALLBACK_RC -ne 0 ] || [ $WT_NATIVE_RC -ne 0 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var c config.Config
|
var c config.Config
|
||||||
conf.MustLoad(*configFile, &c)
|
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||||
|
|
||||||
server := rest.MustNewServer(c.RestConf)
|
server := rest.MustNewServer(c.RestConf)
|
||||||
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
||||||
|
|||||||
@@ -7,16 +7,13 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# ===== PROC CONFIG =====
|
|
||||||
#CommunityRpcConf:
|
|
||||||
# Target: k8s://juwan/community-rpc-svc.juwan:8080
|
|
||||||
#UsercenterRpcConf:
|
|
||||||
# Target: k8s://juwan/users-rpc-svc.juwan:8080
|
|
||||||
|
|
||||||
# ===== DEV CONFIG =====
|
|
||||||
CommunityRpcConf:
|
CommunityRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- community-rpc:8080
|
- "${COMMUNITY_RPC_TARGET}"
|
||||||
|
|
||||||
UsercenterRpcConf:
|
UsercenterRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- user-rpc:8080
|
- "${USER_RPC_TARGET}"
|
||||||
|
|
||||||
|
Log:
|
||||||
|
Level: debug
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
type Comment struct {
|
type Comment struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id,string"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
Author UserProfile `json:"author"`
|
Author UserProfile `json:"author"`
|
||||||
LikeCount int64 `json:"likeCount"`
|
LikeCount int64 `json:"likeCount"`
|
||||||
@@ -54,12 +54,12 @@ type PathId struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Post struct {
|
type Post struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id,string"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
Images []string `json:"images"`
|
Images []string `json:"images"`
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
LinkedOrderId int64 `json:"linkedOrderId,optional"`
|
LinkedOrderId int64 `json:"linkedOrderId,string,optional"`
|
||||||
Pinned bool `json:"pinned"`
|
Pinned bool `json:"pinned"`
|
||||||
LikeCount int64 `json:"likeCount"`
|
LikeCount int64 `json:"likeCount"`
|
||||||
CommentCount int64 `json:"commentCount"`
|
CommentCount int64 `json:"commentCount"`
|
||||||
|
|||||||
@@ -6,36 +6,18 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# ===== PROC CONF =====
|
|
||||||
#SnowflakeRpcConf:
|
|
||||||
# Target: k8s://juwan/snowflake-svc:8080
|
|
||||||
#
|
|
||||||
#DB:
|
|
||||||
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
# Slave: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
#
|
|
||||||
#CacheConf:
|
|
||||||
# - Host: "${REDIS_M_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
# - Host: "${REDIS_S_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
|
|
||||||
# ===== DEV CONF =====
|
|
||||||
SnowflakeRpcConf:
|
SnowflakeRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- snowflake:8080
|
- "${SNOWFLAKE_RPC_TARGET}"
|
||||||
|
|
||||||
DB:
|
DB:
|
||||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
|
|
||||||
CacheConf:
|
CacheConf:
|
||||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||||
Type: node
|
Type: node
|
||||||
|
Pass: "${REDIS_PASSWORD}"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
Level: debug
|
Level: debug
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var c config.Config
|
var c config.Config
|
||||||
conf.MustLoad(*configFile, &c)
|
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||||
|
|
||||||
server := rest.MustNewServer(c.RestConf)
|
server := rest.MustNewServer(c.RestConf)
|
||||||
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
||||||
|
|||||||
@@ -7,13 +7,17 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# ===== DEV CONFIG =====
|
|
||||||
DisputeRpcConf:
|
DisputeRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- dispute-rpc:8080
|
- "${DISPUTE_RPC_TARGET}"
|
||||||
|
|
||||||
OrderRpcConf:
|
OrderRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- order-rpc:8080
|
- "${ORDER_RPC_TARGET}"
|
||||||
|
|
||||||
PlayerRpcConf:
|
PlayerRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- player-rpc:8080
|
- "${PLAYER_RPC_TARGET}"
|
||||||
|
|
||||||
|
Log:
|
||||||
|
Level: debug
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ type CreateDisputeReq struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Dispute struct {
|
type Dispute struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id,string"`
|
||||||
OrderId int64 `json:"orderId"`
|
OrderId int64 `json:"orderId,string"`
|
||||||
InitiatorId int64 `json:"initiatorId"`
|
InitiatorId int64 `json:"initiatorId,string"`
|
||||||
InitiatorName string `json:"initiatorName"`
|
InitiatorName string `json:"initiatorName"`
|
||||||
RespondentId int64 `json:"respondentId"`
|
RespondentId int64 `json:"respondentId,string"`
|
||||||
Reason string `json:"reason"`
|
Reason string `json:"reason"`
|
||||||
Evidence []string `json:"evidence"`
|
Evidence []string `json:"evidence"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
@@ -28,7 +28,7 @@ type Dispute struct {
|
|||||||
RespondentEvidence []string `json:"respondentEvidence"`
|
RespondentEvidence []string `json:"respondentEvidence"`
|
||||||
AppealReason string `json:"appealReason,optional"`
|
AppealReason string `json:"appealReason,optional"`
|
||||||
AppealedAt string `json:"appealedAt,optional"`
|
AppealedAt string `json:"appealedAt,optional"`
|
||||||
ResolvedBy int64 `json:"resolvedBy,optional"`
|
ResolvedBy int64 `json:"resolvedBy,string,optional"`
|
||||||
ResolvedAt string `json:"resolvedAt,optional"`
|
ResolvedAt string `json:"resolvedAt,optional"`
|
||||||
CreatedAt string `json:"createdAt"`
|
CreatedAt string `json:"createdAt"`
|
||||||
UpdatedAt string `json:"updatedAt"`
|
UpdatedAt string `json:"updatedAt"`
|
||||||
|
|||||||
@@ -6,18 +6,18 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# ===== DEV CONF =====
|
|
||||||
SnowflakeRpcConf:
|
SnowflakeRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- snowflake:8080
|
- "${SNOWFLAKE_RPC_TARGET}"
|
||||||
|
|
||||||
DB:
|
DB:
|
||||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
|
|
||||||
CacheConf:
|
CacheConf:
|
||||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||||
Type: node
|
Type: node
|
||||||
|
Pass: "${REDIS_PASSWORD}"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
Level: debug
|
Level: debug
|
||||||
|
|||||||
@@ -7,21 +7,10 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# ===== PROC CONFIG =====
|
|
||||||
#CacheConf:
|
|
||||||
# - Host: "${REDIS_M_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
# - Host: "${REDIS_S_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
|
|
||||||
# ===== DEV CONFIG =====
|
|
||||||
CacheConf:
|
CacheConf:
|
||||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||||
Type: node
|
Type: node
|
||||||
|
Pass: "${REDIS_PASSWORD}"
|
||||||
|
|
||||||
Kmq:
|
Kmq:
|
||||||
Name: email-api
|
Name: email-api
|
||||||
@@ -29,3 +18,6 @@ Kmq:
|
|||||||
- "${KAFKA_BROKER}"
|
- "${KAFKA_BROKER}"
|
||||||
Group: "email-api-group"
|
Group: "email-api-group"
|
||||||
Topic: "email-task"
|
Topic: "email-task"
|
||||||
|
|
||||||
|
Log:
|
||||||
|
Level: debug
|
||||||
|
|||||||
@@ -30,15 +30,5 @@ Mail:
|
|||||||
InsecureSkipVerify: false
|
InsecureSkipVerify: false
|
||||||
ReplyTo: "${EMAIL_REPLY_TO}"
|
ReplyTo: "${EMAIL_REPLY_TO}"
|
||||||
|
|
||||||
# Mail:
|
Log:
|
||||||
# Enabled: true
|
Level: debug
|
||||||
# Host: "smtp.163.com"
|
|
||||||
# Port: 465
|
|
||||||
# Username: "churong2646@163.com"
|
|
||||||
# Password: "GTv6C6qNbv5urAiD"
|
|
||||||
# FromAddress: "churong2646@163.com"
|
|
||||||
# FromName: "聚玩"
|
|
||||||
# UseSSL: true
|
|
||||||
# UseStartTLS: false
|
|
||||||
# InsecureSkipVerify: false
|
|
||||||
# ReplyTo: ""
|
|
||||||
|
|||||||
@@ -7,14 +7,9 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# ===== PROC CONF =====
|
|
||||||
#GameRpcConf:
|
|
||||||
# Target: k8s://juwan/game-rpc-svc:8080
|
|
||||||
|
|
||||||
# ===== DEV CONF =====
|
|
||||||
GameRpcConf:
|
GameRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- game-rpc:8080
|
- "${GAME_RPC_TARGET}"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
Level: debug
|
Level: debug
|
||||||
@@ -22,7 +22,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var c config.Config
|
var c config.Config
|
||||||
conf.MustLoad(*configFile, &c)
|
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||||
|
|
||||||
server := rest.MustNewServer(c.RestConf)
|
server := rest.MustNewServer(c.RestConf)
|
||||||
server.Use(middlewares.NewRequestMiddleware().Handle)
|
server.Use(middlewares.NewRequestMiddleware().Handle)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// Code generated by goctl. DO NOT EDIT.
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
// goctl 1.9.2
|
// goctl 1.10.1
|
||||||
|
|
||||||
package handler
|
package handler
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ type EmptyResp struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Game struct {
|
type Game struct {
|
||||||
Id int64 `json:"id,optional"`
|
Id int64 `json:"id,string,optional"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Icon string `json:"icon"`
|
Icon string `json:"icon"`
|
||||||
Category string `json:"category"`
|
Category string `json:"category"`
|
||||||
|
|||||||
@@ -6,40 +6,18 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# ===== PROC CONF =====
|
|
||||||
#DB:
|
|
||||||
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#SnowflakeRpcConf:
|
|
||||||
# Target: k8s://juwan/snowflake-svc:8080
|
|
||||||
#
|
|
||||||
#CacheConf:
|
|
||||||
# - Host: "${REDIS_M_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
# - Host: "${REDIS_S_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
#
|
|
||||||
#Log:
|
|
||||||
# Level: info
|
|
||||||
|
|
||||||
# ===== DEV CONF =====
|
|
||||||
SnowflakeRpcConf:
|
SnowflakeRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- snowflake:8080
|
- "${SNOWFLAKE_RPC_TARGET}"
|
||||||
|
|
||||||
DB:
|
DB:
|
||||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
|
|
||||||
CacheConf:
|
CacheConf:
|
||||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||||
Type: node
|
Type: node
|
||||||
|
Pass: "${REDIS_PASSWORD}"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
Level: debug
|
Level: debug
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# ===== DEV CONFIG =====
|
|
||||||
NotificationRpcConf:
|
NotificationRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- notification-rpc:8080
|
- "${NOTIFICATION_RPC_TARGET}"
|
||||||
|
|
||||||
|
Log:
|
||||||
|
Level: debug
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ type EmptyResp struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Notification struct {
|
type Notification struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id,string"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var c config.Config
|
var c config.Config
|
||||||
conf.MustLoad(*configFile, &c)
|
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||||
|
|
||||||
server := rest.MustNewServer(c.RestConf)
|
server := rest.MustNewServer(c.RestConf)
|
||||||
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
||||||
|
|||||||
@@ -6,18 +6,18 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# ===== DEV CONF =====
|
|
||||||
SnowflakeRpcConf:
|
SnowflakeRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- snowflake:8080
|
- "${SNOWFLAKE_RPC_TARGET}"
|
||||||
|
|
||||||
DB:
|
DB:
|
||||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
|
|
||||||
CacheConf:
|
CacheConf:
|
||||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||||
Type: node
|
Type: node
|
||||||
|
Pass: "${REDIS_PASSWORD}"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
Level: debug
|
Level: debug
|
||||||
|
|||||||
@@ -7,21 +7,9 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
|
|
||||||
# ===== PROC CONF =====
|
|
||||||
#FileRpcConf:
|
|
||||||
# Target: k8s://juwan/objectstory-rpc-svc:8080
|
|
||||||
#
|
|
||||||
#Log:
|
|
||||||
# Level: info
|
|
||||||
|
|
||||||
# ===== DEV CONF =====
|
|
||||||
FileRpcConf:
|
FileRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- objectstory-rpc:8080
|
- "${OBJECTSTORY_RPC_TARGET}"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
Level: debug
|
Level: debug
|
||||||
|
|
||||||
# k8s://juwan/<service name>:8080
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var c config.Config
|
var c config.Config
|
||||||
conf.MustLoad(*configFile, &c)
|
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||||
|
|
||||||
server := rest.MustNewServer(c.RestConf)
|
server := rest.MustNewServer(c.RestConf)
|
||||||
server.Use(middlewares.NewRequestMiddleware().Handle)
|
server.Use(middlewares.NewRequestMiddleware().Handle)
|
||||||
|
|||||||
@@ -6,36 +6,13 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# Target: k8s://juwan/<service name>.<namespace>:8080
|
|
||||||
#S3Conf:
|
|
||||||
# Endpoint: "${S3_ENDPOINT}"
|
|
||||||
# AccessKey: "${S3_ACCESS_KEY}"
|
|
||||||
# SecretKey: "${S3_SECRET_KEY}"
|
|
||||||
# Bucket: "${S3_BUCKET_NAME}"
|
|
||||||
# Region: "${S3_REGION}"
|
|
||||||
|
|
||||||
S3Conf:
|
S3Conf:
|
||||||
Endpoint: "https://cn-nb1.rains3.com"
|
Endpoint: "${S3_ENDPOINT}"
|
||||||
AccessKey: "mfgGnaAcUDP2zYAi"
|
AccessKey: "${S3_ACCESS_KEY}"
|
||||||
SecretKey: "ZfKkbhUvsAchiKlxzIXrDHrSyskyRj"
|
SecretKey: "${S3_SECRET_KEY}"
|
||||||
Bucket: "juwan-dev-image-zj"
|
Bucket: "${S3_BUCKET_NAME}"
|
||||||
Region: auto
|
Region: "${S3_REGION}"
|
||||||
UsePathStyle: true
|
UsePathStyle: true
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
Level: debug
|
Level: debug
|
||||||
|
|
||||||
#DB:
|
|
||||||
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
#
|
|
||||||
#CacheConf:
|
|
||||||
# - Host: "${REDIS_M_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
# - Host: "${REDIS_S_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
#
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var c config.Config
|
var c config.Config
|
||||||
conf.MustLoad(*configFile, &c)
|
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||||
ctx := svc.NewServiceContext(c)
|
ctx := svc.NewServiceContext(c)
|
||||||
|
|
||||||
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
|
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
|
||||||
|
|||||||
@@ -7,26 +7,17 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# k8s://juwan/<service name>:8080
|
|
||||||
# ===== PROC CONF =====
|
|
||||||
#OrderRpcConf:
|
|
||||||
# Target: k8s://juwan/order-rpc-svc:8080
|
|
||||||
#
|
|
||||||
#PlayerRpcConf:
|
|
||||||
# Target: k8s://juwan/player-rpc-svc:8080
|
|
||||||
#
|
|
||||||
#ShopRpcConf:
|
|
||||||
# Target: k8s://juwan/shop-rpc-svc:8080
|
|
||||||
|
|
||||||
# ===== DEV CONF ====
|
|
||||||
OrderRpcConf:
|
OrderRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- order-rpc:8080
|
- "${ORDER_RPC_TARGET}"
|
||||||
|
|
||||||
PlayerRpcConf:
|
PlayerRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- player-rpc:8080
|
- "${PLAYER_RPC_TARGET}"
|
||||||
|
|
||||||
ShopRpcConf:
|
ShopRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- shop-rpc:8080
|
- "${SHOP_RPC_TARGET}"
|
||||||
|
|
||||||
|
Log:
|
||||||
|
Level: debug
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
type CreateOrderReq struct {
|
type CreateOrderReq struct {
|
||||||
PlayerId int64 `json:"playerId"`
|
PlayerId int64 `json:"playerId,string"`
|
||||||
ShopId int64 `json:"shopId,optional"`
|
ShopId int64 `json:"shopId,string,optional"`
|
||||||
ServiceId int64 `json:"serviceId"`
|
ServiceId int64 `json:"serviceId,string"`
|
||||||
Quantity int `json:"quantity"`
|
Quantity int `json:"quantity"`
|
||||||
Note string `json:"note,optional"`
|
Note string `json:"note,optional"`
|
||||||
}
|
}
|
||||||
@@ -20,10 +20,10 @@ type EmptyResp struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Order struct {
|
type Order struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id,string"`
|
||||||
ConsumerId int64 `json:"consumerId"`
|
ConsumerId int64 `json:"consumerId,string"`
|
||||||
PlayerId string `json:"playerId"`
|
PlayerId string `json:"playerId"`
|
||||||
ShopId int64 `json:"shopId,optional"`
|
ShopId int64 `json:"shopId,string,optional"`
|
||||||
Service PlayerService `json:"service"`
|
Service PlayerService `json:"service"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
TotalPrice float64 `json:"totalPrice"`
|
TotalPrice float64 `json:"totalPrice"`
|
||||||
@@ -60,9 +60,9 @@ type PathId struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PlayerService struct {
|
type PlayerService struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id,string"`
|
||||||
PlayerId int64 `json:"playerId"`
|
PlayerId int64 `json:"playerId,string"`
|
||||||
GameId int64 `json:"gameId"`
|
GameId int64 `json:"gameId,string"`
|
||||||
GameName string `json:"gameName"`
|
GameName string `json:"gameName"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var c config.Config
|
var c config.Config
|
||||||
conf.MustLoad(*configFile, &c)
|
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||||
|
|
||||||
server := rest.MustNewServer(c.RestConf)
|
server := rest.MustNewServer(c.RestConf)
|
||||||
server.Use(middlewares.NewRequestMiddleware().Handle)
|
server.Use(middlewares.NewRequestMiddleware().Handle)
|
||||||
|
|||||||
@@ -1,54 +1,23 @@
|
|||||||
Name: pb.rpc
|
Name: pb.rpc
|
||||||
ListenOn: 0.0.0.0:8080
|
ListenOn: 0.0.0.0:8080
|
||||||
|
|
||||||
|
|
||||||
Prometheus:
|
Prometheus:
|
||||||
Host: 0.0.0.0
|
Host: 0.0.0.0
|
||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# tcd:
|
|
||||||
# Hosts:
|
|
||||||
# - 127.0.0.1:2379
|
|
||||||
# Key: pb.rpc
|
|
||||||
|
|
||||||
# Target: k8s://juwan/<service name>.<namespace>:8080
|
|
||||||
|
|
||||||
# ==== PROC CONF ====
|
|
||||||
#SnowflakeRpcConf:
|
|
||||||
# Target: k8s://juwan/snowflake-svc:8080
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#DB:
|
|
||||||
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#CacheConf:
|
|
||||||
# - Host: "${REDIS_M_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
# - Host: "${REDIS_S_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
#
|
|
||||||
#Log:
|
|
||||||
# Level: info
|
|
||||||
|
|
||||||
# ==== DEV CONF ====
|
|
||||||
SnowflakeRpcConf:
|
SnowflakeRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- snowflake:8080
|
- "${SNOWFLAKE_RPC_TARGET}"
|
||||||
|
|
||||||
DB:
|
DB:
|
||||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
|
|
||||||
CacheConf:
|
CacheConf:
|
||||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||||
Type: node
|
Type: node
|
||||||
|
Pass: "${REDIS_PASSWORD}"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
Level: debug
|
Level: debug
|
||||||
@@ -7,15 +7,13 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# k8s://juwan/<service name>:8080
|
|
||||||
# ===== PROC CONF =====
|
|
||||||
#PlayerRpcConf:
|
|
||||||
# Target: k8s://juwan/player-rpc-svc:8080
|
|
||||||
|
|
||||||
# ===== DEV CONF ====
|
|
||||||
PlayerRpcConf:
|
PlayerRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- player-rpc:8080
|
- "${PLAYER_RPC_TARGET}"
|
||||||
|
|
||||||
UsercenterRpcConf:
|
UsercenterRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- user-rpc:8080
|
- "${USER_RPC_TARGET}"
|
||||||
|
|
||||||
|
Log:
|
||||||
|
Level: debug
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.10.1
|
||||||
|
|
||||||
|
package player
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
"juwan-backend/app/player/api/internal/logic/player"
|
||||||
|
"juwan-backend/app/player/api/internal/svc"
|
||||||
|
"juwan-backend/app/player/api/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 获取当前用户的打手资料
|
||||||
|
func GetMyPlayerHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.EmptyResp
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
l := player.NewGetMyPlayerLogic(r.Context(), svcCtx)
|
||||||
|
resp, err := l.GetMyPlayer(&req)
|
||||||
|
if err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
} else {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -57,6 +57,12 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
|||||||
Path: "/players/me",
|
Path: "/players/me",
|
||||||
Handler: player.InitPlayerHandler(serverCtx),
|
Handler: player.InitPlayerHandler(serverCtx),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// 获取当前用户的打手资料
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/players/me",
|
||||||
|
Handler: player.GetMyPlayerHandler(serverCtx),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
// 更新接单状态
|
// 更新接单状态
|
||||||
Method: http.MethodPut,
|
Method: http.MethodPut,
|
||||||
|
|||||||
@@ -45,11 +45,16 @@ func (l *GetPlayerLogic) GetPlayer(req *types.GetPlayerReq) (resp *types.PlayerP
|
|||||||
if player == nil {
|
if player == nil {
|
||||||
return nil, errors.New("player not found")
|
return nil, errors.New("player not found")
|
||||||
}
|
}
|
||||||
|
completionRate := 0.0
|
||||||
|
if player.TotalOrders > 0 {
|
||||||
|
completionRate = float64(player.CompletedOrders) / float64(player.TotalOrders)
|
||||||
|
}
|
||||||
|
|
||||||
resp = &types.PlayerProfile{
|
resp = &types.PlayerProfile{
|
||||||
Id: player.Id,
|
Id: player.Id,
|
||||||
Rating: player.Rating,
|
Rating: player.Rating,
|
||||||
TotalOrders: player.TotalOrders,
|
TotalOrders: player.TotalOrders,
|
||||||
|
CompletionRate: completionRate,
|
||||||
Status: player.Status,
|
Status: player.Status,
|
||||||
Gender: player.Gender,
|
Gender: player.Gender,
|
||||||
Services: []types.PlayerService{},
|
Services: []types.PlayerService{},
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
// Code scaffolded by goctl. Safe to edit.
|
||||||
|
// goctl 1.10.1
|
||||||
|
|
||||||
|
package player
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"juwan-backend/app/player/api/internal/svc"
|
||||||
|
"juwan-backend/app/player/api/internal/types"
|
||||||
|
"juwan-backend/app/player/rpc/pb"
|
||||||
|
"juwan-backend/app/player/rpc/playerservice"
|
||||||
|
"juwan-backend/app/users/rpc/usercenter"
|
||||||
|
"juwan-backend/common/utils/contextj"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetMyPlayerLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前用户的打手资料
|
||||||
|
func NewGetMyPlayerLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetMyPlayerLogic {
|
||||||
|
return &GetMyPlayerLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GetMyPlayerLogic) GetMyPlayer(req *types.EmptyResp) (resp *types.PlayerProfile, err error) {
|
||||||
|
userID, err := contextj.UserIDFrom(l.ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
playerResp, err := l.svcCtx.PlayerRpc.GetPlayerByUserId(l.ctx, &playerservice.SearchPlayersReq{UserId: &userID})
|
||||||
|
if err != nil {
|
||||||
|
st, _ := status.FromError(err)
|
||||||
|
if st.Code().String() == "NotFound" {
|
||||||
|
return nil, errors.New("player not found")
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
player := playerResp.GetPlayers()
|
||||||
|
if player == nil {
|
||||||
|
return nil, errors.New("player not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
userResp, err := l.svcCtx.UserRpc.GetUsersById(l.ctx, &usercenter.GetUsersByIdReq{Id: userID})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
user := userResp.GetUsers()
|
||||||
|
if user == nil {
|
||||||
|
return nil, errors.New("user not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
games := make([]string, 0, len(player.Games))
|
||||||
|
for _, gameID := range player.Games {
|
||||||
|
games = append(games, strconv.FormatInt(gameID, 10))
|
||||||
|
}
|
||||||
|
|
||||||
|
verificationStatus := map[string]string{}
|
||||||
|
if user.VerificationStatus != "" {
|
||||||
|
_ = json.Unmarshal([]byte(user.VerificationStatus), &verificationStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp = &types.PlayerProfile{
|
||||||
|
Id: player.Id,
|
||||||
|
User: types.UserProfile{
|
||||||
|
Id: strconv.FormatInt(user.Id, 10),
|
||||||
|
Username: user.Username,
|
||||||
|
Nickname: user.Nickname,
|
||||||
|
Avatar: user.Avatar,
|
||||||
|
Role: user.CurrentRole,
|
||||||
|
VerifiedRoles: append([]string{}, user.VerifiedRoles...),
|
||||||
|
VerificationStatus: verificationStatus,
|
||||||
|
Phone: user.Phone,
|
||||||
|
Bio: user.Bio,
|
||||||
|
CreatedAt: time.Unix(user.CreatedAt, 0).Format(time.DateTime),
|
||||||
|
},
|
||||||
|
Rating: player.Rating,
|
||||||
|
TotalOrders: player.TotalOrders,
|
||||||
|
Status: player.Status,
|
||||||
|
Games: games,
|
||||||
|
Services: []types.PlayerService{},
|
||||||
|
Gender: player.Gender,
|
||||||
|
Tags: append([]string{}, player.Tags...),
|
||||||
|
}
|
||||||
|
if player.ShopId != 0 {
|
||||||
|
resp.ShopId = strconv.FormatInt(player.ShopId, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
svcResp, svcErr := l.svcCtx.PlayerRpc.SearchPlayerServices(l.ctx, &pb.SearchPlayerServicesReq{
|
||||||
|
PlayerId: player.Id,
|
||||||
|
Limit: 100,
|
||||||
|
})
|
||||||
|
if svcErr != nil {
|
||||||
|
logx.Errorf("GetMyPlayer SearchPlayerServices player=%d err: %v", player.Id, svcErr)
|
||||||
|
} else {
|
||||||
|
for _, s := range svcResp.PlayerServices {
|
||||||
|
resp.Services = append(resp.Services, types.PlayerService{
|
||||||
|
Id: s.Id,
|
||||||
|
PlayerId: s.PlayerId,
|
||||||
|
GameId: s.GameId,
|
||||||
|
Title: s.Title,
|
||||||
|
Description: s.Description,
|
||||||
|
Price: s.Price,
|
||||||
|
Unit: s.Unit,
|
||||||
|
RankRange: s.RankRange,
|
||||||
|
Availability: s.Availability,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
type CreateServiceReq struct {
|
type CreateServiceReq struct {
|
||||||
GameId int64 `json:"gameId,optional"`
|
GameId int64 `json:"gameId,string,optional"`
|
||||||
Title string `json:"title,optional"`
|
Title string `json:"title,optional"`
|
||||||
Description string `json:"description,optional"`
|
Description string `json:"description,optional"`
|
||||||
Price float64 `json:"price"`
|
Price float64 `json:"price"`
|
||||||
@@ -56,7 +56,7 @@ type PlayerListResp struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PlayerProfile struct {
|
type PlayerProfile struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id,string"`
|
||||||
User UserProfile `json:"user"`
|
User UserProfile `json:"user"`
|
||||||
Rating float64 `json:"rating"`
|
Rating float64 `json:"rating"`
|
||||||
TotalOrders int64 `json:"totalOrders"`
|
TotalOrders int64 `json:"totalOrders"`
|
||||||
@@ -71,9 +71,9 @@ type PlayerProfile struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PlayerService struct {
|
type PlayerService struct {
|
||||||
Id int64 `json:"id,optional"`
|
Id int64 `json:"id,string,optional"`
|
||||||
PlayerId int64 `json:"playerId"`
|
PlayerId int64 `json:"playerId,string"`
|
||||||
GameId int64 `json:"gameId"`
|
GameId int64 `json:"gameId,string"`
|
||||||
GameName string `json:"gameName"`
|
GameName string `json:"gameName"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
@@ -100,7 +100,7 @@ type UpdatePlayerStatusReq struct {
|
|||||||
|
|
||||||
type UpdateServiceReq struct {
|
type UpdateServiceReq struct {
|
||||||
Id int64 `path:"id"`
|
Id int64 `path:"id"`
|
||||||
GameId *int64 `json:"gameId,optional"`
|
GameId *int64 `json:"gameId,string,optional"`
|
||||||
Title *string `json:"title,optional"`
|
Title *string `json:"title,optional"`
|
||||||
Description *string `json:"description,optional"`
|
Description *string `json:"description,optional"`
|
||||||
Price *float64 `json:"price,optional"`
|
Price *float64 `json:"price,optional"`
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var c config.Config
|
var c config.Config
|
||||||
conf.MustLoad(*configFile, &c)
|
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||||
|
|
||||||
server := rest.MustNewServer(c.RestConf)
|
server := rest.MustNewServer(c.RestConf)
|
||||||
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
||||||
|
|||||||
@@ -1,48 +1,23 @@
|
|||||||
Name: pb.rpc
|
Name: pb.rpc
|
||||||
ListenOn: 0.0.0.0:8080
|
ListenOn: 0.0.0.0:8080
|
||||||
|
|
||||||
|
|
||||||
Prometheus:
|
Prometheus:
|
||||||
Host: 0.0.0.0
|
Host: 0.0.0.0
|
||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ===== PROC CONF =====
|
|
||||||
#SnowflakeRpcConf:
|
|
||||||
# Target: k8s://juwan/snowflake-svc:8080
|
|
||||||
|
|
||||||
#DB:
|
|
||||||
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
#
|
|
||||||
#CacheConf:
|
|
||||||
# - Host: "${REDIS_M_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
# - Host: "${REDIS_S_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
#
|
|
||||||
#Log:
|
|
||||||
# Level: info
|
|
||||||
|
|
||||||
# ===== DEV CONF =====
|
|
||||||
SnowflakeRpcConf:
|
SnowflakeRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- snowflake:8080
|
- "${SNOWFLAKE_RPC_TARGET}"
|
||||||
|
|
||||||
DB:
|
DB:
|
||||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
|
|
||||||
CacheConf:
|
CacheConf:
|
||||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||||
Type: node
|
Type: node
|
||||||
|
Pass: "${REDIS_PASSWORD}"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
Level: debug
|
Level: debug
|
||||||
|
|||||||
@@ -7,13 +7,17 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# ===== DEV CONFIG =====
|
|
||||||
ReviewRpcConf:
|
ReviewRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- review-rpc:8080
|
- "${REVIEW_RPC_TARGET}"
|
||||||
|
|
||||||
OrderRpcConf:
|
OrderRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- order-rpc:8080
|
- "${ORDER_RPC_TARGET}"
|
||||||
|
|
||||||
PlayerRpcConf:
|
PlayerRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- player-rpc:8080
|
- "${PLAYER_RPC_TARGET}"
|
||||||
|
|
||||||
|
Log:
|
||||||
|
Level: debug
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ type PageReq struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Review struct {
|
type Review struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id,string"`
|
||||||
OrderId int64 `json:"orderId"`
|
OrderId int64 `json:"orderId,string"`
|
||||||
FromUserId int64 `json:"fromUserId"`
|
FromUserId int64 `json:"fromUserId,string"`
|
||||||
FromUserName string `json:"fromUserName"`
|
FromUserName string `json:"fromUserName"`
|
||||||
Rating int `json:"rating"`
|
Rating int `json:"rating"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var c config.Config
|
var c config.Config
|
||||||
conf.MustLoad(*configFile, &c)
|
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||||
|
|
||||||
server := rest.MustNewServer(c.RestConf)
|
server := rest.MustNewServer(c.RestConf)
|
||||||
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
||||||
|
|||||||
@@ -6,18 +6,18 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# ===== DEV CONF =====
|
|
||||||
SnowflakeRpcConf:
|
SnowflakeRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- snowflake:8080
|
- "${SNOWFLAKE_RPC_TARGET}"
|
||||||
|
|
||||||
DB:
|
DB:
|
||||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
|
|
||||||
CacheConf:
|
CacheConf:
|
||||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||||
Type: node
|
Type: node
|
||||||
|
Pass: "${REDIS_PASSWORD}"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
Level: debug
|
Level: debug
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# ===== DEV CONFIG =====
|
|
||||||
SearchRpcConf:
|
SearchRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- search-rpc:8080
|
- "${SEARCH_RPC_TARGET}"
|
||||||
|
|
||||||
|
Log:
|
||||||
|
Level: debug
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var c config.Config
|
var c config.Config
|
||||||
conf.MustLoad(*configFile, &c)
|
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||||
|
|
||||||
server := rest.MustNewServer(c.RestConf)
|
server := rest.MustNewServer(c.RestConf)
|
||||||
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
||||||
|
|||||||
@@ -6,18 +6,18 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# ===== DEV CONF =====
|
|
||||||
SnowflakeRpcConf:
|
SnowflakeRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- snowflake:8080
|
- "${SNOWFLAKE_RPC_TARGET}"
|
||||||
|
|
||||||
DB:
|
DB:
|
||||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
|
|
||||||
CacheConf:
|
CacheConf:
|
||||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||||
Type: node
|
Type: node
|
||||||
|
Pass: "${REDIS_PASSWORD}"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
Level: debug
|
Level: debug
|
||||||
|
|||||||
@@ -7,17 +7,13 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# k8s://juwan/<service name>:8080
|
|
||||||
|
|
||||||
# ===== PROC CONFIG =====
|
|
||||||
#ShopRpcConf:
|
|
||||||
# Target: k8s://juwan/shop-rpc-svc.juwan:8080
|
|
||||||
|
|
||||||
|
|
||||||
# ===== DEV CONFIG ====
|
|
||||||
ShopRpcConf:
|
ShopRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- shop-rpc:8080
|
- "${SHOP_RPC_TARGET}"
|
||||||
|
|
||||||
PlayerRpcConf:
|
PlayerRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- player-rpc:8080
|
- "${PLAYER_RPC_TARGET}"
|
||||||
|
|
||||||
|
Log:
|
||||||
|
Level: debug
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ type IncomeStatsResp struct {
|
|||||||
|
|
||||||
type InvitationReq struct {
|
type InvitationReq struct {
|
||||||
Id int64 `path:"id"`
|
Id int64 `path:"id"`
|
||||||
PlayerId int64 `json:"playerId"`
|
PlayerId int64 `json:"playerId,string"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PageMeta struct {
|
type PageMeta struct {
|
||||||
@@ -61,11 +61,11 @@ type ShopIdReq struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ShopInvitation struct {
|
type ShopInvitation struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id,string"`
|
||||||
ShopId int64 `json:"shopId"`
|
ShopId int64 `json:"shopId,string"`
|
||||||
PlayerId int64 `json:"playerId"`
|
PlayerId int64 `json:"playerId,string"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
InvitedBy int64 `json:"invitedBy"`
|
InvitedBy int64 `json:"invitedBy,string"`
|
||||||
CreatedAt int64 `json:"createdAt"`
|
CreatedAt int64 `json:"createdAt"`
|
||||||
RespondedAt int64 `json:"respondedAt,optional"`
|
RespondedAt int64 `json:"respondedAt,optional"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var c config.Config
|
var c config.Config
|
||||||
conf.MustLoad(*configFile, &c)
|
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||||
|
|
||||||
server := rest.MustNewServer(c.RestConf)
|
server := rest.MustNewServer(c.RestConf)
|
||||||
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
||||||
|
|||||||
@@ -6,53 +6,22 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# tcd:
|
|
||||||
# Hosts:
|
|
||||||
# - 127.0.0.1:2379
|
|
||||||
# Key: pb.rpc
|
|
||||||
|
|
||||||
# ===== PROC Config =====
|
|
||||||
#SnowflakeRpcConf:
|
|
||||||
# Target: k8s://juwan/snowflake-svc:8080
|
|
||||||
#UsersRpcConf:
|
|
||||||
# Target: k8s://juwan/user-rpc-svc:8080
|
|
||||||
|
|
||||||
#DB:
|
|
||||||
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@{DB_HOST_RW}.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@{BD_HOST_RO}.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#CacheConf:
|
|
||||||
# - Host: "${REDIS_M_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
# - Host: "${REDIS_S_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
|
|
||||||
# ===== DEV Config =====
|
|
||||||
SnowflakeRpcConf:
|
SnowflakeRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- snowflake:8080
|
- "${SNOWFLAKE_RPC_TARGET}"
|
||||||
|
|
||||||
UsersRpcConf:
|
UsersRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- user-rpc:8080
|
- "${USER_RPC_TARGET}"
|
||||||
|
|
||||||
DB:
|
DB:
|
||||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
|
|
||||||
CacheConf:
|
CacheConf:
|
||||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||||
Type: node
|
Type: node
|
||||||
|
Pass: "${REDIS_PASSWORD}"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
Level: info
|
Level: debug
|
||||||
|
|
||||||
|
|
||||||
# Target: k8s://juwan/<service name>.<namespace>:8080
|
|
||||||
#DB:
|
|
||||||
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var c config.Config
|
var c config.Config
|
||||||
conf.MustLoad(*configFile, &c)
|
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||||
ctx := svc.NewServiceContext(c)
|
ctx := svc.NewServiceContext(c)
|
||||||
|
|
||||||
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
|
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
|
||||||
|
|||||||
@@ -1,45 +1,27 @@
|
|||||||
Name: pb.rpc
|
Name: pb.rpc
|
||||||
ListenOn: 0.0.0.0:8080
|
ListenOn: 0.0.0.0:8080
|
||||||
|
|
||||||
|
Prometheus:
|
||||||
|
Host: 0.0.0.0
|
||||||
|
Port: 4001
|
||||||
|
Path: /metrics
|
||||||
|
|
||||||
# ===== PROC Config =====
|
|
||||||
#SnowflakeRpcConf:
|
|
||||||
# Target: k8s://juwan/snowflake-svc.juwan:8080
|
|
||||||
#UserRpcConf:
|
|
||||||
# Target: k8s://juwan/user-rpc-svc.juwan:8080
|
|
||||||
#
|
|
||||||
#DB:
|
|
||||||
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
# Slave: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
#
|
|
||||||
#CacheConf:
|
|
||||||
# - Host: "${REDIS_M_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
# - Host: "${REDIS_S_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
#
|
|
||||||
#Log:
|
|
||||||
# Level: info
|
|
||||||
|
|
||||||
# ===== DEV Config =====
|
|
||||||
SnowflakeRpcConf:
|
SnowflakeRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- snowflake:8080
|
- "${SNOWFLAKE_RPC_TARGET}"
|
||||||
|
|
||||||
UserRpcConf:
|
UserRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- user-rpc:8080
|
- "${USER_RPC_TARGET}"
|
||||||
|
|
||||||
DB:
|
DB:
|
||||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
Slave: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Slave: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
|
|
||||||
CacheConf:
|
CacheConf:
|
||||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||||
Type: node
|
Type: node
|
||||||
|
Pass: "${REDIS_PASSWORD}"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
Level: debug
|
Level: debug
|
||||||
|
|||||||
@@ -7,19 +7,13 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# ===== PROC CONFIG =====
|
|
||||||
#UsercenterRpcConf:
|
|
||||||
# Target: k8s://juwan/user-rpc-svc:8080
|
|
||||||
#UserVerificationRpc:
|
|
||||||
# Target: k8s://juwan/user_verifications-svc:8080
|
|
||||||
|
|
||||||
# ===== DEV CONFIG ====
|
|
||||||
UserVerificationRpc:
|
UserVerificationRpc:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- user-verifications-rpc:8080
|
- "${USER_VERIFICATIONS_RPC_TARGET}"
|
||||||
|
|
||||||
UsercenterRpcConf:
|
UsercenterRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- user-rpc:8080
|
- "${USER_RPC_TARGET}"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
Level: debug
|
Level: debug
|
||||||
@@ -125,8 +125,8 @@ type VerificationIdReq struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type VerificationItem struct {
|
type VerificationItem struct {
|
||||||
Id int64 `json:"id"` // 认证记录ID (主键,用于管理员操作)
|
Id int64 `json:"id,string"` // 认证记录ID (主键,用于管理员操作)
|
||||||
UserId int64 `json:"userId"` // 申请人ID (外键)
|
UserId int64 `json:"userId,string"` // 申请人ID (外键)
|
||||||
UserNickname string `json:"userNickname"` // 冗余显示,方便前端展示
|
UserNickname string `json:"userNickname"` // 冗余显示,方便前端展示
|
||||||
Role string `json:"role"` // 申请角色: player, owner
|
Role string `json:"role"` // 申请角色: player, owner
|
||||||
Status string `json:"status"` // pending, approved, rejected
|
Status string `json:"status"` // pending, approved, rejected
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var c config.Config
|
var c config.Config
|
||||||
conf.MustLoad(*configFile, &c)
|
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||||
|
|
||||||
server := rest.MustNewServer(c.RestConf)
|
server := rest.MustNewServer(c.RestConf)
|
||||||
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
||||||
|
|||||||
+35
-11
@@ -6,14 +6,28 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"juwan-backend/app/snowflake/rpc/snowflake"
|
"juwan-backend/app/users/rpc/internal/models/schema"
|
||||||
"juwan-backend/app/users/rpc/internal/models/users"
|
"juwan-backend/app/users/rpc/internal/models/users"
|
||||||
"juwan-backend/app/users/rpc/internal/svc"
|
"juwan-backend/app/users/rpc/internal/svc"
|
||||||
"juwan-backend/common/utils/pwdUtils"
|
"juwan-backend/common/utils/pwdUtils"
|
||||||
|
"juwan-backend/pkg/types"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const adminUserID int64 = 100000
|
||||||
|
|
||||||
|
var adminVerifiedRoles = types.TextArray{
|
||||||
|
Elements: []string{"consumer", "player", "owner", "admin"},
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
var adminVerificationStatus = schema.VerificationStatusStruct{
|
||||||
|
Consumer: "approved",
|
||||||
|
Player: "approved",
|
||||||
|
Owner: "approved",
|
||||||
|
}
|
||||||
|
|
||||||
func initAdmin(svcCtx *svc.ServiceContext) {
|
func initAdmin(svcCtx *svc.ServiceContext) {
|
||||||
username := strings.TrimSpace(os.Getenv("ADMIN_USERNAME"))
|
username := strings.TrimSpace(os.Getenv("ADMIN_USERNAME"))
|
||||||
password := strings.TrimSpace(os.Getenv("ADMIN_PASSWORD"))
|
password := strings.TrimSpace(os.Getenv("ADMIN_PASSWORD"))
|
||||||
@@ -24,8 +38,9 @@ func initAdmin(svcCtx *svc.ServiceContext) {
|
|||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
var existing bool
|
||||||
for i := range 30 {
|
for i := range 30 {
|
||||||
exists, err := svcCtx.UsersModelRW.Users.Query().Where(users.UsernameEQ(username)).Exist(ctx)
|
ok, err := svcCtx.UsersModelRW.Users.Query().Where(users.UsernameEQ(username)).Exist(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if i < 29 {
|
if i < 29 {
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
@@ -34,10 +49,23 @@ func initAdmin(svcCtx *svc.ServiceContext) {
|
|||||||
logx.Errorf("check admin user: %v", err)
|
logx.Errorf("check admin user: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if exists {
|
existing = ok
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if existing {
|
||||||
|
err := svcCtx.UsersModelRW.Users.Update().
|
||||||
|
Where(users.UsernameEQ(username)).
|
||||||
|
SetIsAdmin(true).
|
||||||
|
SetVerifiedRoles(adminVerifiedRoles).
|
||||||
|
SetVerificationStatus(adminVerificationStatus).
|
||||||
|
Exec(ctx)
|
||||||
|
if err != nil {
|
||||||
|
logx.Errorf("reconcile admin user: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
break
|
logx.Infof("reconciled admin user: %s", username)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
hashedPassword, err := pwdUtils.HashPassword(password)
|
hashedPassword, err := pwdUtils.HashPassword(password)
|
||||||
@@ -46,14 +74,8 @@ func initAdmin(svcCtx *svc.ServiceContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := svcCtx.Snowflake.NextId(ctx, &snowflake.NextIdReq{})
|
|
||||||
if err != nil {
|
|
||||||
logx.Errorf("generate admin user ID: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = svcCtx.UsersModelRW.Users.Create().
|
_, err = svcCtx.UsersModelRW.Users.Create().
|
||||||
SetID(resp.Id).
|
SetID(adminUserID).
|
||||||
SetUsername(username).
|
SetUsername(username).
|
||||||
SetPasswordHash(hashedPassword).
|
SetPasswordHash(hashedPassword).
|
||||||
SetEmail(email).
|
SetEmail(email).
|
||||||
@@ -63,6 +85,8 @@ func initAdmin(svcCtx *svc.ServiceContext) {
|
|||||||
SetCurrentRole("consumer").
|
SetCurrentRole("consumer").
|
||||||
SetNickname(username).
|
SetNickname(username).
|
||||||
SetIsAdmin(true).
|
SetIsAdmin(true).
|
||||||
|
SetVerifiedRoles(adminVerifiedRoles).
|
||||||
|
SetVerificationStatus(adminVerificationStatus).
|
||||||
Save(ctx)
|
Save(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Errorf("create admin user: %v", err)
|
logx.Errorf("create admin user: %v", err)
|
||||||
|
|||||||
@@ -6,46 +6,21 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
DataSource: "${DB_URI}?sslmode=disable"
|
|
||||||
|
|
||||||
|
|
||||||
# ===== PROC CONFIG =====
|
|
||||||
#SnowflakeRpcConf:
|
|
||||||
# Target: k8s://juwan/snowflake-svc:8080
|
|
||||||
#
|
|
||||||
#DB:
|
|
||||||
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
# Slave: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
#
|
|
||||||
#CacheConf:
|
|
||||||
# - Host: "${REDIS_M_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
# - Host: "${REDIS_S_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
#
|
|
||||||
#Jwt:
|
|
||||||
# SecretKey: "${JWT_SECRET_KEY}"
|
|
||||||
# Issuer: "juwan-user-rpc"
|
|
||||||
|
|
||||||
# ===== DEV CONFIG =====
|
|
||||||
SnowflakeRpcConf:
|
SnowflakeRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- snowflake:8080
|
- "${SNOWFLAKE_RPC_TARGET}"
|
||||||
|
|
||||||
DB:
|
DB:
|
||||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
Slave: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Slave: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
|
|
||||||
CacheConf:
|
CacheConf:
|
||||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||||
Type: node
|
Type: node
|
||||||
|
Pass: "${REDIS_PASSWORD}"
|
||||||
|
|
||||||
Jwt:
|
Jwt:
|
||||||
SecretKey: "MGUyMWE3ZDhjMTQ5ZDg1MWViOWU0MGM3OTE2NWVkYTBlOTE5ZWRkZDU1YjYzOGJjOWRiNzM0NTc4NDIyMjlkZQ"
|
SecretKey: "${JWT_SECRET_KEY}"
|
||||||
Issuer: "juwan-user-rpc"
|
Issuer: "juwan-user-rpc"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ type JwtConfig struct {
|
|||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
zrpc.RpcServerConf
|
zrpc.RpcServerConf
|
||||||
DataSource string `json:"dataSource"`
|
|
||||||
DB struct {
|
DB struct {
|
||||||
Master string
|
Master string
|
||||||
Slave string
|
Slave string
|
||||||
|
|||||||
@@ -7,16 +7,9 @@ Prometheus:
|
|||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# ===== PROC CONF =====
|
|
||||||
#WalletRpcConf:
|
|
||||||
# Target: k8s://juwan/wallet-rpc:8080
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ===== DEV CONF =====
|
|
||||||
WalletRpcConf:
|
WalletRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- wallet-rpc:8080
|
- "${WALLET_RPC_TARGET}"
|
||||||
|
|
||||||
# k8s://juwan/<service name>:8080
|
|
||||||
|
|
||||||
|
Log:
|
||||||
|
Level: debug
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// Code generated by goctl. DO NOT EDIT.
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
// goctl 1.9.2
|
// goctl 1.10.1
|
||||||
|
|
||||||
package handler
|
package handler
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// Code generated by goctl. DO NOT EDIT.
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
// goctl 1.9.2
|
// goctl 1.10.1
|
||||||
|
|
||||||
package types
|
package types
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ type TopupReq struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Transaction struct {
|
type Transaction struct {
|
||||||
Id int64 `json:"id"`
|
Id int64 `json:"id,string"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Amount string `json:"amount"`
|
Amount string `json:"amount"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
var c config.Config
|
var c config.Config
|
||||||
conf.MustLoad(*configFile, &c)
|
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||||
|
|
||||||
server := rest.MustNewServer(c.RestConf)
|
server := rest.MustNewServer(c.RestConf)
|
||||||
server.Use(middlewares.NewRequestMiddleware().Handle)
|
server.Use(middlewares.NewRequestMiddleware().Handle)
|
||||||
|
|||||||
@@ -1,55 +1,23 @@
|
|||||||
Name: pb.rpc
|
Name: pb.rpc
|
||||||
ListenOn: 0.0.0.0:8080
|
ListenOn: 0.0.0.0:8080
|
||||||
|
|
||||||
|
|
||||||
Prometheus:
|
Prometheus:
|
||||||
Host: 0.0.0.0
|
Host: 0.0.0.0
|
||||||
Port: 4001
|
Port: 4001
|
||||||
Path: /metrics
|
Path: /metrics
|
||||||
|
|
||||||
# tcd:
|
|
||||||
# Hosts:
|
|
||||||
# - 127.0.0.1:2379
|
|
||||||
# Key: pb.rpc
|
|
||||||
|
|
||||||
# Target: k8s://juwan/<service name>.<namespace>:8080
|
|
||||||
|
|
||||||
|
|
||||||
# ===== PROC CONF =====
|
|
||||||
#SnowflakeRpcConf:
|
|
||||||
# Target: k8s://juwan/snowflake-svc:8080
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#DB:
|
|
||||||
# Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-rw.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
# Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@user-db-ro.juwan:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#CacheConf:
|
|
||||||
# - Host: "${REDIS_M_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
# - Host: "${REDIS_S_HOST}"
|
|
||||||
# Type: node
|
|
||||||
# Pass: "${REDIS_PASSWORD}"
|
|
||||||
# User: "default"
|
|
||||||
#
|
|
||||||
#Log:
|
|
||||||
# Level: info
|
|
||||||
|
|
||||||
# ===== DEV CONFIG =====
|
|
||||||
SnowflakeRpcConf:
|
SnowflakeRpcConf:
|
||||||
Endpoints:
|
Endpoints:
|
||||||
- snowflake:8080
|
- "${SNOWFLAKE_RPC_TARGET}"
|
||||||
|
|
||||||
DB:
|
DB:
|
||||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
Slaves: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||||
|
|
||||||
CacheConf:
|
CacheConf:
|
||||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||||
Type: node
|
Type: node
|
||||||
|
Pass: "${REDIS_PASSWORD}"
|
||||||
|
|
||||||
Log:
|
Log:
|
||||||
Level: debug
|
Level: debug
|
||||||
+29
-3
@@ -3,18 +3,44 @@ PD_USERNAME=postgres
|
|||||||
DB_PASSWORD=123456
|
DB_PASSWORD=123456
|
||||||
DB_PORT=5432
|
DB_PORT=5432
|
||||||
DB_NAME=app
|
DB_NAME=app
|
||||||
DB_URI=postgresql://postgres:123456@postgres:5432/app
|
DB_HOST=postgres
|
||||||
|
DB_HOST_RO=postgres
|
||||||
|
|
||||||
# Redis
|
# Redis
|
||||||
REDIS_HOST=redis
|
REDIS_HOST=redis
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
REDIS_PASSWORD=
|
REDIS_PASSWORD=
|
||||||
REDIS_M_HOST=redis:6379
|
|
||||||
REDIS_S_HOST=redis:6379
|
# Mongo (chat)
|
||||||
|
MONGO_URI=mongodb://mongo:27017
|
||||||
|
MONGO_DATABASE=juwan_chat
|
||||||
|
|
||||||
# Kafka
|
# Kafka
|
||||||
KAFKA_BROKER=kafka:9092
|
KAFKA_BROKER=kafka:9092
|
||||||
|
|
||||||
|
# JWT
|
||||||
|
JWT_SECRET_KEY=MGUyMWE3ZDhjMTQ5ZDg1MWViOWU0MGM3OTE2NWVkYTBlOTE5ZWRkZDU1YjYzOGJjOWRiNzM0NTc4NDIyMjlkZQ
|
||||||
|
|
||||||
|
# RPC targets (compose DNS)
|
||||||
|
SNOWFLAKE_RPC_TARGET=snowflake:8080
|
||||||
|
USER_RPC_TARGET=user-rpc:8080
|
||||||
|
USER_VERIFICATIONS_RPC_TARGET=user-verifications-rpc:8080
|
||||||
|
PLAYER_RPC_TARGET=player-rpc:8080
|
||||||
|
GAME_RPC_TARGET=game-rpc:8080
|
||||||
|
SHOP_RPC_TARGET=shop-rpc:8080
|
||||||
|
ORDER_RPC_TARGET=order-rpc:8080
|
||||||
|
WALLET_RPC_TARGET=wallet-rpc:8080
|
||||||
|
COMMUNITY_RPC_TARGET=community-rpc:8080
|
||||||
|
REVIEW_RPC_TARGET=review-rpc:8080
|
||||||
|
DISPUTE_RPC_TARGET=dispute-rpc:8080
|
||||||
|
NOTIFICATION_RPC_TARGET=notification-rpc:8080
|
||||||
|
SEARCH_RPC_TARGET=search-rpc:8080
|
||||||
|
OBJECTSTORY_RPC_TARGET=objectstory-rpc:8080
|
||||||
|
|
||||||
|
# Chat WebTransport TLS (dev self-signed; chat service reads OptionalValue with empty fallback)
|
||||||
|
CHAT_WT_CERT_FILE=/etc/certs/tls.crt
|
||||||
|
CHAT_WT_KEY_FILE=/etc/certs/tls.key
|
||||||
|
|
||||||
# Email (placeholder)
|
# Email (placeholder)
|
||||||
EMAIL_SMTP_HOST=smtp.example.com
|
EMAIL_SMTP_HOST=smtp.example.com
|
||||||
EMAIL_SMTP_PORT=465
|
EMAIL_SMTP_PORT=465
|
||||||
|
|||||||
+35
-42
@@ -4,63 +4,54 @@
|
|||||||
|
|
||||||
- Docker(需要 buildx)
|
- Docker(需要 buildx)
|
||||||
- Python 3(构建脚本)
|
- Python 3(构建脚本)
|
||||||
|
- Git(含 submodule:首次需 `git submodule update --init --recursive`)
|
||||||
|
|
||||||
## 使用
|
## 使用
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd deploy/dev
|
cd deploy/dev
|
||||||
|
|
||||||
# 1. 构建所有微服务镜像
|
# 1. 构建所有镜像(默认 8 并行,可通过 BAKE_BATCH_SIZE 调整)
|
||||||
# 默认 8 并行,可通过环境变量 BAKE_BATCH_SIZE 调整
|
|
||||||
python3 build.py
|
python3 build.py
|
||||||
|
|
||||||
# 2. 启动
|
# 2. 启动
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
|
|
||||||
# 3. 查看状态
|
# 3. 通过网关访问
|
||||||
docker compose ps
|
open http://127.0.0.1:18080
|
||||||
|
|
||||||
# 4. 通过网关访问
|
|
||||||
curl http://127.0.0.1:18080/healthz
|
|
||||||
|
|
||||||
# 5. 停止
|
|
||||||
docker compose down
|
|
||||||
```
|
```
|
||||||
|
|
||||||
构建脚本会扫描 `app/` 下所有 `api`、`rpc`、`mq`、`adapter` 入口,通过 `docker buildx bake` 并行构建所有服务镜像,生成 `juwan/<service>-<type>:dev`。
|
构建脚本扫描 `app/` 下所有 `api`、`rpc`、`mq`、`adapter` 入口和 `frontend/`,通过 `docker buildx bake` 并行构建所有镜像,生成 `juwan/<service>-<type>:dev` 与 `juwan/frontend:dev`。
|
||||||
|
|
||||||
端到端接口测试走网关 `http://127.0.0.1:18080`,`18801-18814` 是各服务的直连端口,不经过认证链路。
|
前端作为 submodule 接入 compose,通过 envoy 的同源 fallback 路由向浏览器提供,无需独立端口。
|
||||||
|
|
||||||
Chat WebSocket 通过网关 `ws://127.0.0.1:18080/ws/chat` 访问。WebTransport 使用 `18443/udp` 的 `/wt/chat` 入口。
|
Chat WebSocket 通过 `ws://127.0.0.1:18080/ws/chat` 访问。WebTransport 使用 `18443/udp` 的 `/wt/chat`。
|
||||||
|
|
||||||
如需只启动部分服务:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker compose up -d postgres redis snowflake player-rpc player-api
|
|
||||||
```
|
|
||||||
|
|
||||||
## 端口映射
|
## 端口映射
|
||||||
|
|
||||||
| 服务 | 宿主机端口 |
|
| 服务 | 宿主机端口 | 说明 |
|
||||||
| ---------------- | ---------------- |
|
| ---------------- | ---------------- | ---------------------------------- |
|
||||||
| PostgreSQL | 15432 |
|
| Envoy Gateway | 18080 | 浏览器入口,`/api/*`、`/ws/*`、前端静态都从这里出 |
|
||||||
| Redis | 16379 |
|
| Redis | 16379 | 共享会话与验证码 |
|
||||||
| Kafka | 19092 |
|
| MongoDB | 27017 | chat 消息持久化 |
|
||||||
| Envoy Gateway | 18080 |
|
| Kafka | 19092 | email-mq 任务队列 |
|
||||||
| users-api | 18801 |
|
| ratelimit | 18081, 16070 | 限流服务 |
|
||||||
| player-api | 18802 |
|
| users-api | 18801 | 直连调试入口,不经认证链路 |
|
||||||
| game-api | 18803 |
|
| player-api | 18802 | |
|
||||||
| shop-api | 18804 |
|
| game-api | 18803 | |
|
||||||
| order-api | 18805 |
|
| shop-api | 18804 | |
|
||||||
| wallet-api | 18806 |
|
| order-api | 18805 | |
|
||||||
| community-api | 18807 |
|
| wallet-api | 18806 | |
|
||||||
| objectstory-api | 18808 |
|
| community-api | 18807 | |
|
||||||
| email-api | 18809 |
|
| objectstory-api | 18808 | |
|
||||||
| chat-api | 18810, 18443/udp |
|
| email-api | 18809 | |
|
||||||
| review-api | 18811 |
|
| chat-api | 18810, 18889, 18443/udp | |
|
||||||
| dispute-api | 18812 |
|
| review-api | 18811 | |
|
||||||
| notification-api | 18813 |
|
| dispute-api | 18812 | |
|
||||||
| search-api | 18814 |
|
| notification-api | 18813 | |
|
||||||
|
| search-api | 18814 | |
|
||||||
|
|
||||||
|
11 个 per-domain PostgreSQL(`users-db`、`player-db`、`game-db`、`shop-db`、`order-db`、`wallet-db`、`community-db`、`review-db`、`dispute-db`、`notification-db`、`search-db`)和 `frontend` 容器不暴露宿主端口,仅在 compose 内网通过 DNS 互访。
|
||||||
|
|
||||||
## 环境变量
|
## 环境变量
|
||||||
|
|
||||||
@@ -74,17 +65,19 @@ docker compose up -d postgres redis snowflake player-rpc player-api
|
|||||||
| ADMIN_PASSWORD | 管理员密码 | admin123 |
|
| ADMIN_PASSWORD | 管理员密码 | admin123 |
|
||||||
| ADMIN_EMAIL | 管理员邮箱 | admin@juwan.dev |
|
| ADMIN_EMAIL | 管理员邮箱 | admin@juwan.dev |
|
||||||
|
|
||||||
|
默认 admin 固定 ID `100000`,拥有消费者、打手、店主三种身份全部开通,并预置了店铺、服务、钱包、帖子等演示数据,可直接用于完整链路联调。
|
||||||
|
|
||||||
## 认证
|
## 认证
|
||||||
|
|
||||||
登录和注册通过 `users-api` 下发 `JToken` Cookie。`envoy-gateway` 负责 JWT 校验并注入认证头,`authz-adapter` 做会话态二次校验,后端服务只消费 `x-auth-user-id` 等头。
|
登录和注册通过 `users-api` 下发 `JToken` Cookie。`envoy-gateway` 负责 JWT 校验并注入认证头,`authz-adapter` 做会话态二次校验,后端服务只消费 `x-auth-user-id` 等头。
|
||||||
|
|
||||||
写接口需要先 `GET /healthz` 领取 `XSRF-TOKEN` 和 `XSRF-GUARD`,再在请求头带上 `xsrf-token`。
|
写接口需要先 `GET /healthz` 领取 `__Host-XSRF-TOKEN` 和 `__Host-XSRF-GUARD` cookie,再在请求头带上 `xsrf-token`。
|
||||||
|
|
||||||
注册和密码重置都需要先调验证码接口拿到 `requestId`,再把它放到 `X-Request-Id` 请求头里发后续请求。
|
注册和密码重置都需要先调验证码接口拿到 `requestId`,再把它放到 `X-Request-Id` 请求头里发后续请求。
|
||||||
|
|
||||||
## 数据库初始化
|
## 数据库与初始化
|
||||||
|
|
||||||
首次启动时 PostgreSQL 会自动执行 `desc/sql/` 下的建表语句。如需重新初始化,删除 volume 后重启:
|
每个 per-domain PostgreSQL 首次启动时,通过挂载 `desc/sql/<domain>/` 和 `deploy/dev/fixture/<domain>.sql` 自动完成建表与演示数据导入。如需完全重置:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose down -v
|
docker compose down -v
|
||||||
|
|||||||
@@ -91,9 +91,23 @@ def discover_targets():
|
|||||||
return targets
|
return targets
|
||||||
|
|
||||||
|
|
||||||
|
def frontend_target():
|
||||||
|
frontend_root = ROOT_DIR / "frontend"
|
||||||
|
if not (frontend_root / "Dockerfile").exists():
|
||||||
|
return None
|
||||||
|
return {
|
||||||
|
"context": "frontend",
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
"tags": [f"{IMAGE_PREFIX}/frontend:{IMAGE_TAG}"],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
os.chdir(ROOT_DIR)
|
os.chdir(ROOT_DIR)
|
||||||
targets = discover_targets()
|
targets = discover_targets()
|
||||||
|
ft = frontend_target()
|
||||||
|
if ft is not None:
|
||||||
|
targets["frontend"] = ft
|
||||||
if not targets:
|
if not targets:
|
||||||
print("No targets found")
|
print("No targets found")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|||||||
+214
-30
@@ -1,19 +1,10 @@
|
|||||||
services:
|
x-postgres-base: &postgres-base
|
||||||
# ==================== 基础设施 ====================
|
|
||||||
postgres:
|
|
||||||
image: postgres:17-bookworm
|
image: postgres:17-bookworm
|
||||||
container_name: juwan-postgres
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment: &postgres-env
|
||||||
POSTGRES_USER: ${PD_USERNAME}
|
POSTGRES_USER: ${PD_USERNAME}
|
||||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||||
POSTGRES_DB: ${DB_NAME}
|
POSTGRES_DB: ${DB_NAME}
|
||||||
ports:
|
|
||||||
- "15432:5432"
|
|
||||||
volumes:
|
|
||||||
- pgdata:/var/lib/postgresql/data
|
|
||||||
- ./init-db.sh:/docker-entrypoint-initdb.d/init-db.sh:ro
|
|
||||||
- ../../desc/sql:/docker-entrypoint-initdb.d/sql:ro
|
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "pg_isready -U ${PD_USERNAME} -d ${DB_NAME}"]
|
test: ["CMD-SHELL", "pg_isready -U ${PD_USERNAME} -d ${DB_NAME}"]
|
||||||
interval: 5s
|
interval: 5s
|
||||||
@@ -21,6 +12,140 @@ services:
|
|||||||
start_period: 30s
|
start_period: 30s
|
||||||
retries: 10
|
retries: 10
|
||||||
|
|
||||||
|
services:
|
||||||
|
# ==================== 基础设施 ====================
|
||||||
|
users-db:
|
||||||
|
<<: *postgres-base
|
||||||
|
container_name: juwan-users-db
|
||||||
|
environment:
|
||||||
|
<<: *postgres-env
|
||||||
|
POSTGRES_DOMAIN: users
|
||||||
|
volumes:
|
||||||
|
- users-pgdata:/var/lib/postgresql/data
|
||||||
|
- ./init-domain.sh:/docker-entrypoint-initdb.d/00-init-domain.sh:ro
|
||||||
|
- ../../desc/sql:/docker-entrypoint-initdb.d/sql:ro
|
||||||
|
- ./fixture:/docker-entrypoint-initdb.d/fixture:ro
|
||||||
|
|
||||||
|
game-db:
|
||||||
|
<<: *postgres-base
|
||||||
|
container_name: juwan-game-db
|
||||||
|
environment:
|
||||||
|
<<: *postgres-env
|
||||||
|
POSTGRES_DOMAIN: game
|
||||||
|
volumes:
|
||||||
|
- game-pgdata:/var/lib/postgresql/data
|
||||||
|
- ./init-domain.sh:/docker-entrypoint-initdb.d/00-init-domain.sh:ro
|
||||||
|
- ../../desc/sql:/docker-entrypoint-initdb.d/sql:ro
|
||||||
|
- ./fixture:/docker-entrypoint-initdb.d/fixture:ro
|
||||||
|
|
||||||
|
player-db:
|
||||||
|
<<: *postgres-base
|
||||||
|
container_name: juwan-player-db
|
||||||
|
environment:
|
||||||
|
<<: *postgres-env
|
||||||
|
POSTGRES_DOMAIN: player
|
||||||
|
volumes:
|
||||||
|
- player-pgdata:/var/lib/postgresql/data
|
||||||
|
- ./init-domain.sh:/docker-entrypoint-initdb.d/00-init-domain.sh:ro
|
||||||
|
- ../../desc/sql:/docker-entrypoint-initdb.d/sql:ro
|
||||||
|
- ./fixture:/docker-entrypoint-initdb.d/fixture:ro
|
||||||
|
|
||||||
|
shop-db:
|
||||||
|
<<: *postgres-base
|
||||||
|
container_name: juwan-shop-db
|
||||||
|
environment:
|
||||||
|
<<: *postgres-env
|
||||||
|
POSTGRES_DOMAIN: shop
|
||||||
|
volumes:
|
||||||
|
- shop-pgdata:/var/lib/postgresql/data
|
||||||
|
- ./init-domain.sh:/docker-entrypoint-initdb.d/00-init-domain.sh:ro
|
||||||
|
- ../../desc/sql:/docker-entrypoint-initdb.d/sql:ro
|
||||||
|
- ./fixture:/docker-entrypoint-initdb.d/fixture:ro
|
||||||
|
|
||||||
|
order-db:
|
||||||
|
<<: *postgres-base
|
||||||
|
container_name: juwan-order-db
|
||||||
|
environment:
|
||||||
|
<<: *postgres-env
|
||||||
|
POSTGRES_DOMAIN: order
|
||||||
|
volumes:
|
||||||
|
- order-pgdata:/var/lib/postgresql/data
|
||||||
|
- ./init-domain.sh:/docker-entrypoint-initdb.d/00-init-domain.sh:ro
|
||||||
|
- ../../desc/sql:/docker-entrypoint-initdb.d/sql:ro
|
||||||
|
- ./fixture:/docker-entrypoint-initdb.d/fixture:ro
|
||||||
|
|
||||||
|
wallet-db:
|
||||||
|
<<: *postgres-base
|
||||||
|
container_name: juwan-wallet-db
|
||||||
|
environment:
|
||||||
|
<<: *postgres-env
|
||||||
|
POSTGRES_DOMAIN: wallet
|
||||||
|
volumes:
|
||||||
|
- wallet-pgdata:/var/lib/postgresql/data
|
||||||
|
- ./init-domain.sh:/docker-entrypoint-initdb.d/00-init-domain.sh:ro
|
||||||
|
- ../../desc/sql:/docker-entrypoint-initdb.d/sql:ro
|
||||||
|
- ./fixture:/docker-entrypoint-initdb.d/fixture:ro
|
||||||
|
|
||||||
|
community-db:
|
||||||
|
<<: *postgres-base
|
||||||
|
container_name: juwan-community-db
|
||||||
|
environment:
|
||||||
|
<<: *postgres-env
|
||||||
|
POSTGRES_DOMAIN: community
|
||||||
|
volumes:
|
||||||
|
- community-pgdata:/var/lib/postgresql/data
|
||||||
|
- ./init-domain.sh:/docker-entrypoint-initdb.d/00-init-domain.sh:ro
|
||||||
|
- ../../desc/sql:/docker-entrypoint-initdb.d/sql:ro
|
||||||
|
- ./fixture:/docker-entrypoint-initdb.d/fixture:ro
|
||||||
|
|
||||||
|
review-db:
|
||||||
|
<<: *postgres-base
|
||||||
|
container_name: juwan-review-db
|
||||||
|
environment:
|
||||||
|
<<: *postgres-env
|
||||||
|
POSTGRES_DOMAIN: review
|
||||||
|
volumes:
|
||||||
|
- review-pgdata:/var/lib/postgresql/data
|
||||||
|
- ./init-domain.sh:/docker-entrypoint-initdb.d/00-init-domain.sh:ro
|
||||||
|
- ../../desc/sql:/docker-entrypoint-initdb.d/sql:ro
|
||||||
|
- ./fixture:/docker-entrypoint-initdb.d/fixture:ro
|
||||||
|
|
||||||
|
dispute-db:
|
||||||
|
<<: *postgres-base
|
||||||
|
container_name: juwan-dispute-db
|
||||||
|
environment:
|
||||||
|
<<: *postgres-env
|
||||||
|
POSTGRES_DOMAIN: dispute
|
||||||
|
volumes:
|
||||||
|
- dispute-pgdata:/var/lib/postgresql/data
|
||||||
|
- ./init-domain.sh:/docker-entrypoint-initdb.d/00-init-domain.sh:ro
|
||||||
|
- ../../desc/sql:/docker-entrypoint-initdb.d/sql:ro
|
||||||
|
- ./fixture:/docker-entrypoint-initdb.d/fixture:ro
|
||||||
|
|
||||||
|
notification-db:
|
||||||
|
<<: *postgres-base
|
||||||
|
container_name: juwan-notification-db
|
||||||
|
environment:
|
||||||
|
<<: *postgres-env
|
||||||
|
POSTGRES_DOMAIN: notification
|
||||||
|
volumes:
|
||||||
|
- notification-pgdata:/var/lib/postgresql/data
|
||||||
|
- ./init-domain.sh:/docker-entrypoint-initdb.d/00-init-domain.sh:ro
|
||||||
|
- ../../desc/sql:/docker-entrypoint-initdb.d/sql:ro
|
||||||
|
- ./fixture:/docker-entrypoint-initdb.d/fixture:ro
|
||||||
|
|
||||||
|
search-db:
|
||||||
|
<<: *postgres-base
|
||||||
|
container_name: juwan-search-db
|
||||||
|
environment:
|
||||||
|
<<: *postgres-env
|
||||||
|
POSTGRES_DOMAIN: search
|
||||||
|
volumes:
|
||||||
|
- search-pgdata:/var/lib/postgresql/data
|
||||||
|
- ./init-domain.sh:/docker-entrypoint-initdb.d/00-init-domain.sh:ro
|
||||||
|
- ../../desc/sql:/docker-entrypoint-initdb.d/sql:ro
|
||||||
|
- ./fixture:/docker-entrypoint-initdb.d/fixture:ro
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: redis:8-alpine
|
image: redis:8-alpine
|
||||||
container_name: juwan-redis
|
container_name: juwan-redis
|
||||||
@@ -166,6 +291,14 @@ services:
|
|||||||
rl-redis:
|
rl-redis:
|
||||||
condition: service_started
|
condition: service_started
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
image: juwan/frontend:dev
|
||||||
|
container_name: juwan-frontend
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
PORT: "3000"
|
||||||
|
|
||||||
# ==================== RPC 层 ====================
|
# ==================== RPC 层 ====================
|
||||||
user-rpc:
|
user-rpc:
|
||||||
image: juwan/users-rpc:dev
|
image: juwan/users-rpc:dev
|
||||||
@@ -173,11 +306,13 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file: .env
|
env_file: .env
|
||||||
environment:
|
environment:
|
||||||
|
DB_HOST: users-db
|
||||||
|
DB_HOST_RO: users-db
|
||||||
ADMIN_USERNAME: ${ADMIN_USERNAME}
|
ADMIN_USERNAME: ${ADMIN_USERNAME}
|
||||||
ADMIN_PASSWORD: ${ADMIN_PASSWORD}
|
ADMIN_PASSWORD: ${ADMIN_PASSWORD}
|
||||||
ADMIN_EMAIL: ${ADMIN_EMAIL}
|
ADMIN_EMAIL: ${ADMIN_EMAIL}
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
users-db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -189,8 +324,11 @@ services:
|
|||||||
container_name: juwan-user-verifications-rpc
|
container_name: juwan-user-verifications-rpc
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
DB_HOST: users-db
|
||||||
|
DB_HOST_RO: users-db
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
users-db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -204,8 +342,11 @@ services:
|
|||||||
container_name: juwan-player-rpc
|
container_name: juwan-player-rpc
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
DB_HOST: player-db
|
||||||
|
DB_HOST_RO: player-db
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
player-db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -217,8 +358,11 @@ services:
|
|||||||
container_name: juwan-game-rpc
|
container_name: juwan-game-rpc
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
DB_HOST: game-db
|
||||||
|
DB_HOST_RO: game-db
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
game-db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -230,8 +374,11 @@ services:
|
|||||||
container_name: juwan-shop-rpc
|
container_name: juwan-shop-rpc
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
DB_HOST: shop-db
|
||||||
|
DB_HOST_RO: shop-db
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
shop-db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -245,8 +392,11 @@ services:
|
|||||||
container_name: juwan-order-rpc
|
container_name: juwan-order-rpc
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
DB_HOST: order-db
|
||||||
|
DB_HOST_RO: order-db
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
order-db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -258,8 +408,11 @@ services:
|
|||||||
container_name: juwan-wallet-rpc
|
container_name: juwan-wallet-rpc
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
DB_HOST: wallet-db
|
||||||
|
DB_HOST_RO: wallet-db
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
wallet-db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -271,19 +424,17 @@ services:
|
|||||||
container_name: juwan-community-rpc
|
container_name: juwan-community-rpc
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
DB_HOST: community-db
|
||||||
|
DB_HOST_RO: community-db
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
community-db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
snowflake:
|
snowflake:
|
||||||
condition: service_started
|
condition: service_started
|
||||||
|
|
||||||
chat-rpc:
|
|
||||||
image: juwan/chat-rpc:dev
|
|
||||||
container_name: juwan-chat-rpc
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
objectstory-rpc:
|
objectstory-rpc:
|
||||||
image: juwan/objectstory-rpc:dev
|
image: juwan/objectstory-rpc:dev
|
||||||
container_name: juwan-objectstory-rpc
|
container_name: juwan-objectstory-rpc
|
||||||
@@ -295,8 +446,11 @@ services:
|
|||||||
container_name: juwan-review-rpc
|
container_name: juwan-review-rpc
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
DB_HOST: review-db
|
||||||
|
DB_HOST_RO: review-db
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
review-db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -308,8 +462,11 @@ services:
|
|||||||
container_name: juwan-dispute-rpc
|
container_name: juwan-dispute-rpc
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
DB_HOST: dispute-db
|
||||||
|
DB_HOST_RO: dispute-db
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
dispute-db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -321,8 +478,11 @@ services:
|
|||||||
container_name: juwan-notification-rpc
|
container_name: juwan-notification-rpc
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
DB_HOST: notification-db
|
||||||
|
DB_HOST_RO: notification-db
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
notification-db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -334,8 +494,11 @@ services:
|
|||||||
container_name: juwan-search-rpc
|
container_name: juwan-search-rpc
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
DB_HOST: search-db
|
||||||
|
DB_HOST_RO: search-db
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
search-db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -456,6 +619,7 @@ services:
|
|||||||
image: juwan/chat-api:dev
|
image: juwan/chat-api:dev
|
||||||
container_name: juwan-chat-api
|
container_name: juwan-chat-api
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
env_file: .env
|
||||||
ports:
|
ports:
|
||||||
- "18810:8888"
|
- "18810:8888"
|
||||||
- "18889:8889"
|
- "18889:8889"
|
||||||
@@ -531,8 +695,28 @@ services:
|
|||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
pgdata:
|
users-pgdata:
|
||||||
name: juwan-pgdata
|
name: juwan-users-pgdata
|
||||||
|
game-pgdata:
|
||||||
|
name: juwan-game-pgdata
|
||||||
|
player-pgdata:
|
||||||
|
name: juwan-player-pgdata
|
||||||
|
shop-pgdata:
|
||||||
|
name: juwan-shop-pgdata
|
||||||
|
order-pgdata:
|
||||||
|
name: juwan-order-pgdata
|
||||||
|
wallet-pgdata:
|
||||||
|
name: juwan-wallet-pgdata
|
||||||
|
community-pgdata:
|
||||||
|
name: juwan-community-pgdata
|
||||||
|
review-pgdata:
|
||||||
|
name: juwan-review-pgdata
|
||||||
|
dispute-pgdata:
|
||||||
|
name: juwan-dispute-pgdata
|
||||||
|
notification-pgdata:
|
||||||
|
name: juwan-notification-pgdata
|
||||||
|
search-pgdata:
|
||||||
|
name: juwan-search-pgdata
|
||||||
redisdata:
|
redisdata:
|
||||||
name: juwan-redisdata
|
name: juwan-redisdata
|
||||||
mongodata:
|
mongodata:
|
||||||
|
|||||||
+37
-4
@@ -116,6 +116,15 @@ static_resources:
|
|||||||
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
|
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
|
||||||
disabled: true
|
disabled: true
|
||||||
|
|
||||||
|
- match:
|
||||||
|
path: /api/v1/players/me
|
||||||
|
headers:
|
||||||
|
- name: ":method"
|
||||||
|
exact_match: GET
|
||||||
|
route:
|
||||||
|
cluster: player_api_cluster
|
||||||
|
timeout: 30s
|
||||||
|
|
||||||
- match:
|
- match:
|
||||||
prefix: /api/v1/players
|
prefix: /api/v1/players
|
||||||
headers:
|
headers:
|
||||||
@@ -418,10 +427,13 @@ static_resources:
|
|||||||
|
|
||||||
- match:
|
- match:
|
||||||
prefix: /
|
prefix: /
|
||||||
direct_response:
|
route:
|
||||||
status: 404
|
cluster: frontend_cluster
|
||||||
body:
|
timeout: 30s
|
||||||
inline_string: gateway route not found
|
typed_per_filter_config:
|
||||||
|
envoy.filters.http.ext_authz:
|
||||||
|
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
|
||||||
|
disabled: true
|
||||||
|
|
||||||
access_log:
|
access_log:
|
||||||
- name: envoy.access_loggers.stdout
|
- name: envoy.access_loggers.stdout
|
||||||
@@ -616,6 +628,13 @@ static_resources:
|
|||||||
headers:
|
headers:
|
||||||
- name: ":method"
|
- name: ":method"
|
||||||
exact_match: GET
|
exact_match: GET
|
||||||
|
- match:
|
||||||
|
path: /api/v1/players/me
|
||||||
|
headers:
|
||||||
|
- name: ":method"
|
||||||
|
exact_match: GET
|
||||||
|
requires:
|
||||||
|
provider_name: juwan_user_jwt
|
||||||
- match:
|
- match:
|
||||||
prefix: /api/v1/players
|
prefix: /api/v1/players
|
||||||
headers:
|
headers:
|
||||||
@@ -959,6 +978,20 @@ static_resources:
|
|||||||
address: ratelimit
|
address: ratelimit
|
||||||
port_value: 8081
|
port_value: 8081
|
||||||
|
|
||||||
|
- name: frontend_cluster
|
||||||
|
connect_timeout: 2s
|
||||||
|
type: STRICT_DNS
|
||||||
|
lb_policy: ROUND_ROBIN
|
||||||
|
load_assignment:
|
||||||
|
cluster_name: frontend_cluster
|
||||||
|
endpoints:
|
||||||
|
- lb_endpoints:
|
||||||
|
- endpoint:
|
||||||
|
address:
|
||||||
|
socket_address:
|
||||||
|
address: frontend
|
||||||
|
port_value: 3000
|
||||||
|
|
||||||
admin:
|
admin:
|
||||||
access_log_path: /tmp/admin.log
|
access_log_path: /tmp/admin.log
|
||||||
address:
|
address:
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
INSERT INTO posts (id, author_id, author_role, title, content, tags, like_count, comment_count) VALUES
|
||||||
|
(100000, 100000, 'admin', '新赛季代练活动上线:首单立减 20',
|
||||||
|
'新赛季开启,聚玩新一轮活动来了:
|
||||||
|
|
||||||
|
活动期间:
|
||||||
|
- 新用户首单立减 20 元,最低 19.9 起
|
||||||
|
- 老用户推荐新人,双方各得 30 元代金券
|
||||||
|
- 周末下单额外送一局陪玩体验
|
||||||
|
|
||||||
|
所有活动可在下单时自动生效,有任何问题可在社区留言或私信我。祝大家上分顺利!',
|
||||||
|
ARRAY['活动','公告','新赛季'], 20, 1),
|
||||||
|
(100001, 100001, 'player', '新赛季中单法师强度排行',
|
||||||
|
'新赛季中单法师的强度有了不少变化,这里给大家分析一下当前版本的T0-T2梯队。
|
||||||
|
|
||||||
|
T0: 阿狸、辛德拉
|
||||||
|
T1: 维克托、泽丽
|
||||||
|
T2: 佐伊、妮蔻
|
||||||
|
|
||||||
|
大家觉得还有哪些英雄被低估了?',
|
||||||
|
ARRAY['英雄联盟','攻略','中单'], 12, 3),
|
||||||
|
(100002, 100003, 'player', 'VALORANT 新地图攻略分享',
|
||||||
|
'新地图的几个关键烟点和架枪位分享给大家。决斗位在这张图上优势很大,特别是A点的peek角度。',
|
||||||
|
ARRAY['VALORANT','攻略','地图'], 8, 1),
|
||||||
|
(100003, 100004, 'owner', '星辰工作室招募公告',
|
||||||
|
'星辰代练工作室现招募以下段位打手:
|
||||||
|
- LOL 大师及以上
|
||||||
|
- 王者荣耀 王者50星以上
|
||||||
|
|
||||||
|
待遇优厚,佣金比例可谈。有意者私信联系。',
|
||||||
|
ARRAY['招募','工作室'], 5, 2),
|
||||||
|
(100004, 100006, 'consumer', '求推荐靠谱的LOL代练',
|
||||||
|
'钻石卡了好久上不去,想找个靠谱的代练帮忙上大师。有推荐的吗?最好是有保障的工作室。',
|
||||||
|
ARRAY['英雄联盟','求推荐'], 3, 2),
|
||||||
|
(100005, 100002, 'player', '上分心得:如何从钻石到大师',
|
||||||
|
'很多人卡在钻石上不去,其实关键在于几个点:
|
||||||
|
1. 英雄池不要太广,精通2-3个就够
|
||||||
|
2. 对线期不要浪,稳住发育
|
||||||
|
3. 多看小地图,把握团战时机
|
||||||
|
|
||||||
|
希望对大家有帮助!',
|
||||||
|
ARRAY['英雄联盟','心得','上分'], 15, 4);
|
||||||
|
|
||||||
|
INSERT INTO comments (id, post_id, author_id, content, like_count) VALUES
|
||||||
|
(100000, 100000, 100001, '这波活动真香,已经下单了', 5),
|
||||||
|
(100001, 100001, 100002, '阿狸确实强,ban率太高了', 3),
|
||||||
|
(100002, 100001, 100006, '维克托感觉也是T0级别的', 1),
|
||||||
|
(100003, 100001, 100003, '法师版本确实舒服', 2),
|
||||||
|
(100004, 100002, 100001, '新地图确实好玩,决斗位优势大', 1),
|
||||||
|
(100005, 100003, 100001, '有兴趣,已私信', 0),
|
||||||
|
(100006, 100003, 100002, '星辰工作室不错,之前合作过', 2),
|
||||||
|
(100007, 100004, 100001, '可以看看我的主页,钻石到大师是我的强项', 1),
|
||||||
|
(100008, 100004, 100004, '欢迎来星辰工作室了解,我们有专业的代练团队', 0),
|
||||||
|
(100009, 100005, 100006, '写得好,学到了', 2),
|
||||||
|
(100010, 100005, 100007, '确实,英雄池精了比广好', 1),
|
||||||
|
(100011, 100005, 100001, '补充一点:心态也很重要,连跪就休息', 3),
|
||||||
|
(100012, 100005, 100003, '赞同,我也是靠精通少数英雄上的不朽', 1);
|
||||||
|
|
||||||
|
INSERT INTO post_likes (id, post_id, user_id) VALUES
|
||||||
|
(109100, 100000, 100001),(109099, 100000, 100002),(109098, 100000, 100006),(109097, 100000, 100007),(109096, 100000, 100008),
|
||||||
|
(109101, 100001, 100002),(109102, 100001, 100003),(109103, 100001, 100006),(109104, 100001, 100007),
|
||||||
|
(109105, 100002, 100001),(109106, 100002, 100006),
|
||||||
|
(109107, 100003, 100001),(109108, 100003, 100002),
|
||||||
|
(109109, 100004, 100001),(109110, 100004, 100004),
|
||||||
|
(109111, 100005, 100001),(109112, 100005, 100003),(109113, 100005, 100006),(109114, 100005, 100007);
|
||||||
|
|
||||||
|
INSERT INTO comment_likes (id, comment_id, user_id) VALUES
|
||||||
|
(109201, 100001, 100001),(109202, 100001, 100006),(109203, 100001, 100007),
|
||||||
|
(109204, 100003, 100001),(109205, 100003, 100006),
|
||||||
|
(109206, 100006, 100001),(109207, 100006, 100004),
|
||||||
|
(109208, 100009, 100001),(109209, 100009, 100007),
|
||||||
|
(109210, 100011, 100002),(109211, 100011, 100006),(109212, 100011, 100007);
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
INSERT INTO games (id, name, icon, category, sort_order) VALUES
|
||||||
|
(100001, '英雄联盟', '🎮', 'MOBA', 1),
|
||||||
|
(100002, '王者荣耀', '👑', 'MOBA', 2),
|
||||||
|
(100003, 'VALORANT', '🔫', 'FPS', 3),
|
||||||
|
(100004, '永劫无间', '⚔️', 'ACT', 4),
|
||||||
|
(100005, '原神', '🌟', 'RPG', 5),
|
||||||
|
(100006, 'CS2', '💣', 'FPS', 6),
|
||||||
|
(100007, '绝地求生', '🪖', 'FPS', 7),
|
||||||
|
(100008, '和平精英', '🎯', 'FPS', 8);
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
INSERT INTO orders (id, consumer_id, player_id, shop_id, service_snapshot, status, total_price, note) VALUES
|
||||||
|
(100001, 100006, 100001, 100001,
|
||||||
|
'{"serviceId":100001,"title":"LOL 钻石上分","price":99.00,"unit":"段","gameName":"英雄联盟"}'::jsonb,
|
||||||
|
'completed', 99.00, '希望快点上分'),
|
||||||
|
(100002, 100006, 100002, 100001,
|
||||||
|
'{"serviceId":100004,"title":"LOL 大师冲击","price":199.00,"unit":"段","gameName":"英雄联盟"}'::jsonb,
|
||||||
|
'in_progress', 199.00, '大师冲宗师'),
|
||||||
|
(100003, 100007, 100003, 100002,
|
||||||
|
'{"serviceId":100006,"title":"VALORANT 不朽上分","price":150.00,"unit":"段","gameName":"VALORANT"}'::jsonb,
|
||||||
|
'pending_accept', 150.00, null),
|
||||||
|
(100004, 100007, 100001, 100001,
|
||||||
|
'{"serviceId":100002,"title":"LOL 排位陪玩","price":30.00,"unit":"局","gameName":"英雄联盟"}'::jsonb,
|
||||||
|
'completed', 30.00, '陪玩两局'),
|
||||||
|
(100005, 100006, 100004, 100003,
|
||||||
|
'{"serviceId":100010,"title":"原神深渊代打","price":80.00,"unit":"次","gameName":"原神"}'::jsonb,
|
||||||
|
'pending_payment', 80.00, '深渊满星');
|
||||||
|
|
||||||
|
INSERT INTO order_state_logs (id, order_id, from_status, to_status, action, actor_id, actor_role) VALUES
|
||||||
|
(100001, 100001, null, 'pending_payment', 'create', 100006, 'consumer'),
|
||||||
|
(100002, 100001, 'pending_payment', 'pending_accept', 'pay', 100006, 'consumer'),
|
||||||
|
(100003, 100001, 'pending_accept', 'in_progress', 'accept', 100001, 'player'),
|
||||||
|
(100004, 100001, 'in_progress', 'pending_close', 'finish', 100001, 'player'),
|
||||||
|
(100005, 100001, 'pending_close', 'completed', 'confirm', 100006, 'consumer'),
|
||||||
|
(100006, 100002, null, 'pending_payment', 'create', 100006, 'consumer'),
|
||||||
|
(100007, 100002, 'pending_payment', 'pending_accept', 'pay', 100006, 'consumer'),
|
||||||
|
(100008, 100002, 'pending_accept', 'in_progress', 'accept', 100002, 'player'),
|
||||||
|
(100009, 100003, null, 'pending_payment', 'create', 100007, 'consumer'),
|
||||||
|
(100010, 100003, 'pending_payment', 'pending_accept', 'pay', 100007, 'consumer'),
|
||||||
|
(100011, 100004, null, 'pending_payment', 'create', 100007, 'consumer'),
|
||||||
|
(100012, 100004, 'pending_payment', 'pending_accept', 'pay', 100007, 'consumer'),
|
||||||
|
(100013, 100004, 'pending_accept', 'in_progress', 'accept', 100001, 'player'),
|
||||||
|
(100014, 100004, 'in_progress', 'pending_close', 'finish', 100001, 'player'),
|
||||||
|
(100015, 100004, 'pending_close', 'completed', 'confirm', 100007, 'consumer'),
|
||||||
|
(100016, 100005, null, 'pending_payment', 'create', 100006, 'consumer');
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
INSERT INTO players (id, user_id, status, rating, total_orders, completed_orders, gender, tags, games, shop_id) VALUES
|
||||||
|
(100000, 100000, 'available', 5.00, 0, 0, false, ARRAY['LOL王者','VALORANT不朽','多游戏'], ARRAY[100001,100002,100003,100005]::bigint[], 100000),
|
||||||
|
(100001, 100001, 'available', 4.85, 128, 120, false, ARRAY['中单','法师','上分快'], ARRAY[100001,100002]::bigint[], 100001),
|
||||||
|
(100002, 100002, 'available', 4.72, 95, 88, true, ARRAY['上单','刺客','高端局'], ARRAY[100001]::bigint[], 100001),
|
||||||
|
(100003, 100003, 'busy', 4.90, 67, 65, false, ARRAY['决斗','不朽段位'], ARRAY[100003]::bigint[], 100002),
|
||||||
|
(100004, 100008, 'available', 4.60, 42, 38, true, ARRAY['全能','多游戏'], ARRAY[100001,100003,100005]::bigint[], 100003);
|
||||||
|
|
||||||
|
INSERT INTO player_services (id, player_id, game_id, title, description, price, unit, rank_range, availability) VALUES
|
||||||
|
(100001, 100001, 100001, 'LOL 钻石上分', '钻石到大师,稳定上分', 99.00, '段', '钻石→大师', ARRAY['周一至周五','晚间']),
|
||||||
|
(100002, 100001, 100001, 'LOL 排位陪玩', '钻石段位陪玩,轻松愉快', 30.00, '局', '钻石', ARRAY['全天']),
|
||||||
|
(100003, 100001, 100002, '王者荣耀 星耀上分', '星耀到王者,快速安全', 68.00, '段', '星耀→王者', ARRAY['全天']),
|
||||||
|
(100004, 100002, 100001, 'LOL 大师冲击', '大师到宗师,高端局专精', 199.00, '段', '大师→宗师', ARRAY['周末','晚间']),
|
||||||
|
(100005, 100002, 100001, 'LOL 定位赛代打', '10局定位赛,保底铂金', 50.00, '10局','定位赛', ARRAY['全天']),
|
||||||
|
(100006, 100003, 100003, 'VALORANT 不朽上分', '永恒到不朽,决斗位专精', 150.00, '段', '永恒→不朽', ARRAY['晚间','周末']),
|
||||||
|
(100007, 100003, 100003, 'VALORANT 陪玩', '不朽段位陪玩,教学向', 40.00, '局', '不朽', ARRAY['全天']),
|
||||||
|
(100008, 100004, 100001, 'LOL 黄金上分', '黄金到铂金,新手友好', 39.00, '段', '黄金→铂金', ARRAY['全天']),
|
||||||
|
(100009, 100004, 100003, 'VALORANT 白银上分', '白银到黄金,基础教学', 45.00, '段', '白银→黄金', ARRAY['全天']),
|
||||||
|
(100010, 100004, 100005, '原神深渊代打', '深渊12层满星', 80.00, '次', '深渊12层', ARRAY['全天']),
|
||||||
|
(100011, 100000, 100001, 'LOL 全段位上分', '铂金到王者全段位接单,经验丰富', 88.00, '段', '铂金→王者', ARRAY['全天']),
|
||||||
|
(100012, 100000, 100003, 'VALORANT 高端陪玩','不朽段位陪练,教学向,耐心稳重', 50.00, '局', '不朽', ARRAY['晚间','周末']),
|
||||||
|
(100013, 100000, 100002, '王者荣耀 巅峰赛带飞','巅峰赛 2300+ 老玩家,稳定上分', 66.00, '段', '星耀→王者', ARRAY['全天']);
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user