Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 430cc63eb2 | |||
| d9a41c9831 | |||
| e92bdf30d9 | |||
| c456f3e296 | |||
| cba510c675 | |||
| 8697569b81 | |||
| 20ca50c127 | |||
| 2d4dc236e9 | |||
| f3b12f30f0 | |||
| 2a41969771 | |||
| d1ff2661d1 | |||
| 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 |
+5
-1
@@ -119,7 +119,11 @@ dist
|
||||
|
||||
# End of https://mrkandreev.name/snippets/gitignore-generator/#Node
|
||||
|
||||
DockerFile
|
||||
/app/*/api/Dockerfile
|
||||
/app/*/rpc/Dockerfile
|
||||
/app/*/mq/Dockerfile
|
||||
/app/*/adapter/Dockerfile
|
||||
/app/*/test/Dockerfile
|
||||
.idea
|
||||
|
||||
# Go compiled binaries
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "frontend"]
|
||||
path = frontend
|
||||
url = https://git.juwan.xhttp.zip/juwan/juwan-frontend.git
|
||||
@@ -20,7 +20,7 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||
svcCtx := svc.NewServiceContext(c)
|
||||
|
||||
handler := chathandler.NewHandler(svcCtx)
|
||||
|
||||
@@ -17,8 +17,8 @@ Hybrid:
|
||||
Wt:
|
||||
Addr: :8443
|
||||
Path: /wt/chat
|
||||
CertFile: /etc/certs/tls.crt
|
||||
KeyFile: /etc/certs/tls.key
|
||||
CertFile: "${CHAT_WT_CERT_FILE}"
|
||||
KeyFile: "${CHAT_WT_KEY_FILE}"
|
||||
Auth:
|
||||
Enabled: true
|
||||
FallbackStrategy: auto
|
||||
@@ -29,18 +29,18 @@ Hybrid:
|
||||
WsHeaderName: x-auth-user-id
|
||||
WtTokenSource: cookie
|
||||
WtTokenName: JToken
|
||||
WtJWTSecret: MGUyMWE3ZDhjMTQ5ZDg1MWViOWU0MGM3OTE2NWVkYTBlOTE5ZWRkZDU1YjYzOGJjOWRiNzM0NTc4NDIyMjlkZQ
|
||||
WtJWTSecret: "${JWT_SECRET_KEY}"
|
||||
|
||||
Stateless:
|
||||
PollInterval: 100ms
|
||||
BatchSize: 100
|
||||
|
||||
Mongo:
|
||||
URI: mongodb://mongo:27017
|
||||
Database: juwan_chat
|
||||
URI: "${MONGO_URI}"
|
||||
Database: "${MONGO_DATABASE}"
|
||||
|
||||
Redis:
|
||||
Addr: redis:6379
|
||||
Addr: "${REDIS_HOST}:${REDIS_PORT}"
|
||||
|
||||
Log:
|
||||
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
|
||||
|
||||
WORKDIR /build
|
||||
ENV GOTOOLCHAIN=auto
|
||||
ENV GOPROXY=https://goproxy.cn,direct
|
||||
|
||||
COPY go-wst/ go-wst/
|
||||
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
|
||||
Ws:
|
||||
Name: chat-ws
|
||||
Addr: :28888
|
||||
Addr: :28889
|
||||
Path: /ws/chat
|
||||
MaxConnections: 10000
|
||||
Auth:
|
||||
Enabled: true
|
||||
Source: envoy-header
|
||||
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
|
||||
MaxRetries: 3
|
||||
MaxConnections: 10000
|
||||
|
||||
@@ -21,6 +21,8 @@ Hybrid:
|
||||
KeyFile: /etc/certs/tls.key
|
||||
Auth:
|
||||
Enabled: true
|
||||
Auth:
|
||||
Enabled: true
|
||||
FallbackStrategy: auto
|
||||
MaxRetries: 3
|
||||
MaxConnections: 10000
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
Name: pb.rpc
|
||||
ListenOn: 0.0.0.0:28080
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
@@ -12,7 +12,6 @@ echo ""
|
||||
cleanup() {
|
||||
echo ""
|
||||
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
|
||||
echo "=== Stopping containers ==="
|
||||
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"
|
||||
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 ==="
|
||||
docker compose -f "$SCRIPT_DIR/docker-compose.yml" up -d 2>&1 | tee -a "$LOG_DIR/build.log"
|
||||
echo ""
|
||||
@@ -39,24 +54,37 @@ sleep 3
|
||||
echo "Services should be ready."
|
||||
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 ==="
|
||||
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]}
|
||||
echo ""
|
||||
|
||||
echo "=== Step 5: Running WebTransport fallback tests ==="
|
||||
python3 test_wt.py 2>&1 | tee "$LOG_DIR/wt_test_stdout.log"
|
||||
WT_RC=${PIPESTATUS[0]}
|
||||
echo "=== Step 5: Running WebTransport fallback tests (WS) ==="
|
||||
ALL_PROXY= HTTP_PROXY= HTTPS_PROXY= NO_PROXY=* "$VENV_PYTHON" test_wt.py 2>&1 | tee "$LOG_DIR/wt_test_stdout.log"
|
||||
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 "=== Test Summary ==="
|
||||
echo "WebSocket test: $([ $WS_RC -eq 0 ] && echo 'PASSED' || echo 'FAILED')"
|
||||
echo "WebTransport test: $([ $WT_RC -eq 0 ] && echo 'PASSED' || echo 'FAILED')"
|
||||
echo "WebSocket test: $([ $WS_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 "Logs saved to: $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
|
||||
fi
|
||||
|
||||
@@ -22,7 +22,7 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||
|
||||
server := rest.MustNewServer(c.RestConf)
|
||||
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
||||
|
||||
@@ -7,16 +7,13 @@ Prometheus:
|
||||
Port: 4001
|
||||
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:
|
||||
Endpoints:
|
||||
- community-rpc:8080
|
||||
- "${COMMUNITY_RPC_TARGET}"
|
||||
|
||||
UsercenterRpcConf:
|
||||
Endpoints:
|
||||
- user-rpc:8080
|
||||
- "${USER_RPC_TARGET}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
package types
|
||||
|
||||
type Comment struct {
|
||||
Id int64 `json:"id"`
|
||||
Id int64 `json:"id,string"`
|
||||
Content string `json:"content"`
|
||||
Author UserProfile `json:"author"`
|
||||
LikeCount int64 `json:"likeCount"`
|
||||
@@ -54,12 +54,12 @@ type PathId struct {
|
||||
}
|
||||
|
||||
type Post struct {
|
||||
Id int64 `json:"id"`
|
||||
Id int64 `json:"id,string"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
Images []string `json:"images"`
|
||||
Tags []string `json:"tags"`
|
||||
LinkedOrderId int64 `json:"linkedOrderId,optional"`
|
||||
LinkedOrderId int64 `json:"linkedOrderId,string,optional"`
|
||||
Pinned bool `json:"pinned"`
|
||||
LikeCount int64 `json:"likeCount"`
|
||||
CommentCount int64 `json:"commentCount"`
|
||||
|
||||
@@ -6,36 +6,18 @@ Prometheus:
|
||||
Port: 4001
|
||||
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:
|
||||
Endpoints:
|
||||
- snowflake:8080
|
||||
- "${SNOWFLAKE_RPC_TARGET}"
|
||||
|
||||
DB:
|
||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
Slaves: "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}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
|
||||
CacheConf:
|
||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||
Type: node
|
||||
Pass: "${REDIS_PASSWORD}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -22,7 +22,7 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||
|
||||
server := rest.MustNewServer(c.RestConf)
|
||||
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
||||
|
||||
@@ -7,13 +7,17 @@ Prometheus:
|
||||
Port: 4001
|
||||
Path: /metrics
|
||||
|
||||
# ===== DEV CONFIG =====
|
||||
DisputeRpcConf:
|
||||
Endpoints:
|
||||
- dispute-rpc:8080
|
||||
- "${DISPUTE_RPC_TARGET}"
|
||||
|
||||
OrderRpcConf:
|
||||
Endpoints:
|
||||
- order-rpc:8080
|
||||
- "${ORDER_RPC_TARGET}"
|
||||
|
||||
PlayerRpcConf:
|
||||
Endpoints:
|
||||
- player-rpc:8080
|
||||
- "${PLAYER_RPC_TARGET}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -15,11 +15,11 @@ type CreateDisputeReq struct {
|
||||
}
|
||||
|
||||
type Dispute struct {
|
||||
Id int64 `json:"id"`
|
||||
OrderId int64 `json:"orderId"`
|
||||
InitiatorId int64 `json:"initiatorId"`
|
||||
Id int64 `json:"id,string"`
|
||||
OrderId int64 `json:"orderId,string"`
|
||||
InitiatorId int64 `json:"initiatorId,string"`
|
||||
InitiatorName string `json:"initiatorName"`
|
||||
RespondentId int64 `json:"respondentId"`
|
||||
RespondentId int64 `json:"respondentId,string"`
|
||||
Reason string `json:"reason"`
|
||||
Evidence []string `json:"evidence"`
|
||||
Status string `json:"status"`
|
||||
@@ -28,7 +28,7 @@ type Dispute struct {
|
||||
RespondentEvidence []string `json:"respondentEvidence"`
|
||||
AppealReason string `json:"appealReason,optional"`
|
||||
AppealedAt string `json:"appealedAt,optional"`
|
||||
ResolvedBy int64 `json:"resolvedBy,optional"`
|
||||
ResolvedBy int64 `json:"resolvedBy,string,optional"`
|
||||
ResolvedAt string `json:"resolvedAt,optional"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
UpdatedAt string `json:"updatedAt"`
|
||||
|
||||
@@ -6,18 +6,18 @@ Prometheus:
|
||||
Port: 4001
|
||||
Path: /metrics
|
||||
|
||||
# ===== DEV CONF =====
|
||||
SnowflakeRpcConf:
|
||||
Endpoints:
|
||||
- snowflake:8080
|
||||
- "${SNOWFLAKE_RPC_TARGET}"
|
||||
|
||||
DB:
|
||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
Slaves: "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}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
|
||||
CacheConf:
|
||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||
Type: node
|
||||
Pass: "${REDIS_PASSWORD}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -7,21 +7,10 @@ Prometheus:
|
||||
Port: 4001
|
||||
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:
|
||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||
Type: node
|
||||
Pass: "${REDIS_PASSWORD}"
|
||||
|
||||
Kmq:
|
||||
Name: email-api
|
||||
@@ -29,3 +18,6 @@ Kmq:
|
||||
- "${KAFKA_BROKER}"
|
||||
Group: "email-api-group"
|
||||
Topic: "email-task"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -30,15 +30,5 @@ Mail:
|
||||
InsecureSkipVerify: false
|
||||
ReplyTo: "${EMAIL_REPLY_TO}"
|
||||
|
||||
# Mail:
|
||||
# Enabled: true
|
||||
# Host: "smtp.163.com"
|
||||
# Port: 465
|
||||
# Username: "churong2646@163.com"
|
||||
# Password: "GTv6C6qNbv5urAiD"
|
||||
# FromAddress: "churong2646@163.com"
|
||||
# FromName: "聚玩"
|
||||
# UseSSL: true
|
||||
# UseStartTLS: false
|
||||
# InsecureSkipVerify: false
|
||||
# ReplyTo: ""
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -7,14 +7,9 @@ Prometheus:
|
||||
Port: 4001
|
||||
Path: /metrics
|
||||
|
||||
# ===== PROC CONF =====
|
||||
#GameRpcConf:
|
||||
# Target: k8s://juwan/game-rpc-svc:8080
|
||||
|
||||
# ===== DEV CONF =====
|
||||
GameRpcConf:
|
||||
Endpoints:
|
||||
- game-rpc:8080
|
||||
- "${GAME_RPC_TARGET}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
@@ -22,7 +22,7 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||
|
||||
server := rest.MustNewServer(c.RestConf)
|
||||
server.Use(middlewares.NewRequestMiddleware().Handle)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.9.2
|
||||
// goctl 1.10.1
|
||||
|
||||
package handler
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ type EmptyResp struct {
|
||||
}
|
||||
|
||||
type Game struct {
|
||||
Id int64 `json:"id,optional"`
|
||||
Id int64 `json:"id,string,optional"`
|
||||
Name string `json:"name"`
|
||||
Icon string `json:"icon"`
|
||||
Category string `json:"category"`
|
||||
|
||||
@@ -6,40 +6,18 @@ Prometheus:
|
||||
Port: 4001
|
||||
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:
|
||||
Endpoints:
|
||||
- snowflake:8080
|
||||
- "${SNOWFLAKE_RPC_TARGET}"
|
||||
|
||||
DB:
|
||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
Slaves: "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}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
|
||||
CacheConf:
|
||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||
Type: node
|
||||
Pass: "${REDIS_PASSWORD}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -7,7 +7,9 @@ Prometheus:
|
||||
Port: 4001
|
||||
Path: /metrics
|
||||
|
||||
# ===== DEV CONFIG =====
|
||||
NotificationRpcConf:
|
||||
Endpoints:
|
||||
- notification-rpc:8080
|
||||
- "${NOTIFICATION_RPC_TARGET}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -7,7 +7,7 @@ type EmptyResp struct {
|
||||
}
|
||||
|
||||
type Notification struct {
|
||||
Id int64 `json:"id"`
|
||||
Id int64 `json:"id,string"`
|
||||
Type string `json:"type"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
|
||||
@@ -22,7 +22,7 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||
|
||||
server := rest.MustNewServer(c.RestConf)
|
||||
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
||||
|
||||
@@ -6,18 +6,18 @@ Prometheus:
|
||||
Port: 4001
|
||||
Path: /metrics
|
||||
|
||||
# ===== DEV CONF =====
|
||||
SnowflakeRpcConf:
|
||||
Endpoints:
|
||||
- snowflake:8080
|
||||
- "${SNOWFLAKE_RPC_TARGET}"
|
||||
|
||||
DB:
|
||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
Slaves: "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}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
|
||||
CacheConf:
|
||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||
Type: node
|
||||
Pass: "${REDIS_PASSWORD}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -7,21 +7,9 @@ Prometheus:
|
||||
Port: 4001
|
||||
Path: /metrics
|
||||
|
||||
|
||||
# ===== PROC CONF =====
|
||||
#FileRpcConf:
|
||||
# Target: k8s://juwan/objectstory-rpc-svc:8080
|
||||
#
|
||||
#Log:
|
||||
# Level: info
|
||||
|
||||
# ===== DEV CONF =====
|
||||
FileRpcConf:
|
||||
Endpoints:
|
||||
- objectstory-rpc:8080
|
||||
- "${OBJECTSTORY_RPC_TARGET}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
# k8s://juwan/<service name>:8080
|
||||
|
||||
Level: debug
|
||||
|
||||
@@ -22,7 +22,7 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||
|
||||
server := rest.MustNewServer(c.RestConf)
|
||||
server.Use(middlewares.NewRequestMiddleware().Handle)
|
||||
|
||||
@@ -6,36 +6,13 @@ Prometheus:
|
||||
Port: 4001
|
||||
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:
|
||||
Endpoint: "https://cn-nb1.rains3.com"
|
||||
AccessKey: "mfgGnaAcUDP2zYAi"
|
||||
SecretKey: "ZfKkbhUvsAchiKlxzIXrDHrSyskyRj"
|
||||
Bucket: "juwan-dev-image-zj"
|
||||
Region: auto
|
||||
Endpoint: "${S3_ENDPOINT}"
|
||||
AccessKey: "${S3_ACCESS_KEY}"
|
||||
SecretKey: "${S3_SECRET_KEY}"
|
||||
Bucket: "${S3_BUCKET_NAME}"
|
||||
Region: "${S3_REGION}"
|
||||
UsePathStyle: true
|
||||
|
||||
Log:
|
||||
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()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||
ctx := svc.NewServiceContext(c)
|
||||
|
||||
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
|
||||
|
||||
@@ -7,26 +7,17 @@ Prometheus:
|
||||
Port: 4001
|
||||
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:
|
||||
Endpoints:
|
||||
- order-rpc:8080
|
||||
- "${ORDER_RPC_TARGET}"
|
||||
|
||||
PlayerRpcConf:
|
||||
Endpoints:
|
||||
- player-rpc:8080
|
||||
- "${PLAYER_RPC_TARGET}"
|
||||
|
||||
ShopRpcConf:
|
||||
Endpoints:
|
||||
- shop-rpc:8080
|
||||
- "${SHOP_RPC_TARGET}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
package types
|
||||
|
||||
type CreateOrderReq struct {
|
||||
PlayerId int64 `json:"playerId"`
|
||||
ShopId int64 `json:"shopId,optional"`
|
||||
ServiceId int64 `json:"serviceId"`
|
||||
PlayerId int64 `json:"playerId,string"`
|
||||
ShopId int64 `json:"shopId,string,optional"`
|
||||
ServiceId int64 `json:"serviceId,string"`
|
||||
Quantity int `json:"quantity"`
|
||||
Note string `json:"note,optional"`
|
||||
}
|
||||
@@ -20,10 +20,10 @@ type EmptyResp struct {
|
||||
}
|
||||
|
||||
type Order struct {
|
||||
Id int64 `json:"id"`
|
||||
ConsumerId int64 `json:"consumerId"`
|
||||
Id int64 `json:"id,string"`
|
||||
ConsumerId int64 `json:"consumerId,string"`
|
||||
PlayerId string `json:"playerId"`
|
||||
ShopId int64 `json:"shopId,optional"`
|
||||
ShopId int64 `json:"shopId,string,optional"`
|
||||
Service PlayerService `json:"service"`
|
||||
Status string `json:"status"`
|
||||
TotalPrice float64 `json:"totalPrice"`
|
||||
@@ -60,9 +60,9 @@ type PathId struct {
|
||||
}
|
||||
|
||||
type PlayerService struct {
|
||||
Id int64 `json:"id"`
|
||||
PlayerId int64 `json:"playerId"`
|
||||
GameId int64 `json:"gameId"`
|
||||
Id int64 `json:"id,string"`
|
||||
PlayerId int64 `json:"playerId,string"`
|
||||
GameId int64 `json:"gameId,string"`
|
||||
GameName string `json:"gameName"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
|
||||
@@ -22,7 +22,7 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||
|
||||
server := rest.MustNewServer(c.RestConf)
|
||||
server.Use(middlewares.NewRequestMiddleware().Handle)
|
||||
|
||||
@@ -1,54 +1,23 @@
|
||||
Name: pb.rpc
|
||||
ListenOn: 0.0.0.0:8080
|
||||
|
||||
|
||||
Prometheus:
|
||||
Host: 0.0.0.0
|
||||
Port: 4001
|
||||
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:
|
||||
Endpoints:
|
||||
- snowflake:8080
|
||||
- "${SNOWFLAKE_RPC_TARGET}"
|
||||
|
||||
DB:
|
||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
Slaves: "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}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
|
||||
CacheConf:
|
||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||
Type: node
|
||||
Pass: "${REDIS_PASSWORD}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
@@ -7,15 +7,13 @@ Prometheus:
|
||||
Port: 4001
|
||||
Path: /metrics
|
||||
|
||||
# k8s://juwan/<service name>:8080
|
||||
# ===== PROC CONF =====
|
||||
#PlayerRpcConf:
|
||||
# Target: k8s://juwan/player-rpc-svc:8080
|
||||
|
||||
# ===== DEV CONF ====
|
||||
PlayerRpcConf:
|
||||
Endpoints:
|
||||
- player-rpc:8080
|
||||
- "${PLAYER_RPC_TARGET}"
|
||||
|
||||
UsercenterRpcConf:
|
||||
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",
|
||||
Handler: player.InitPlayerHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 获取当前用户的打手资料
|
||||
Method: http.MethodGet,
|
||||
Path: "/players/me",
|
||||
Handler: player.GetMyPlayerHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 更新接单状态
|
||||
Method: http.MethodPut,
|
||||
|
||||
@@ -45,15 +45,20 @@ func (l *GetPlayerLogic) GetPlayer(req *types.GetPlayerReq) (resp *types.PlayerP
|
||||
if player == nil {
|
||||
return nil, errors.New("player not found")
|
||||
}
|
||||
completionRate := 0.0
|
||||
if player.TotalOrders > 0 {
|
||||
completionRate = float64(player.CompletedOrders) / float64(player.TotalOrders)
|
||||
}
|
||||
|
||||
resp = &types.PlayerProfile{
|
||||
Id: player.Id,
|
||||
Rating: player.Rating,
|
||||
TotalOrders: player.TotalOrders,
|
||||
Status: player.Status,
|
||||
Gender: player.Gender,
|
||||
Services: []types.PlayerService{},
|
||||
Tags: append([]string{}, player.Tags...),
|
||||
Id: player.Id,
|
||||
Rating: player.Rating,
|
||||
TotalOrders: player.TotalOrders,
|
||||
CompletionRate: completionRate,
|
||||
Status: player.Status,
|
||||
Gender: player.Gender,
|
||||
Services: []types.PlayerService{},
|
||||
Tags: append([]string{}, player.Tags...),
|
||||
}
|
||||
|
||||
games := make([]string, 0, len(player.Games))
|
||||
|
||||
@@ -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
|
||||
|
||||
type CreateServiceReq struct {
|
||||
GameId int64 `json:"gameId,optional"`
|
||||
GameId int64 `json:"gameId,string,optional"`
|
||||
Title string `json:"title,optional"`
|
||||
Description string `json:"description,optional"`
|
||||
Price float64 `json:"price"`
|
||||
@@ -56,7 +56,7 @@ type PlayerListResp struct {
|
||||
}
|
||||
|
||||
type PlayerProfile struct {
|
||||
Id int64 `json:"id"`
|
||||
Id int64 `json:"id,string"`
|
||||
User UserProfile `json:"user"`
|
||||
Rating float64 `json:"rating"`
|
||||
TotalOrders int64 `json:"totalOrders"`
|
||||
@@ -71,9 +71,9 @@ type PlayerProfile struct {
|
||||
}
|
||||
|
||||
type PlayerService struct {
|
||||
Id int64 `json:"id,optional"`
|
||||
PlayerId int64 `json:"playerId"`
|
||||
GameId int64 `json:"gameId"`
|
||||
Id int64 `json:"id,string,optional"`
|
||||
PlayerId int64 `json:"playerId,string"`
|
||||
GameId int64 `json:"gameId,string"`
|
||||
GameName string `json:"gameName"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
@@ -100,7 +100,7 @@ type UpdatePlayerStatusReq struct {
|
||||
|
||||
type UpdateServiceReq struct {
|
||||
Id int64 `path:"id"`
|
||||
GameId *int64 `json:"gameId,optional"`
|
||||
GameId *int64 `json:"gameId,string,optional"`
|
||||
Title *string `json:"title,optional"`
|
||||
Description *string `json:"description,optional"`
|
||||
Price *float64 `json:"price,optional"`
|
||||
|
||||
@@ -22,7 +22,7 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||
|
||||
server := rest.MustNewServer(c.RestConf)
|
||||
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
||||
|
||||
@@ -1,48 +1,23 @@
|
||||
Name: pb.rpc
|
||||
ListenOn: 0.0.0.0:8080
|
||||
|
||||
|
||||
Prometheus:
|
||||
Host: 0.0.0.0
|
||||
Port: 4001
|
||||
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:
|
||||
Endpoints:
|
||||
- snowflake:8080
|
||||
- "${SNOWFLAKE_RPC_TARGET}"
|
||||
|
||||
DB:
|
||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
Slaves: "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}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
|
||||
CacheConf:
|
||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||
Type: node
|
||||
Pass: "${REDIS_PASSWORD}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -7,13 +7,17 @@ Prometheus:
|
||||
Port: 4001
|
||||
Path: /metrics
|
||||
|
||||
# ===== DEV CONFIG =====
|
||||
ReviewRpcConf:
|
||||
Endpoints:
|
||||
- review-rpc:8080
|
||||
- "${REVIEW_RPC_TARGET}"
|
||||
|
||||
OrderRpcConf:
|
||||
Endpoints:
|
||||
- order-rpc:8080
|
||||
- "${ORDER_RPC_TARGET}"
|
||||
|
||||
PlayerRpcConf:
|
||||
Endpoints:
|
||||
- player-rpc:8080
|
||||
- "${PLAYER_RPC_TARGET}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -27,9 +27,9 @@ type PageReq struct {
|
||||
}
|
||||
|
||||
type Review struct {
|
||||
Id int64 `json:"id"`
|
||||
OrderId int64 `json:"orderId"`
|
||||
FromUserId int64 `json:"fromUserId"`
|
||||
Id int64 `json:"id,string"`
|
||||
OrderId int64 `json:"orderId,string"`
|
||||
FromUserId int64 `json:"fromUserId,string"`
|
||||
FromUserName string `json:"fromUserName"`
|
||||
Rating int `json:"rating"`
|
||||
Content string `json:"content"`
|
||||
|
||||
@@ -22,7 +22,7 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||
|
||||
server := rest.MustNewServer(c.RestConf)
|
||||
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
||||
|
||||
@@ -6,18 +6,18 @@ Prometheus:
|
||||
Port: 4001
|
||||
Path: /metrics
|
||||
|
||||
# ===== DEV CONF =====
|
||||
SnowflakeRpcConf:
|
||||
Endpoints:
|
||||
- snowflake:8080
|
||||
- "${SNOWFLAKE_RPC_TARGET}"
|
||||
|
||||
DB:
|
||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
Slaves: "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}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
|
||||
CacheConf:
|
||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||
Type: node
|
||||
Pass: "${REDIS_PASSWORD}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -7,7 +7,9 @@ Prometheus:
|
||||
Port: 4001
|
||||
Path: /metrics
|
||||
|
||||
# ===== DEV CONFIG =====
|
||||
SearchRpcConf:
|
||||
Endpoints:
|
||||
- search-rpc:8080
|
||||
- "${SEARCH_RPC_TARGET}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -22,7 +22,7 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||
|
||||
server := rest.MustNewServer(c.RestConf)
|
||||
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
||||
|
||||
@@ -6,18 +6,18 @@ Prometheus:
|
||||
Port: 4001
|
||||
Path: /metrics
|
||||
|
||||
# ===== DEV CONF =====
|
||||
SnowflakeRpcConf:
|
||||
Endpoints:
|
||||
- snowflake:8080
|
||||
- "${SNOWFLAKE_RPC_TARGET}"
|
||||
|
||||
DB:
|
||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
Slaves: "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}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
|
||||
CacheConf:
|
||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||
Type: node
|
||||
Pass: "${REDIS_PASSWORD}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -7,17 +7,13 @@ Prometheus:
|
||||
Port: 4001
|
||||
Path: /metrics
|
||||
|
||||
# k8s://juwan/<service name>:8080
|
||||
|
||||
# ===== PROC CONFIG =====
|
||||
#ShopRpcConf:
|
||||
# Target: k8s://juwan/shop-rpc-svc.juwan:8080
|
||||
|
||||
|
||||
# ===== DEV CONFIG ====
|
||||
ShopRpcConf:
|
||||
Endpoints:
|
||||
- shop-rpc:8080
|
||||
- "${SHOP_RPC_TARGET}"
|
||||
|
||||
PlayerRpcConf:
|
||||
Endpoints:
|
||||
- player-rpc:8080
|
||||
- "${PLAYER_RPC_TARGET}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -37,7 +37,7 @@ type IncomeStatsResp struct {
|
||||
|
||||
type InvitationReq struct {
|
||||
Id int64 `path:"id"`
|
||||
PlayerId int64 `json:"playerId"`
|
||||
PlayerId int64 `json:"playerId,string"`
|
||||
}
|
||||
|
||||
type PageMeta struct {
|
||||
@@ -61,11 +61,11 @@ type ShopIdReq struct {
|
||||
}
|
||||
|
||||
type ShopInvitation struct {
|
||||
Id int64 `json:"id"`
|
||||
ShopId int64 `json:"shopId"`
|
||||
PlayerId int64 `json:"playerId"`
|
||||
Id int64 `json:"id,string"`
|
||||
ShopId int64 `json:"shopId,string"`
|
||||
PlayerId int64 `json:"playerId,string"`
|
||||
Status string `json:"status"`
|
||||
InvitedBy int64 `json:"invitedBy"`
|
||||
InvitedBy int64 `json:"invitedBy,string"`
|
||||
CreatedAt int64 `json:"createdAt"`
|
||||
RespondedAt int64 `json:"respondedAt,optional"`
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||
|
||||
server := rest.MustNewServer(c.RestConf)
|
||||
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
||||
|
||||
@@ -6,53 +6,22 @@ Prometheus:
|
||||
Port: 4001
|
||||
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:
|
||||
Endpoints:
|
||||
- snowflake:8080
|
||||
- "${SNOWFLAKE_RPC_TARGET}"
|
||||
|
||||
UsersRpcConf:
|
||||
Endpoints:
|
||||
- user-rpc:8080
|
||||
- "${USER_RPC_TARGET}"
|
||||
|
||||
DB:
|
||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
Slaves: "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}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
|
||||
CacheConf:
|
||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||
Type: node
|
||||
Pass: "${REDIS_PASSWORD}"
|
||||
|
||||
Log:
|
||||
Level: info
|
||||
|
||||
|
||||
# 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"
|
||||
Level: debug
|
||||
|
||||
@@ -2,5 +2,5 @@ Name: snowflake.rpc
|
||||
ListenOn: 0.0.0.0:8080
|
||||
|
||||
Snowflake:
|
||||
DatacenterId: 1
|
||||
WorkerId: 0
|
||||
DatacenterId: ${SNOWFLAKE_DATACENTER_ID}
|
||||
WorkerId: ${SNOWFLAKE_WORKER_ID}
|
||||
|
||||
@@ -22,7 +22,7 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||
ctx := svc.NewServiceContext(c)
|
||||
|
||||
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
|
||||
|
||||
@@ -1,45 +1,27 @@
|
||||
Name: pb.rpc
|
||||
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:
|
||||
Endpoints:
|
||||
- snowflake:8080
|
||||
- "${SNOWFLAKE_RPC_TARGET}"
|
||||
|
||||
UserRpcConf:
|
||||
Endpoints:
|
||||
- user-rpc:8080
|
||||
- "${USER_RPC_TARGET}"
|
||||
|
||||
DB:
|
||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
Slave: "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}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
|
||||
CacheConf:
|
||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||
Type: node
|
||||
Pass: "${REDIS_PASSWORD}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -7,19 +7,13 @@ Prometheus:
|
||||
Port: 4001
|
||||
Path: /metrics
|
||||
|
||||
# ===== PROC CONFIG =====
|
||||
#UsercenterRpcConf:
|
||||
# Target: k8s://juwan/user-rpc-svc:8080
|
||||
#UserVerificationRpc:
|
||||
# Target: k8s://juwan/user_verifications-svc:8080
|
||||
|
||||
# ===== DEV CONFIG ====
|
||||
UserVerificationRpc:
|
||||
Endpoints:
|
||||
- user-verifications-rpc:8080
|
||||
- "${USER_VERIFICATIONS_RPC_TARGET}"
|
||||
|
||||
UsercenterRpcConf:
|
||||
Endpoints:
|
||||
- user-rpc:8080
|
||||
- "${USER_RPC_TARGET}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
@@ -125,13 +125,13 @@ type VerificationIdReq struct {
|
||||
}
|
||||
|
||||
type VerificationItem struct {
|
||||
Id int64 `json:"id"` // 认证记录ID (主键,用于管理员操作)
|
||||
UserId int64 `json:"userId"` // 申请人ID (外键)
|
||||
UserNickname string `json:"userNickname"` // 冗余显示,方便前端展示
|
||||
Role string `json:"role"` // 申请角色: player, owner
|
||||
Status string `json:"status"` // pending, approved, rejected
|
||||
Materials map[string]string `json:"materials"` // 核心字段:对应 DB 的 JSONB
|
||||
RejectReason string `json:"rejectReason"` // 驳回原因
|
||||
CreatedAt string `json:"createdAt"` // 申请时间
|
||||
ReviewedAt string `json:"reviewedAt"` // 审核时间
|
||||
Id int64 `json:"id,string"` // 认证记录ID (主键,用于管理员操作)
|
||||
UserId int64 `json:"userId,string"` // 申请人ID (外键)
|
||||
UserNickname string `json:"userNickname"` // 冗余显示,方便前端展示
|
||||
Role string `json:"role"` // 申请角色: player, owner
|
||||
Status string `json:"status"` // pending, approved, rejected
|
||||
Materials map[string]string `json:"materials"` // 核心字段:对应 DB 的 JSONB
|
||||
RejectReason string `json:"rejectReason"` // 驳回原因
|
||||
CreatedAt string `json:"createdAt"` // 申请时间
|
||||
ReviewedAt string `json:"reviewedAt"` // 审核时间
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||
|
||||
server := rest.MustNewServer(c.RestConf)
|
||||
server.Use(middlewares.NewHeaderExtractorMiddleware().Handle)
|
||||
|
||||
+35
-11
@@ -6,14 +6,28 @@ import (
|
||||
"strings"
|
||||
"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/svc"
|
||||
"juwan-backend/common/utils/pwdUtils"
|
||||
"juwan-backend/pkg/types"
|
||||
|
||||
"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) {
|
||||
username := strings.TrimSpace(os.Getenv("ADMIN_USERNAME"))
|
||||
password := strings.TrimSpace(os.Getenv("ADMIN_PASSWORD"))
|
||||
@@ -24,8 +38,9 @@ func initAdmin(svcCtx *svc.ServiceContext) {
|
||||
|
||||
go func() {
|
||||
ctx := context.Background()
|
||||
var existing bool
|
||||
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 i < 29 {
|
||||
time.Sleep(time.Second)
|
||||
@@ -34,10 +49,23 @@ func initAdmin(svcCtx *svc.ServiceContext) {
|
||||
logx.Errorf("check admin user: %v", err)
|
||||
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
|
||||
}
|
||||
break
|
||||
logx.Infof("reconciled admin user: %s", username)
|
||||
return
|
||||
}
|
||||
|
||||
hashedPassword, err := pwdUtils.HashPassword(password)
|
||||
@@ -46,14 +74,8 @@ func initAdmin(svcCtx *svc.ServiceContext) {
|
||||
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().
|
||||
SetID(resp.Id).
|
||||
SetID(adminUserID).
|
||||
SetUsername(username).
|
||||
SetPasswordHash(hashedPassword).
|
||||
SetEmail(email).
|
||||
@@ -63,6 +85,8 @@ func initAdmin(svcCtx *svc.ServiceContext) {
|
||||
SetCurrentRole("consumer").
|
||||
SetNickname(username).
|
||||
SetIsAdmin(true).
|
||||
SetVerifiedRoles(adminVerifiedRoles).
|
||||
SetVerificationStatus(adminVerificationStatus).
|
||||
Save(ctx)
|
||||
if err != nil {
|
||||
logx.Errorf("create admin user: %v", err)
|
||||
|
||||
@@ -6,46 +6,21 @@ Prometheus:
|
||||
Port: 4001
|
||||
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:
|
||||
Endpoints:
|
||||
- snowflake:8080
|
||||
- "${SNOWFLAKE_RPC_TARGET}"
|
||||
|
||||
DB:
|
||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
Slave: "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}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
|
||||
CacheConf:
|
||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||
Type: node
|
||||
Pass: "${REDIS_PASSWORD}"
|
||||
|
||||
Jwt:
|
||||
SecretKey: "MGUyMWE3ZDhjMTQ5ZDg1MWViOWU0MGM3OTE2NWVkYTBlOTE5ZWRkZDU1YjYzOGJjOWRiNzM0NTc4NDIyMjlkZQ"
|
||||
SecretKey: "${JWT_SECRET_KEY}"
|
||||
Issuer: "juwan-user-rpc"
|
||||
|
||||
Log:
|
||||
|
||||
@@ -12,8 +12,7 @@ type JwtConfig struct {
|
||||
|
||||
type Config struct {
|
||||
zrpc.RpcServerConf
|
||||
DataSource string `json:"dataSource"`
|
||||
DB struct {
|
||||
DB struct {
|
||||
Master string
|
||||
Slave string
|
||||
}
|
||||
|
||||
@@ -7,16 +7,9 @@ Prometheus:
|
||||
Port: 4001
|
||||
Path: /metrics
|
||||
|
||||
# ===== PROC CONF =====
|
||||
#WalletRpcConf:
|
||||
# Target: k8s://juwan/wallet-rpc:8080
|
||||
|
||||
|
||||
|
||||
# ===== DEV CONF =====
|
||||
WalletRpcConf:
|
||||
Endpoints:
|
||||
- wallet-rpc:8080
|
||||
|
||||
# k8s://juwan/<service name>:8080
|
||||
- "${WALLET_RPC_TARGET}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.9.2
|
||||
// goctl 1.10.1
|
||||
|
||||
package handler
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.9.2
|
||||
// goctl 1.10.1
|
||||
|
||||
package types
|
||||
|
||||
@@ -29,7 +29,7 @@ type TopupReq struct {
|
||||
}
|
||||
|
||||
type Transaction struct {
|
||||
Id int64 `json:"id"`
|
||||
Id int64 `json:"id,string"`
|
||||
Type string `json:"type"`
|
||||
Amount string `json:"amount"`
|
||||
Description string `json:"description"`
|
||||
|
||||
@@ -22,7 +22,7 @@ func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
conf.MustLoad(*configFile, &c, conf.UseEnv())
|
||||
|
||||
server := rest.MustNewServer(c.RestConf)
|
||||
server.Use(middlewares.NewRequestMiddleware().Handle)
|
||||
|
||||
@@ -1,55 +1,23 @@
|
||||
Name: pb.rpc
|
||||
ListenOn: 0.0.0.0:8080
|
||||
|
||||
|
||||
Prometheus:
|
||||
Host: 0.0.0.0
|
||||
Port: 4001
|
||||
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:
|
||||
Endpoints:
|
||||
- snowflake:8080
|
||||
- "${SNOWFLAKE_RPC_TARGET}"
|
||||
|
||||
DB:
|
||||
Master: "postgresql://${PD_USERNAME}:${DB_PASSWORD}@postgres:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
Slaves: "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}@${DB_HOST_RO}:${DB_PORT}/${DB_NAME}?sslmode=disable"
|
||||
|
||||
CacheConf:
|
||||
- Host: "${REDIS_HOST}:${REDIS_PORT}"
|
||||
Type: node
|
||||
Pass: "${REDIS_PASSWORD}"
|
||||
|
||||
Log:
|
||||
Level: debug
|
||||
@@ -0,0 +1,2 @@
|
||||
GITEA_DOMAIN=git.juwan.xhttp.zip
|
||||
RUNNER_TOKEN=
|
||||
@@ -0,0 +1,4 @@
|
||||
/secrets/
|
||||
/garage/garage.toml
|
||||
/zot/htpasswd
|
||||
/.env
|
||||
@@ -0,0 +1,100 @@
|
||||
# 管理机部署
|
||||
|
||||
Zot(容器仓库)、Garage(对象存储)、Gitea(代码 + Actions Runner)、Caddy(HTTPS 反代 + 业务入口),全部在同一台 center 机器上以 Docker Compose 运行。业务服务部署在另一台 k01 机器上,公网流量经由 center 的 Caddy 反代到 k01 上的 envoy-gateway NodePort。
|
||||
|
||||
部署机参考:center(Vultr High Frequency / 1 vCPU / 1 GB RAM / 32 GB NVMe)。
|
||||
|
||||
## 前置条件
|
||||
|
||||
- Docker Engine 与 compose v2
|
||||
- `apache2-utils`(提供 `htpasswd` 命令,用于给 Zot 生成 bcrypt 密码)
|
||||
- DNS:`git` / `registry` / `s3` / `juwan` 四条 A 记录全部指向 66.135.5.101,灰云直连
|
||||
- 防火墙入站规则允许 TCP 80、443、UDP 443
|
||||
|
||||
## 首次部署
|
||||
|
||||
```bash
|
||||
cd deploy/center
|
||||
|
||||
# 生成所有随机密码与 token,渲染 garage.toml / zot.htpasswd / .env
|
||||
bash init.sh
|
||||
|
||||
# 启动 Caddy + Zot + Garage + Gitea
|
||||
docker compose up -d caddy zot garage gitea
|
||||
|
||||
# 创建 Gitea 管理员
|
||||
docker compose exec -u git gitea gitea admin user create \
|
||||
--username admin \
|
||||
--email admin@juwan.xhttp.zip \
|
||||
--password "$(cat secrets/gitea-admin-password)" \
|
||||
--admin --must-change-password=false
|
||||
|
||||
# 在浏览器打开 https://git.juwan.xhttp.zip
|
||||
# → Site Administration → Actions → Runners → 生成 runner token
|
||||
# → 把 token 写入 .env 的 RUNNER_TOKEN
|
||||
# → 回到终端执行:
|
||||
docker compose up -d runner
|
||||
|
||||
# 初始化 Garage:创建 layout、两个 bucket、生成 access key
|
||||
bash garage/bootstrap.sh
|
||||
```
|
||||
|
||||
`bootstrap.sh` 最后会打印 S3 连接信息,其中 `S3_ACCESS_KEY` / `S3_SECRET_KEY` 留给 k01 的 `objectstory-rpc` 和 CNPG backup 配置。
|
||||
|
||||
## 访问入口
|
||||
|
||||
| 子域 | 内容 |
|
||||
| -------------------------- | ------------------------------------------------- |
|
||||
| `git.juwan.xhttp.zip` | Gitea 代码仓库 |
|
||||
| `registry.juwan.xhttp.zip` | Zot 镜像仓库 + 内置 zui 浏览器 |
|
||||
| `s3.juwan.xhttp.zip` | Garage S3 API |
|
||||
| `juwan.xhttp.zip` | 业务前端,Caddy 反代至 k01 envoy-gateway NodePort |
|
||||
|
||||
## 凭据与认证
|
||||
|
||||
`init.sh` 会把所有密码写入 `secrets/` 目录(权限 600,`.gitignore` 已排除)。`garage/garage.toml` 和 `zot/htpasswd` 由模板渲染生成,同样不在仓库中跟踪。
|
||||
|
||||
### Zot
|
||||
|
||||
匿名用户可浏览 zui、`docker pull` 镜像。推送或删除需要登录:
|
||||
|
||||
```bash
|
||||
docker login registry.juwan.xhttp.zip -u admin -p "$(cat secrets/zot-admin-password)"
|
||||
```
|
||||
|
||||
### Gitea
|
||||
|
||||
注册链接默认关闭。管理员登录后通过以下方式创建新用户:
|
||||
|
||||
```bash
|
||||
docker compose exec -u git gitea gitea admin user create \
|
||||
--username NAME --email MAIL --password PASS
|
||||
```
|
||||
|
||||
## Runner
|
||||
|
||||
通过宿主 `/var/run/docker.sock` 启动 job 容器。Workflow 里写 `runs-on: ubuntu-latest` 时,runner 会拉取 `gitea/runner-images:ubuntu-latest-slim` 作为临时工作环境。`docker build` 命令在此容器内调用宿主的 dockerd,生成的镜像可直接推送到本机 Zot。
|
||||
|
||||
## 日常维护
|
||||
|
||||
```bash
|
||||
docker compose restart # 全部重启
|
||||
docker compose logs -f caddy # 查看 Caddy 日志(含 ACME 信息)
|
||||
docker compose logs -f runner # 查看 Runner 日志(含 job 输出)
|
||||
|
||||
# 彻底重置:删除所有 Compose 卷与 init.sh 生成的本地文件
|
||||
docker compose down -v
|
||||
rm -rf secrets garage/garage.toml zot/htpasswd
|
||||
```
|
||||
|
||||
持久化数据所在的 Docker 卷:
|
||||
|
||||
| 卷 | 内容 |
|
||||
| -------------------- | ------------------------ |
|
||||
| `juwan-caddy-data` | ACME 证书 |
|
||||
| `juwan-caddy-config` | Caddy 自动配置 |
|
||||
| `juwan-zot-data` | 容器镜像层 |
|
||||
| `juwan-garage-meta` | Garage 元数据 |
|
||||
| `juwan-garage-data` | S3 对象数据 |
|
||||
| `juwan-gitea-data` | Git 仓库与 SQLite 数据库 |
|
||||
| `juwan-runner-data` | Runner 注册信息 |
|
||||
@@ -0,0 +1,78 @@
|
||||
{
|
||||
email admin@juwan.xhttp.zip
|
||||
servers {
|
||||
enable_webtransport
|
||||
}
|
||||
}
|
||||
|
||||
(common_log) {
|
||||
log {
|
||||
output stdout
|
||||
format console {
|
||||
time_format common_log
|
||||
time_local
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(stream_proxy) {
|
||||
flush_interval -1
|
||||
transport http {
|
||||
read_timeout 0
|
||||
write_timeout 0
|
||||
response_header_timeout 0
|
||||
}
|
||||
}
|
||||
|
||||
git.juwan.xhttp.zip {
|
||||
import common_log
|
||||
request_body {
|
||||
max_size 2GB
|
||||
}
|
||||
reverse_proxy http://gitea:3000 {
|
||||
import stream_proxy
|
||||
}
|
||||
}
|
||||
|
||||
registry.juwan.xhttp.zip {
|
||||
import common_log
|
||||
request_body {
|
||||
max_size 2GB
|
||||
}
|
||||
reverse_proxy http://zot:5000 {
|
||||
import stream_proxy
|
||||
}
|
||||
}
|
||||
|
||||
s3.juwan.xhttp.zip {
|
||||
import common_log
|
||||
request_body {
|
||||
max_size 5GB
|
||||
}
|
||||
reverse_proxy http://garage:3900 {
|
||||
import stream_proxy
|
||||
}
|
||||
}
|
||||
|
||||
juwan.xhttp.zip {
|
||||
import common_log
|
||||
|
||||
handle /wt/* {
|
||||
reverse_proxy https://140.82.15.92:8443 {
|
||||
transport http {
|
||||
versions 3
|
||||
tls_insecure_skip_verify
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handle {
|
||||
reverse_proxy http://140.82.15.92:30080 {
|
||||
lb_policy round_robin
|
||||
health_uri /healthz
|
||||
health_interval 10s
|
||||
fail_duration 30s
|
||||
import stream_proxy
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
FROM caddy:2.11.2-builder-alpine AS builder
|
||||
|
||||
# 编译带 PR #7669(experimental WebTransport reverse-proxy passthrough)
|
||||
# 的 Caddy。来源是 tomholford 的 fork 分支 webtransport-reverse-proxy。
|
||||
RUN xcaddy build \
|
||||
--with github.com/caddyserver/caddy/v2=github.com/tomholford/caddy/v2@webtransport-reverse-proxy
|
||||
|
||||
FROM caddy:2.11.2-alpine
|
||||
|
||||
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
|
||||
@@ -0,0 +1,113 @@
|
||||
services:
|
||||
# ==================== 反代 ====================
|
||||
caddy:
|
||||
build:
|
||||
context: ./caddy
|
||||
image: juwan-center/caddy:wt
|
||||
container_name: juwan-caddy
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "443:443/udp"
|
||||
volumes:
|
||||
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- caddy-data:/data
|
||||
- caddy-config:/config
|
||||
depends_on:
|
||||
- gitea
|
||||
- zot
|
||||
- garage
|
||||
|
||||
# ==================== 容器仓库 ====================
|
||||
zot:
|
||||
image: ghcr.io/project-zot/zot:v2.1.16
|
||||
container_name: juwan-zot
|
||||
restart: unless-stopped
|
||||
command: ["serve", "/etc/zot/config.json"]
|
||||
volumes:
|
||||
- ./zot/config.json:/etc/zot/config.json:ro
|
||||
- ./zot/htpasswd:/etc/zot/htpasswd:ro
|
||||
- zot-data:/var/lib/registry
|
||||
expose:
|
||||
- "5000"
|
||||
|
||||
# ==================== S3 对象存储 ====================
|
||||
garage:
|
||||
image: dxflrs/garage:v2.3.0
|
||||
container_name: juwan-garage
|
||||
restart: unless-stopped
|
||||
command: ["/garage", "server"]
|
||||
volumes:
|
||||
- ./garage/garage.toml:/etc/garage.toml:ro
|
||||
- garage-meta:/var/lib/garage/meta
|
||||
- garage-data:/var/lib/garage/data
|
||||
expose:
|
||||
- "3900"
|
||||
- "3901"
|
||||
- "3902"
|
||||
- "3903"
|
||||
|
||||
# ==================== Git 服务 ====================
|
||||
gitea:
|
||||
image: docker.gitea.com/gitea:1.26.1
|
||||
container_name: juwan-gitea
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
USER_UID: "1000"
|
||||
USER_GID: "1000"
|
||||
GITEA__database__DB_TYPE: sqlite3
|
||||
GITEA__server__DOMAIN: ${GITEA_DOMAIN}
|
||||
GITEA__server__ROOT_URL: https://${GITEA_DOMAIN}/
|
||||
GITEA__server__PROTOCOL: http
|
||||
GITEA__server__HTTP_PORT: "3000"
|
||||
GITEA__server__DISABLE_SSH: "true"
|
||||
GITEA__service__DISABLE_REGISTRATION: "true"
|
||||
GITEA__security__INSTALL_LOCK: "true"
|
||||
GITEA__actions__ENABLED: "true"
|
||||
volumes:
|
||||
- gitea-data:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
expose:
|
||||
- "3000"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3000/api/healthz >/dev/null || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 30s
|
||||
|
||||
# ==================== CI/CD 执行器 ====================
|
||||
runner:
|
||||
image: gitea/act_runner:0.6.1
|
||||
container_name: juwan-runner
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
GITEA_INSTANCE_URL: http://gitea:3000
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN: ${RUNNER_TOKEN}
|
||||
GITEA_RUNNER_NAME: juwan-center
|
||||
GITEA_RUNNER_LABELS: ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest-slim
|
||||
CONFIG_FILE: /data/config.yaml
|
||||
volumes:
|
||||
- runner-data:/data
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
depends_on:
|
||||
gitea:
|
||||
condition: service_healthy
|
||||
|
||||
volumes:
|
||||
caddy-data:
|
||||
name: juwan-caddy-data
|
||||
caddy-config:
|
||||
name: juwan-caddy-config
|
||||
zot-data:
|
||||
name: juwan-zot-data
|
||||
garage-meta:
|
||||
name: juwan-garage-meta
|
||||
garage-data:
|
||||
name: juwan-garage-data
|
||||
gitea-data:
|
||||
name: juwan-gitea-data
|
||||
runner-data:
|
||||
name: juwan-runner-data
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
GARAGE="docker compose exec -T garage /garage"
|
||||
|
||||
NODE_ID="$($GARAGE node id -q | cut -d@ -f1 | tr -d '\r')"
|
||||
echo "node id: $NODE_ID"
|
||||
|
||||
$GARAGE layout assign -z dc1 -c 10G "$NODE_ID"
|
||||
$GARAGE layout apply --version 1
|
||||
|
||||
$GARAGE bucket create juwan-objectstory
|
||||
$GARAGE bucket create juwan-pg-backup
|
||||
|
||||
KEY_INFO="$($GARAGE key create juwan-app)"
|
||||
echo "$KEY_INFO"
|
||||
|
||||
ACCESS_KEY="$(echo "$KEY_INFO" | awk '/Key ID:/ {print $3}')"
|
||||
SECRET_KEY="$(echo "$KEY_INFO" | awk '/Secret key:/ {print $3}')"
|
||||
|
||||
$GARAGE bucket allow --read --write --owner juwan-objectstory --key juwan-app
|
||||
$GARAGE bucket allow --read --write --owner juwan-pg-backup --key juwan-app
|
||||
|
||||
cat <<EOF
|
||||
|
||||
S3_ENDPOINT=https://s3.juwan.xhttp.zip
|
||||
S3_REGION=garage
|
||||
S3_ACCESS_KEY=$ACCESS_KEY
|
||||
S3_SECRET_KEY=$SECRET_KEY
|
||||
S3_BUCKET_NAME=juwan-objectstory
|
||||
EOF
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user