diff --git a/backend/docker-compose.dev.yml b/backend/docker-compose.dev.yml index 7ad5ccb..4b6c786 100644 --- a/backend/docker-compose.dev.yml +++ b/backend/docker-compose.dev.yml @@ -7,6 +7,7 @@ networks: services: # Nginx 网关 nginx: + container_name: backend-nginx image: nginx:1.25-alpine ports: - "8080:80" @@ -19,14 +20,16 @@ services: # 网关服务 gateway: + container_name: backend-gateway build: - context: ./gateway - dockerfile: Dockerfile + context: . + dockerfile: ./gateway/Dockerfile ports: - "8000:8000" volumes: - - ./gateway:/app - command: air -c .air.toml + - ./gateway/cmd:/app/cmd + - ./gateway/internal:/app/internal + - ./shared:/shared depends_on: - user-svc - redis @@ -35,21 +38,26 @@ services: # 用户服务 user-svc: + container_name: backend-user-svc build: - context: ./services/user-svc - dockerfile: Dockerfile + context: . + dockerfile: ./services/user-svc/Dockerfile ports: - "9000:9000" volumes: - - ./services/user-svc:/app - command: air -c .air.toml + - ./services/user-svc/cmd:/app/cmd + - ./services/user-svc/internal:/app/internal + - ./services/user-svc/proto:/app/proto + - ./shared:/shared depends_on: - - postgres + postgres: + condition: service_healthy networks: - backend-network # 数据库 postgres: + container_name: backend-postgres image: postgres:18.3-alpine3.23 environment: POSTGRES_USER: admin @@ -62,9 +70,15 @@ services: - ./services/user-svc/migrations:/docker-entrypoint-initdb.d networks: - backend-network + healthcheck: + test: ["CMD-SHELL", "pg_isready -U admin -d backend"] + interval: 5s + timeout: 5s + retries: 5 # Redis redis: + container_name: backend-redis image: redis:8.6.2-alpine ports: - "6379:6379" diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml index a4ac789..dbd6f13 100644 --- a/backend/docker-compose.yml +++ b/backend/docker-compose.yml @@ -73,7 +73,7 @@ services: context: ./scripts/docker-proto-builder dockerfile: Dockerfile volumes: - - ./shared/proto:/proto + - .:/proto networks: - backend-network diff --git a/backend/gateway/Dockerfile b/backend/gateway/Dockerfile index 66bc02a..e741d64 100644 --- a/backend/gateway/Dockerfile +++ b/backend/gateway/Dockerfile @@ -1,16 +1,29 @@ -FROM golang:1.26.1-alpine3.23 as builder +FROM golang:1.25.8-alpine3.23 AS builder # 设置工作目录 WORKDIR /app -# 复制 go.mod 和 go.sum -COPY go.mod go.sum ./ +# 安装 git +RUN apk add --no-cache git -# 下载依赖 -RUN go mod download +# 设置 Go 环境变量 +ENV GOPROXY=https://goproxy.io,direct +ENV GOSUMDB=off + +# 复制共享包 +COPY shared/ /shared/ + +# 复制 go.mod +COPY gateway/go.mod ./ + +# 复制 go.sum(如果存在) +COPY gateway/go.sum* ./ # 复制源代码 -COPY . . +COPY gateway/ . + +# 生成 go.sum 并下载依赖 +RUN go mod tidy # 构建应用 RUN go build -o gateway ./cmd/main.go diff --git a/backend/gateway/cmd/main.go b/backend/gateway/cmd/main.go index d946cdf..a5d79ed 100644 --- a/backend/gateway/cmd/main.go +++ b/backend/gateway/cmd/main.go @@ -5,11 +5,12 @@ import ( "log" "net/http" - "backend/gateway/internal/config" - "backend/gateway/internal/router" - "backend/gateway/internal/service" - "backend/gateway/internal/ws" - "backend/shared/pkg/logger" + "gateway/internal/config" + "gateway/internal/router" + "gateway/internal/service" + "gateway/internal/ws" + + "shared/pkg/logger" ) func main() { diff --git a/backend/gateway/go.mod b/backend/gateway/go.mod index efe62c8..80c8803 100644 --- a/backend/gateway/go.mod +++ b/backend/gateway/go.mod @@ -1,10 +1,15 @@ -module backend/gateway +module gateway -go 1.26.1 +go 1.25.8 require ( github.com/gorilla/websocket v1.5.1 github.com/spf13/viper v1.19.0 google.golang.org/grpc v1.64.0 google.golang.org/protobuf v1.33.0 + shared v0.0.0 +) + +replace ( + shared => /shared ) \ No newline at end of file diff --git a/backend/gateway/internal/config/config.go b/backend/gateway/internal/config/config.go index 605e455..5a0cca1 100644 --- a/backend/gateway/internal/config/config.go +++ b/backend/gateway/internal/config/config.go @@ -36,10 +36,10 @@ func Load() (*Config, error) { viper.AddConfigPath("../../config") viper.SetDefault("server.port", 8000) - viper.SetDefault("redis.addr", "redis:6379") + viper.SetDefault("redis.addr", "backend-redis:6379") viper.SetDefault("redis.password", "") viper.SetDefault("redis.db", 0) - viper.SetDefault("services.userService.addr", "user-svc:9000") + viper.SetDefault("services.userService.addr", "backend-user-svc:9000") if err := viper.ReadInConfig(); err != nil { if _, ok := err.(viper.ConfigFileNotFoundError); !ok { diff --git a/backend/gateway/internal/router/router.go b/backend/gateway/internal/router/router.go index dc48fa3..159c83f 100644 --- a/backend/gateway/internal/router/router.go +++ b/backend/gateway/internal/router/router.go @@ -1,12 +1,11 @@ package router import ( - "encoding/json" "log" "net/http" - "backend/gateway/internal/service" - "backend/gateway/internal/ws" + "gateway/internal/service" + "gateway/internal/ws" "github.com/gorilla/websocket" ) @@ -54,11 +53,11 @@ func (r *Router) handleWebSocket(w http.ResponseWriter, req *http.Request) { } client := ws.NewClient(r.hub, conn) - r.hub.register <- client + r.hub.Register <- client // 启动客户端的读写协程 - go client.writePump() - go client.readPump() + go client.WritePump() + go client.ReadPump() } func (r *Router) handleHealth(w http.ResponseWriter, req *http.Request) { diff --git a/backend/gateway/internal/service/user_service.go b/backend/gateway/internal/service/user_service.go index 438f85a..b3f9a06 100644 --- a/backend/gateway/internal/service/user_service.go +++ b/backend/gateway/internal/service/user_service.go @@ -3,14 +3,14 @@ package service import ( "context" - "backend/gateway/internal/config" - "backend/shared/pkg/logger" + "gateway/internal/config" + "shared/pkg/logger" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" // 导入生成的 proto 代码 - userpb "backend/services/user-svc/proto" + userpb "shared/proto/user" ) type UserService struct { diff --git a/backend/gateway/internal/ws/client.go b/backend/gateway/internal/ws/client.go index 489bab6..c5d8de4 100644 --- a/backend/gateway/internal/ws/client.go +++ b/backend/gateway/internal/ws/client.go @@ -23,21 +23,21 @@ const ( ) type Client struct { - hub *Hub - conn *websocket.Conn - send chan *Message + Hub *Hub + Conn *websocket.Conn + Send chan *Message } func NewClient(hub *Hub, conn *websocket.Conn) *Client { return &Client{ - hub: hub, - conn: conn, - send: make(chan *Message, 256), + Hub: hub, + Conn: conn, + Send: make(chan *Message, 256), } } -// sendWs 发送 WebSocket 消息,自动生成 seq、cmd、timestamp -func (c *Client) sendWs(cmd string, data interface{}) error { +// SendWs 发送 WebSocket 消息,自动生成 seq、cmd、timestamp +func (c *Client) SendWs(cmd string, data interface{}) error { // 生成唯一请求ID seq := "req_" + time.Now().Format("20060102150405") + "_" + generateRandomString(8) @@ -57,8 +57,8 @@ func (c *Client) sendWs(cmd string, data interface{}) error { } // 写入 WebSocket 连接 - c.conn.SetWriteDeadline(time.Now().Add(writeWait)) - if err := c.conn.WriteMessage(websocket.TextMessage, msgBytes); err != nil { + c.Conn.SetWriteDeadline(time.Now().Add(writeWait)) + if err := c.Conn.WriteMessage(websocket.TextMessage, msgBytes); err != nil { log.Printf("error writing message: %v", err) return err } @@ -77,21 +77,21 @@ func generateRandomString(length int) string { return string(result) } -func (c *Client) readPump() { +func (c *Client) ReadPump() { defer func() { - c.hub.unregister <- c - c.conn.Close() + c.Hub.Unregister <- c + c.Conn.Close() }() - c.conn.SetReadLimit(maxMessageSize) - c.conn.SetReadDeadline(time.Now().Add(pongWait)) - c.conn.SetPongHandler(func(string) error { - c.conn.SetReadDeadline(time.Now().Add(pongWait)) + c.Conn.SetReadLimit(maxMessageSize) + c.Conn.SetReadDeadline(time.Now().Add(pongWait)) + c.Conn.SetPongHandler(func(string) error { + c.Conn.SetReadDeadline(time.Now().Add(pongWait)) return nil }) for { - _, message, err := c.conn.ReadMessage() + _, message, err := c.Conn.ReadMessage() if err != nil { if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) { log.Printf("error: %v", err) @@ -107,18 +107,19 @@ func (c *Client) readPump() { } // 处理消息 - c.handleMessage(msgMap) + c.HandleMessage(msgMap) } } -func (c *Client) handleMessage(msgMap map[string]interface{}) { +func (c *Client) HandleMessage(msgMap map[string]interface{}) { // 检查是否是 ping 消息(保持向后兼容) - if msgType, ok := msgMap["type"].(string); ok { + if msgTypeStr, ok := msgMap["type"].(string); ok { + msgType := MessageType(msgTypeStr) switch msgType { case MessageTypePing: // 回复 pong pongMsg := &Message{Type: MessageTypePong} - c.send <- pongMsg + c.Send <- pongMsg return case MessageTypeText: // 广播文本消息 @@ -127,7 +128,7 @@ func (c *Client) handleMessage(msgMap map[string]interface{}) { Content: msgMap["content"].(string), Data: msgMap["data"], } - c.hub.broadcast <- msg + c.Hub.Broadcast <- msg return case MessageTypeCommand: // 处理命令(保持向后兼容) @@ -135,7 +136,7 @@ func (c *Client) handleMessage(msgMap map[string]interface{}) { Type: MessageTypeCommand, Data: msgMap["data"], } - c.handleCommand(msg) + c.HandleCommand(msg) return } } @@ -147,28 +148,28 @@ func (c *Client) handleMessage(msgMap map[string]interface{}) { seq := msgMap["seq"].(string) // 处理命令 - c.handleNewCommand(seq, cmd, data) + c.HandleNewCommand(seq, cmd, data) } } -func (c *Client) writePump() { +func (c *Client) WritePump() { ticker := time.NewTicker(pingPeriod) defer func() { ticker.Stop() - c.conn.Close() + c.Conn.Close() }() for { select { - case message, ok := <-c.send: - c.conn.SetWriteDeadline(time.Now().Add(writeWait)) + case message, ok := <-c.Send: + c.Conn.SetWriteDeadline(time.Now().Add(writeWait)) if !ok { // Hub 关闭了通道 - c.conn.WriteMessage(websocket.CloseMessage, []byte{}) + c.Conn.WriteMessage(websocket.CloseMessage, []byte{}) return } - w, err := c.conn.NextWriter(websocket.TextMessage) + w, err := c.Conn.NextWriter(websocket.TextMessage) if err != nil { return } @@ -186,20 +187,20 @@ func (c *Client) writePump() { } case <-ticker.C: - c.conn.SetWriteDeadline(time.Now().Add(writeWait)) + c.Conn.SetWriteDeadline(time.Now().Add(writeWait)) pingMsg := &Message{Type: MessageTypePing} pingBytes, err := json.Marshal(pingMsg) if err != nil { return } - if err := c.conn.WriteMessage(websocket.TextMessage, pingBytes); err != nil { + if err := c.Conn.WriteMessage(websocket.TextMessage, pingBytes); err != nil { return } } } } -func (c *Client) handleCommand(msg *Message) { +func (c *Client) HandleCommand(msg *Message) { // 处理命令逻辑 // 这里可以根据命令类型执行不同的操作 log.Printf("Received command: %v", msg.Data) @@ -217,22 +218,22 @@ func (c *Client) handleCommand(msg *Message) { Type: MessageTypeError, Content: "Invalid register command: missing account or password", } - c.send <- errorResponse + c.Send <- errorResponse return } // 调用用户服务注册 - if c.hub.userService != nil { + if c.Hub.UserService != nil { // 异步调用用户服务注册 go func() { - resp, err := c.hub.userService.Register(nil, account, password) + resp, err := c.Hub.UserService.Register(nil, account, password) if err != nil { // 回复错误信息 errorResponse := &Message{ Type: MessageTypeError, Content: "Register failed: " + err.Error(), } - c.send <- errorResponse + c.Send <- errorResponse return } @@ -247,7 +248,7 @@ func (c *Client) handleCommand(msg *Message) { "code": resp.Response.Code, }, } - c.send <- successResponse + c.Send <- successResponse }() } else { // 回复错误信息 @@ -255,7 +256,7 @@ func (c *Client) handleCommand(msg *Message) { Type: MessageTypeError, Content: "User service not available", } - c.send <- errorResponse + c.Send <- errorResponse } return } @@ -268,10 +269,10 @@ func (c *Client) handleCommand(msg *Message) { Data: msg.Data, } - c.send <- response + c.Send <- response } -func (c *Client) handleNewCommand(seq string, cmd string, data interface{}) { +func (c *Client) HandleNewCommand(seq string, cmd string, data interface{}) { // 处理新的命令结构 log.Printf("Received new command: %s, seq: %s, data: %v", cmd, seq, data) @@ -285,7 +286,7 @@ func (c *Client) handleNewCommand(seq string, cmd string, data interface{}) { if !accountOk || !passwordOk { // 回复错误信息 - c.sendWs(cmd, map[string]interface{}{ + c.SendWs(cmd, map[string]interface{}{ "type": "error", "content": "Invalid register command: missing account or password", }) @@ -293,13 +294,13 @@ func (c *Client) handleNewCommand(seq string, cmd string, data interface{}) { } // 调用用户服务注册 - if c.hub.userService != nil { + if c.Hub.UserService != nil { // 异步调用用户服务注册 go func() { - resp, err := c.hub.userService.Register(nil, account, password) + resp, err := c.Hub.UserService.Register(nil, account, password) if err != nil { // 回复错误信息 - c.sendWs(cmd, map[string]interface{}{ + c.SendWs(cmd, map[string]interface{}{ "type": "error", "content": "Register failed: " + err.Error(), }) @@ -307,7 +308,7 @@ func (c *Client) handleNewCommand(seq string, cmd string, data interface{}) { } // 回复成功信息 - c.sendWs(cmd, map[string]interface{}{ + c.SendWs(cmd, map[string]interface{}{ "type": "text", "content": "Register successful", "data": map[string]interface{}{ @@ -320,7 +321,7 @@ func (c *Client) handleNewCommand(seq string, cmd string, data interface{}) { }() } else { // 回复错误信息 - c.sendWs(cmd, map[string]interface{}{ + c.SendWs(cmd, map[string]interface{}{ "type": "error", "content": "User service not available", }) @@ -329,7 +330,7 @@ func (c *Client) handleNewCommand(seq string, cmd string, data interface{}) { return default: // 其他命令处理 - c.sendWs(cmd, map[string]interface{}{ + c.SendWs(cmd, map[string]interface{}{ "type": "text", "content": "Command executed successfully", "data": data, diff --git a/backend/gateway/internal/ws/hub.go b/backend/gateway/internal/ws/hub.go index ba0ce22..8a70f04 100644 --- a/backend/gateway/internal/ws/hub.go +++ b/backend/gateway/internal/ws/hub.go @@ -3,57 +3,57 @@ package ws import ( "log" - "backend/gateway/internal/service" + "gateway/internal/service" ) type Hub struct { // 注册的客户端 - clients map[*Client]bool + Clients map[*Client]bool // 从客户端接收的消息 - broadcast chan *Message + Broadcast chan *Message // 注册请求 - register chan *Client + Register chan *Client // 注销请求 - unregister chan *Client + Unregister chan *Client // 用户服务 - userService *service.UserService + UserService *service.UserService } func NewHub(userService *service.UserService) *Hub { return &Hub{ - broadcast: make(chan *Message), - register: make(chan *Client), - unregister: make(chan *Client), - clients: make(map[*Client]bool), - userService: userService, + Broadcast: make(chan *Message), + Register: make(chan *Client), + Unregister: make(chan *Client), + Clients: make(map[*Client]bool), + UserService: userService, } } func (h *Hub) Run() { for { select { - case client := <-h.register: - h.clients[client] = true - log.Printf("Client connected. Total clients: %d", len(h.clients)) + case client := <-h.Register: + h.Clients[client] = true + log.Printf("Client connected. Total clients: %d", len(h.Clients)) - case client := <-h.unregister: - if _, ok := h.clients[client]; ok { - delete(h.clients, client) - close(client.send) - log.Printf("Client disconnected. Total clients: %d", len(h.clients)) + case client := <-h.Unregister: + if _, ok := h.Clients[client]; ok { + delete(h.Clients, client) + close(client.Send) + log.Printf("Client disconnected. Total clients: %d", len(h.Clients)) } - case message := <-h.broadcast: - for client := range h.clients { + case message := <-h.Broadcast: + for client := range h.Clients { select { - case client.send <- message: + case client.Send <- message: default: - close(client.send) - delete(h.clients, client) + close(client.Send) + delete(h.Clients, client) } } } diff --git a/backend/scripts/docker-proto-builder/Dockerfile b/backend/scripts/docker-proto-builder/Dockerfile index 3396a71..72b3f3c 100644 --- a/backend/scripts/docker-proto-builder/Dockerfile +++ b/backend/scripts/docker-proto-builder/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.26.1-alpine3.23 +FROM golang:1.25.8-alpine3.23 # 安装 protoc 和相关工具 RUN apk add --no-cache protobuf-dev @@ -11,4 +11,4 @@ RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest WORKDIR /proto # 生成 proto 文件的命令 -CMD protoc --go_out=. --go-grpc_out=. common/*.proto \ No newline at end of file +CMD protoc --go_out=. --go-grpc_out=. shared/proto/common/*.proto shared/proto/user/*.proto \ No newline at end of file diff --git a/backend/services/user-svc/Dockerfile b/backend/services/user-svc/Dockerfile index e570312..a1e8450 100644 --- a/backend/services/user-svc/Dockerfile +++ b/backend/services/user-svc/Dockerfile @@ -1,16 +1,29 @@ -FROM golang:1.26.1-alpine3.23 as builder +FROM golang:1.25.8-alpine3.23 AS builder # 设置工作目录 WORKDIR /app -# 复制 go.mod 和 go.sum -COPY go.mod go.sum ./ +# 安装 git +RUN apk add --no-cache git -# 下载依赖 -RUN go mod download +# 设置 Go 环境变量 +ENV GOPROXY=https://goproxy.io,direct +ENV GOSUMDB=off + +# 复制共享包 +COPY shared/ /shared/ + +# 复制 go.mod +COPY services/user-svc/go.mod ./ + +# 复制 go.sum(如果存在) +COPY services/user-svc/go.sum* ./ # 复制源代码 -COPY . . +COPY services/user-svc/ . + +# 生成 go.sum 并下载依赖 +RUN go mod tidy # 构建应用 RUN go build -o user-svc ./cmd/main.go diff --git a/backend/services/user-svc/cmd/main.go b/backend/services/user-svc/cmd/main.go index 17a5a32..1815fef 100644 --- a/backend/services/user-svc/cmd/main.go +++ b/backend/services/user-svc/cmd/main.go @@ -4,12 +4,13 @@ import ( "fmt" "log" - "backend/services/user-svc/internal/config" - "backend/services/user-svc/internal/grpcserver" - "backend/services/user-svc/internal/repository" - "backend/services/user-svc/internal/service" - "backend/shared/pkg/database" - "backend/shared/pkg/logger" + "user-svc/internal/config" + "user-svc/internal/grpcserver" + "user-svc/internal/repository" + "user-svc/internal/service" + + "shared/pkg/database" + "shared/pkg/logger" ) func main() { diff --git a/backend/services/user-svc/go.mod b/backend/services/user-svc/go.mod index 90f4ecf..80b7d82 100644 --- a/backend/services/user-svc/go.mod +++ b/backend/services/user-svc/go.mod @@ -1,6 +1,6 @@ -module backend/services/user-svc +module user-svc -go 1.26.1 +go 1.25.8 require ( github.com/google/uuid v1.6.0 @@ -8,4 +8,9 @@ require ( golang.org/x/crypto v0.20.0 google.golang.org/grpc v1.64.0 google.golang.org/protobuf v1.33.0 + shared v0.0.0 +) + +replace ( + shared => /shared ) diff --git a/backend/services/user-svc/internal/config/config.go b/backend/services/user-svc/internal/config/config.go index aab05fd..e3d2c07 100644 --- a/backend/services/user-svc/internal/config/config.go +++ b/backend/services/user-svc/internal/config/config.go @@ -30,7 +30,7 @@ func Load() (*Config, error) { viper.AddConfigPath("../../config") viper.SetDefault("server.port", 9000) - viper.SetDefault("database.host", "postgres") + viper.SetDefault("database.host", "backend-postgres") viper.SetDefault("database.port", 5432) viper.SetDefault("database.user", "admin") viper.SetDefault("database.password", "password") diff --git a/backend/services/user-svc/internal/grpcserver/server.go b/backend/services/user-svc/internal/grpcserver/server.go index 6eb90ce..76d4e78 100644 --- a/backend/services/user-svc/internal/grpcserver/server.go +++ b/backend/services/user-svc/internal/grpcserver/server.go @@ -5,17 +5,18 @@ import ( "fmt" "net" - "backend/services/user-svc/internal/domain" - "backend/services/user-svc/internal/service" - "backend/shared/pkg/errors" - "backend/shared/pkg/logger" + "user-svc/internal/domain" + "user-svc/internal/service" + "shared/pkg/errors" + "shared/pkg/logger" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" // 导入生成的 proto 代码 - userpb "backend/services/user-svc/proto" + userpb "shared/proto/user" + common "shared/proto/common" ) type UserServer struct { @@ -41,36 +42,36 @@ func (s *UserServer) Register(ctx context.Context, req *userpb.RegisterRequest) logger.Error("Register failed: %v", err) // 转换错误类型 - switch { - case errors.IsConflict(err): - return &userpb.RegisterResponse{ - Response: &userpb.Response{ - Code: 409, - Message: "账号已存在", - }, - }, status.Errorf(codes.AlreadyExists, "账号已存在") - case errors.IsInvalidInput(err): - return &userpb.RegisterResponse{ - Response: &userpb.Response{ - Code: 400, - Message: "无效的输入参数", - }, - }, status.Errorf(codes.InvalidArgument, "无效的输入参数") - default: - return &userpb.RegisterResponse{ - Response: &userpb.Response{ - Code: 500, - Message: "内部服务器错误", - }, - }, status.Errorf(codes.Internal, "内部服务器错误") - } + switch { + case errors.IsConflict(err): + return &userpb.RegisterResponse{ + Response: &common.Response{ + Code: 409, + Message: "账号已存在", + }, + }, status.Errorf(codes.AlreadyExists, "账号已存在") + case errors.IsInvalidInput(err): + return &userpb.RegisterResponse{ + Response: &common.Response{ + Code: 400, + Message: "无效的输入参数", + }, + }, status.Errorf(codes.InvalidArgument, "无效的输入参数") + default: + return &userpb.RegisterResponse{ + Response: &common.Response{ + Code: 500, + Message: "内部服务器错误", + }, + }, status.Errorf(codes.Internal, "内部服务器错误") + } } // 构造响应 return &userpb.RegisterResponse{ UserId: resp.UserID.String(), Account: resp.Account, - Response: &userpb.Response{ + Response: &common.Response{ Code: 200, Message: "注册成功", }, @@ -88,21 +89,21 @@ func (s *UserServer) GetUserByAccount(ctx context.Context, req *userpb.GetUserBy switch { case errors.IsNotFound(err): return &userpb.GetUserByAccountResponse{ - Response: &userpb.Response{ + Response: &common.Response{ Code: 404, Message: "用户不存在", }, }, status.Errorf(codes.NotFound, "用户不存在") case errors.IsInvalidInput(err): return &userpb.GetUserByAccountResponse{ - Response: &userpb.Response{ + Response: &common.Response{ Code: 400, Message: "无效的输入参数", }, }, status.Errorf(codes.InvalidArgument, "无效的输入参数") default: return &userpb.GetUserByAccountResponse{ - Response: &userpb.Response{ + Response: &common.Response{ Code: 500, Message: "内部服务器错误", }, @@ -114,7 +115,7 @@ func (s *UserServer) GetUserByAccount(ctx context.Context, req *userpb.GetUserBy return &userpb.GetUserByAccountResponse{ UserId: user.ID.String(), Account: account.Account, - Response: &userpb.Response{ + Response: &common.Response{ Code: 200, Message: "获取成功", }, diff --git a/backend/services/user-svc/internal/repository/repo.go b/backend/services/user-svc/internal/repository/repo.go index 6f938e1..fc8bf18 100644 --- a/backend/services/user-svc/internal/repository/repo.go +++ b/backend/services/user-svc/internal/repository/repo.go @@ -2,10 +2,9 @@ package repository import ( "database/sql" - "time" - "backend/services/user-svc/internal/domain" - "backend/shared/pkg/errors" + "user-svc/internal/domain" + "shared/pkg/errors" "github.com/google/uuid" "golang.org/x/crypto/bcrypt" @@ -41,7 +40,11 @@ func (r *UserRepository) Register(req *domain.RegisterRequest) (*domain.Register } // 创建用户 - userID := uuid.NewV7() + userID, err := uuid.NewV7() + if err != nil { + tx.Rollback() + return nil, errors.WrapError(err, "failed to generate user ID") + } userQuery := "INSERT INTO user_main (id, deleted) VALUES ($1, $2)" if _, err := tx.Exec(userQuery, userID, false); err != nil { @@ -50,7 +53,11 @@ func (r *UserRepository) Register(req *domain.RegisterRequest) (*domain.Register } // 创建登录账号 - accountID := uuid.NewV7() + accountID, err := uuid.NewV7() + if err != nil { + tx.Rollback() + return nil, errors.WrapError(err, "failed to generate account ID") + } accountQuery := "INSERT INTO user_login_account (id, user_id, account, deleted) VALUES ($1, $2, $3, $4)" if _, err := tx.Exec(accountQuery, accountID, userID, req.Account, false); err != nil { tx.Rollback() @@ -65,7 +72,11 @@ func (r *UserRepository) Register(req *domain.RegisterRequest) (*domain.Register } // 创建密码记录 - passwordID := uuid.NewV7() + passwordID, err := uuid.NewV7() + if err != nil { + tx.Rollback() + return nil, errors.WrapError(err, "failed to generate password ID") + } passwordQuery := "INSERT INTO user_login_password (id, user_id, password, deleted) VALUES ($1, $2, $3, $4)" if _, err := tx.Exec(passwordQuery, passwordID, userID, string(hashedPassword), false); err != nil { tx.Rollback() diff --git a/backend/services/user-svc/internal/service/service.go b/backend/services/user-svc/internal/service/service.go index 6b91cc9..2d16eef 100644 --- a/backend/services/user-svc/internal/service/service.go +++ b/backend/services/user-svc/internal/service/service.go @@ -1,9 +1,10 @@ package service import ( - "backend/services/user-svc/internal/domain" - "backend/services/user-svc/internal/repository" - "backend/shared/pkg/errors" + "user-svc/internal/domain" + "user-svc/internal/repository" + + "shared/pkg/errors" ) type UserService struct { diff --git a/backend/services/user-svc/proto/go.mod b/backend/services/user-svc/proto/go.mod new file mode 100644 index 0000000..27f283e --- /dev/null +++ b/backend/services/user-svc/proto/go.mod @@ -0,0 +1,11 @@ +module user-svc/proto + +go 1.25.8 + +require ( + google.golang.org/grpc v1.64.0 + google.golang.org/protobuf v1.33.0 + shared v0.0.0 +) + +replace shared => /shared diff --git a/backend/services/user-svc/proto/user.pb.go b/backend/services/user-svc/proto/user.pb.go new file mode 100644 index 0000000..814e46a --- /dev/null +++ b/backend/services/user-svc/proto/user.pb.go @@ -0,0 +1,323 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v6.31.1 +// source: services/user-svc/proto/user.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + common "shared/proto/common" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// 注册请求 +type RegisterRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Account string `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RegisterRequest) Reset() { + *x = RegisterRequest{} + mi := &file_services_user_svc_proto_user_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegisterRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterRequest) ProtoMessage() {} + +func (x *RegisterRequest) ProtoReflect() protoreflect.Message { + mi := &file_services_user_svc_proto_user_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterRequest.ProtoReflect.Descriptor instead. +func (*RegisterRequest) Descriptor() ([]byte, []int) { + return file_services_user_svc_proto_user_proto_rawDescGZIP(), []int{0} +} + +func (x *RegisterRequest) GetAccount() string { + if x != nil { + return x.Account + } + return "" +} + +func (x *RegisterRequest) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +// 注册响应 +type RegisterResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + Account string `protobuf:"bytes,2,opt,name=account,proto3" json:"account,omitempty"` + Response *common.Response `protobuf:"bytes,3,opt,name=response,proto3" json:"response,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RegisterResponse) Reset() { + *x = RegisterResponse{} + mi := &file_services_user_svc_proto_user_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegisterResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterResponse) ProtoMessage() {} + +func (x *RegisterResponse) ProtoReflect() protoreflect.Message { + mi := &file_services_user_svc_proto_user_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterResponse.ProtoReflect.Descriptor instead. +func (*RegisterResponse) Descriptor() ([]byte, []int) { + return file_services_user_svc_proto_user_proto_rawDescGZIP(), []int{1} +} + +func (x *RegisterResponse) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *RegisterResponse) GetAccount() string { + if x != nil { + return x.Account + } + return "" +} + +func (x *RegisterResponse) GetResponse() *common.Response { + if x != nil { + return x.Response + } + return nil +} + +// 获取用户信息请求 +type GetUserByAccountRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Account string `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetUserByAccountRequest) Reset() { + *x = GetUserByAccountRequest{} + mi := &file_services_user_svc_proto_user_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetUserByAccountRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserByAccountRequest) ProtoMessage() {} + +func (x *GetUserByAccountRequest) ProtoReflect() protoreflect.Message { + mi := &file_services_user_svc_proto_user_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetUserByAccountRequest.ProtoReflect.Descriptor instead. +func (*GetUserByAccountRequest) Descriptor() ([]byte, []int) { + return file_services_user_svc_proto_user_proto_rawDescGZIP(), []int{2} +} + +func (x *GetUserByAccountRequest) GetAccount() string { + if x != nil { + return x.Account + } + return "" +} + +// 获取用户信息响应 +type GetUserByAccountResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + Account string `protobuf:"bytes,2,opt,name=account,proto3" json:"account,omitempty"` + Response *common.Response `protobuf:"bytes,3,opt,name=response,proto3" json:"response,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetUserByAccountResponse) Reset() { + *x = GetUserByAccountResponse{} + mi := &file_services_user_svc_proto_user_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetUserByAccountResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserByAccountResponse) ProtoMessage() {} + +func (x *GetUserByAccountResponse) ProtoReflect() protoreflect.Message { + mi := &file_services_user_svc_proto_user_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetUserByAccountResponse.ProtoReflect.Descriptor instead. +func (*GetUserByAccountResponse) Descriptor() ([]byte, []int) { + return file_services_user_svc_proto_user_proto_rawDescGZIP(), []int{3} +} + +func (x *GetUserByAccountResponse) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *GetUserByAccountResponse) GetAccount() string { + if x != nil { + return x.Account + } + return "" +} + +func (x *GetUserByAccountResponse) GetResponse() *common.Response { + if x != nil { + return x.Response + } + return nil +} + +var File_services_user_svc_proto_user_proto protoreflect.FileDescriptor + +const file_services_user_svc_proto_user_proto_rawDesc = "" + + "\n" + + "\"services/user-svc/proto/user.proto\x12\x04user\x1a shared/proto/common/common.proto\"G\n" + + "\x0fRegisterRequest\x12\x18\n" + + "\aaccount\x18\x01 \x01(\tR\aaccount\x12\x1a\n" + + "\bpassword\x18\x02 \x01(\tR\bpassword\"s\n" + + "\x10RegisterResponse\x12\x17\n" + + "\auser_id\x18\x01 \x01(\tR\x06userId\x12\x18\n" + + "\aaccount\x18\x02 \x01(\tR\aaccount\x12,\n" + + "\bresponse\x18\x03 \x01(\v2\x10.common.ResponseR\bresponse\"3\n" + + "\x17GetUserByAccountRequest\x12\x18\n" + + "\aaccount\x18\x01 \x01(\tR\aaccount\"{\n" + + "\x18GetUserByAccountResponse\x12\x17\n" + + "\auser_id\x18\x01 \x01(\tR\x06userId\x12\x18\n" + + "\aaccount\x18\x02 \x01(\tR\aaccount\x12,\n" + + "\bresponse\x18\x03 \x01(\v2\x10.common.ResponseR\bresponse2\x9b\x01\n" + + "\vUserService\x129\n" + + "\bRegister\x12\x15.user.RegisterRequest\x1a\x16.user.RegisterResponse\x12Q\n" + + "\x10GetUserByAccount\x12\x1d.user.GetUserByAccountRequest\x1a\x1e.user.GetUserByAccountResponseB\x10Z\x0euser-svc/protob\x06proto3" + +var ( + file_services_user_svc_proto_user_proto_rawDescOnce sync.Once + file_services_user_svc_proto_user_proto_rawDescData []byte +) + +func file_services_user_svc_proto_user_proto_rawDescGZIP() []byte { + file_services_user_svc_proto_user_proto_rawDescOnce.Do(func() { + file_services_user_svc_proto_user_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_services_user_svc_proto_user_proto_rawDesc), len(file_services_user_svc_proto_user_proto_rawDesc))) + }) + return file_services_user_svc_proto_user_proto_rawDescData +} + +var file_services_user_svc_proto_user_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_services_user_svc_proto_user_proto_goTypes = []any{ + (*RegisterRequest)(nil), // 0: user.RegisterRequest + (*RegisterResponse)(nil), // 1: user.RegisterResponse + (*GetUserByAccountRequest)(nil), // 2: user.GetUserByAccountRequest + (*GetUserByAccountResponse)(nil), // 3: user.GetUserByAccountResponse + (*common.Response)(nil), // 4: common.Response +} +var file_services_user_svc_proto_user_proto_depIdxs = []int32{ + 4, // 0: user.RegisterResponse.response:type_name -> common.Response + 4, // 1: user.GetUserByAccountResponse.response:type_name -> common.Response + 0, // 2: user.UserService.Register:input_type -> user.RegisterRequest + 2, // 3: user.UserService.GetUserByAccount:input_type -> user.GetUserByAccountRequest + 1, // 4: user.UserService.Register:output_type -> user.RegisterResponse + 3, // 5: user.UserService.GetUserByAccount:output_type -> user.GetUserByAccountResponse + 4, // [4:6] is the sub-list for method output_type + 2, // [2:4] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_services_user_svc_proto_user_proto_init() } +func file_services_user_svc_proto_user_proto_init() { + if File_services_user_svc_proto_user_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_services_user_svc_proto_user_proto_rawDesc), len(file_services_user_svc_proto_user_proto_rawDesc)), + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_services_user_svc_proto_user_proto_goTypes, + DependencyIndexes: file_services_user_svc_proto_user_proto_depIdxs, + MessageInfos: file_services_user_svc_proto_user_proto_msgTypes, + }.Build() + File_services_user_svc_proto_user_proto = out.File + file_services_user_svc_proto_user_proto_goTypes = nil + file_services_user_svc_proto_user_proto_depIdxs = nil +} diff --git a/backend/services/user-svc/proto/user_grpc.pb.go b/backend/services/user-svc/proto/user_grpc.pb.go new file mode 100644 index 0000000..be2b76d --- /dev/null +++ b/backend/services/user-svc/proto/user_grpc.pb.go @@ -0,0 +1,167 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.6.1 +// - protoc v6.31.1 +// source: services/user-svc/proto/user.proto + +package proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + UserService_Register_FullMethodName = "/user.UserService/Register" + UserService_GetUserByAccount_FullMethodName = "/user.UserService/GetUserByAccount" +) + +// UserServiceClient is the client API for UserService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// 用户服务 +type UserServiceClient interface { + // 注册用户 + Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterResponse, error) + // 获取用户信息 + GetUserByAccount(ctx context.Context, in *GetUserByAccountRequest, opts ...grpc.CallOption) (*GetUserByAccountResponse, error) +} + +type userServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewUserServiceClient(cc grpc.ClientConnInterface) UserServiceClient { + return &userServiceClient{cc} +} + +func (c *userServiceClient) Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RegisterResponse) + err := c.cc.Invoke(ctx, UserService_Register_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetUserByAccount(ctx context.Context, in *GetUserByAccountRequest, opts ...grpc.CallOption) (*GetUserByAccountResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetUserByAccountResponse) + err := c.cc.Invoke(ctx, UserService_GetUserByAccount_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// UserServiceServer is the server API for UserService service. +// All implementations must embed UnimplementedUserServiceServer +// for forward compatibility. +// +// 用户服务 +type UserServiceServer interface { + // 注册用户 + Register(context.Context, *RegisterRequest) (*RegisterResponse, error) + // 获取用户信息 + GetUserByAccount(context.Context, *GetUserByAccountRequest) (*GetUserByAccountResponse, error) + mustEmbedUnimplementedUserServiceServer() +} + +// UnimplementedUserServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedUserServiceServer struct{} + +func (UnimplementedUserServiceServer) Register(context.Context, *RegisterRequest) (*RegisterResponse, error) { + return nil, status.Error(codes.Unimplemented, "method Register not implemented") +} +func (UnimplementedUserServiceServer) GetUserByAccount(context.Context, *GetUserByAccountRequest) (*GetUserByAccountResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GetUserByAccount not implemented") +} +func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {} +func (UnimplementedUserServiceServer) testEmbeddedByValue() {} + +// UnsafeUserServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to UserServiceServer will +// result in compilation errors. +type UnsafeUserServiceServer interface { + mustEmbedUnimplementedUserServiceServer() +} + +func RegisterUserServiceServer(s grpc.ServiceRegistrar, srv UserServiceServer) { + // If the following call panics, it indicates UnimplementedUserServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&UserService_ServiceDesc, srv) +} + +func _UserService_Register_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegisterRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).Register(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_Register_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).Register(ctx, req.(*RegisterRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetUserByAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetUserByAccountRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetUserByAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_GetUserByAccount_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetUserByAccount(ctx, req.(*GetUserByAccountRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// UserService_ServiceDesc is the grpc.ServiceDesc for UserService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var UserService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "user.UserService", + HandlerType: (*UserServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Register", + Handler: _UserService_Register_Handler, + }, + { + MethodName: "GetUserByAccount", + Handler: _UserService_GetUserByAccount_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "services/user-svc/proto/user.proto", +} diff --git a/backend/shared/go.mod b/backend/shared/go.mod new file mode 100644 index 0000000..9890c61 --- /dev/null +++ b/backend/shared/go.mod @@ -0,0 +1,8 @@ +module shared + +go 1.25.8 + +require ( + github.com/go-redis/redis/v8 v8.11.5 + github.com/lib/pq v1.10.9 +) diff --git a/backend/shared/pkg/database/postgres.go b/backend/shared/pkg/database/postgres.go index 11f75f4..7f54ff0 100644 --- a/backend/shared/pkg/database/postgres.go +++ b/backend/shared/pkg/database/postgres.go @@ -5,7 +5,7 @@ import ( "fmt" "time" - "backend/shared/pkg/logger" + "shared/pkg/logger" _ "github.com/lib/pq" ) diff --git a/backend/shared/proto/common/common.pb.go b/backend/shared/proto/common/common.pb.go new file mode 100644 index 0000000..97a1a71 --- /dev/null +++ b/backend/shared/proto/common/common.pb.go @@ -0,0 +1,572 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v6.31.1 +// source: shared/proto/common/common.proto + +package common + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// 通用响应结构 +type Response struct { + state protoimpl.MessageState `protogen:"open.v1"` + Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Response) Reset() { + *x = Response{} + mi := &file_shared_proto_common_common_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Response) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Response) ProtoMessage() {} + +func (x *Response) ProtoReflect() protoreflect.Message { + mi := &file_shared_proto_common_common_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Response.ProtoReflect.Descriptor instead. +func (*Response) Descriptor() ([]byte, []int) { + return file_shared_proto_common_common_proto_rawDescGZIP(), []int{0} +} + +func (x *Response) GetCode() int32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *Response) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *Response) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +// 分页请求 +type PaginationRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` + PageSize int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PaginationRequest) Reset() { + *x = PaginationRequest{} + mi := &file_shared_proto_common_common_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PaginationRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PaginationRequest) ProtoMessage() {} + +func (x *PaginationRequest) ProtoReflect() protoreflect.Message { + mi := &file_shared_proto_common_common_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PaginationRequest.ProtoReflect.Descriptor instead. +func (*PaginationRequest) Descriptor() ([]byte, []int) { + return file_shared_proto_common_common_proto_rawDescGZIP(), []int{1} +} + +func (x *PaginationRequest) GetPage() int32 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *PaginationRequest) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +// 分页响应 +type PaginationResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Total int32 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` + Page int32 `protobuf:"varint,2,opt,name=page,proto3" json:"page,omitempty"` + PageSize int32 `protobuf:"varint,3,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + TotalPages int32 `protobuf:"varint,4,opt,name=total_pages,json=totalPages,proto3" json:"total_pages,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PaginationResponse) Reset() { + *x = PaginationResponse{} + mi := &file_shared_proto_common_common_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PaginationResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PaginationResponse) ProtoMessage() {} + +func (x *PaginationResponse) ProtoReflect() protoreflect.Message { + mi := &file_shared_proto_common_common_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PaginationResponse.ProtoReflect.Descriptor instead. +func (*PaginationResponse) Descriptor() ([]byte, []int) { + return file_shared_proto_common_common_proto_rawDescGZIP(), []int{2} +} + +func (x *PaginationResponse) GetTotal() int32 { + if x != nil { + return x.Total + } + return 0 +} + +func (x *PaginationResponse) GetPage() int32 { + if x != nil { + return x.Page + } + return 0 +} + +func (x *PaginationResponse) GetPageSize() int32 { + if x != nil { + return x.PageSize + } + return 0 +} + +func (x *PaginationResponse) GetTotalPages() int32 { + if x != nil { + return x.TotalPages + } + return 0 +} + +// 错误信息 +type Error struct { + state protoimpl.MessageState `protogen:"open.v1"` + Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Details string `protobuf:"bytes,3,opt,name=details,proto3" json:"details,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Error) Reset() { + *x = Error{} + mi := &file_shared_proto_common_common_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Error) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Error) ProtoMessage() {} + +func (x *Error) ProtoReflect() protoreflect.Message { + mi := &file_shared_proto_common_common_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Error.ProtoReflect.Descriptor instead. +func (*Error) Descriptor() ([]byte, []int) { + return file_shared_proto_common_common_proto_rawDescGZIP(), []int{3} +} + +func (x *Error) GetCode() int32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *Error) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *Error) GetDetails() string { + if x != nil { + return x.Details + } + return "" +} + +// 空请求 +type EmptyRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EmptyRequest) Reset() { + *x = EmptyRequest{} + mi := &file_shared_proto_common_common_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EmptyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EmptyRequest) ProtoMessage() {} + +func (x *EmptyRequest) ProtoReflect() protoreflect.Message { + mi := &file_shared_proto_common_common_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EmptyRequest.ProtoReflect.Descriptor instead. +func (*EmptyRequest) Descriptor() ([]byte, []int) { + return file_shared_proto_common_common_proto_rawDescGZIP(), []int{4} +} + +// 空响应 +type EmptyResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *EmptyResponse) Reset() { + *x = EmptyResponse{} + mi := &file_shared_proto_common_common_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *EmptyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EmptyResponse) ProtoMessage() {} + +func (x *EmptyResponse) ProtoReflect() protoreflect.Message { + mi := &file_shared_proto_common_common_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EmptyResponse.ProtoReflect.Descriptor instead. +func (*EmptyResponse) Descriptor() ([]byte, []int) { + return file_shared_proto_common_common_proto_rawDescGZIP(), []int{5} +} + +// ID 请求 +type IDRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *IDRequest) Reset() { + *x = IDRequest{} + mi := &file_shared_proto_common_common_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *IDRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IDRequest) ProtoMessage() {} + +func (x *IDRequest) ProtoReflect() protoreflect.Message { + mi := &file_shared_proto_common_common_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IDRequest.ProtoReflect.Descriptor instead. +func (*IDRequest) Descriptor() ([]byte, []int) { + return file_shared_proto_common_common_proto_rawDescGZIP(), []int{6} +} + +func (x *IDRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// ID 响应 +type IDResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *IDResponse) Reset() { + *x = IDResponse{} + mi := &file_shared_proto_common_common_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *IDResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IDResponse) ProtoMessage() {} + +func (x *IDResponse) ProtoReflect() protoreflect.Message { + mi := &file_shared_proto_common_common_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IDResponse.ProtoReflect.Descriptor instead. +func (*IDResponse) Descriptor() ([]byte, []int) { + return file_shared_proto_common_common_proto_rawDescGZIP(), []int{7} +} + +func (x *IDResponse) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +// 状态响应 +type StatusResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StatusResponse) Reset() { + *x = StatusResponse{} + mi := &file_shared_proto_common_common_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StatusResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StatusResponse) ProtoMessage() {} + +func (x *StatusResponse) ProtoReflect() protoreflect.Message { + mi := &file_shared_proto_common_common_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StatusResponse.ProtoReflect.Descriptor instead. +func (*StatusResponse) Descriptor() ([]byte, []int) { + return file_shared_proto_common_common_proto_rawDescGZIP(), []int{8} +} + +func (x *StatusResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +func (x *StatusResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +var File_shared_proto_common_common_proto protoreflect.FileDescriptor + +const file_shared_proto_common_common_proto_rawDesc = "" + + "\n" + + " shared/proto/common/common.proto\x12\x06common\"L\n" + + "\bResponse\x12\x12\n" + + "\x04code\x18\x01 \x01(\x05R\x04code\x12\x18\n" + + "\amessage\x18\x02 \x01(\tR\amessage\x12\x12\n" + + "\x04data\x18\x03 \x01(\fR\x04data\"D\n" + + "\x11PaginationRequest\x12\x12\n" + + "\x04page\x18\x01 \x01(\x05R\x04page\x12\x1b\n" + + "\tpage_size\x18\x02 \x01(\x05R\bpageSize\"|\n" + + "\x12PaginationResponse\x12\x14\n" + + "\x05total\x18\x01 \x01(\x05R\x05total\x12\x12\n" + + "\x04page\x18\x02 \x01(\x05R\x04page\x12\x1b\n" + + "\tpage_size\x18\x03 \x01(\x05R\bpageSize\x12\x1f\n" + + "\vtotal_pages\x18\x04 \x01(\x05R\n" + + "totalPages\"O\n" + + "\x05Error\x12\x12\n" + + "\x04code\x18\x01 \x01(\x05R\x04code\x12\x18\n" + + "\amessage\x18\x02 \x01(\tR\amessage\x12\x18\n" + + "\adetails\x18\x03 \x01(\tR\adetails\"\x0e\n" + + "\fEmptyRequest\"\x0f\n" + + "\rEmptyResponse\"\x1b\n" + + "\tIDRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"\x1c\n" + + "\n" + + "IDResponse\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"D\n" + + "\x0eStatusResponse\x12\x18\n" + + "\asuccess\x18\x01 \x01(\bR\asuccess\x12\x18\n" + + "\amessage\x18\x02 \x01(\tR\amessageB\x15Z\x13shared/proto/commonb\x06proto3" + +var ( + file_shared_proto_common_common_proto_rawDescOnce sync.Once + file_shared_proto_common_common_proto_rawDescData []byte +) + +func file_shared_proto_common_common_proto_rawDescGZIP() []byte { + file_shared_proto_common_common_proto_rawDescOnce.Do(func() { + file_shared_proto_common_common_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_shared_proto_common_common_proto_rawDesc), len(file_shared_proto_common_common_proto_rawDesc))) + }) + return file_shared_proto_common_common_proto_rawDescData +} + +var file_shared_proto_common_common_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_shared_proto_common_common_proto_goTypes = []any{ + (*Response)(nil), // 0: common.Response + (*PaginationRequest)(nil), // 1: common.PaginationRequest + (*PaginationResponse)(nil), // 2: common.PaginationResponse + (*Error)(nil), // 3: common.Error + (*EmptyRequest)(nil), // 4: common.EmptyRequest + (*EmptyResponse)(nil), // 5: common.EmptyResponse + (*IDRequest)(nil), // 6: common.IDRequest + (*IDResponse)(nil), // 7: common.IDResponse + (*StatusResponse)(nil), // 8: common.StatusResponse +} +var file_shared_proto_common_common_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_shared_proto_common_common_proto_init() } +func file_shared_proto_common_common_proto_init() { + if File_shared_proto_common_common_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_shared_proto_common_common_proto_rawDesc), len(file_shared_proto_common_common_proto_rawDesc)), + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_shared_proto_common_common_proto_goTypes, + DependencyIndexes: file_shared_proto_common_common_proto_depIdxs, + MessageInfos: file_shared_proto_common_common_proto_msgTypes, + }.Build() + File_shared_proto_common_common_proto = out.File + file_shared_proto_common_common_proto_goTypes = nil + file_shared_proto_common_common_proto_depIdxs = nil +} diff --git a/backend/shared/proto/common/common.proto b/backend/shared/proto/common/common.proto index 6703c60..aec85d3 100644 --- a/backend/shared/proto/common/common.proto +++ b/backend/shared/proto/common/common.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package common; +option go_package = "shared/proto/common"; + // 通用响应结构 message Response { int32 code = 1; diff --git a/backend/shared/proto/user/user.pb.go b/backend/shared/proto/user/user.pb.go new file mode 100644 index 0000000..1e80cca --- /dev/null +++ b/backend/shared/proto/user/user.pb.go @@ -0,0 +1,323 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v6.31.1 +// source: shared/proto/user/user.proto + +package user + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + common "shared/proto/common" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// 注册请求 +type RegisterRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Account string `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RegisterRequest) Reset() { + *x = RegisterRequest{} + mi := &file_shared_proto_user_user_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegisterRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterRequest) ProtoMessage() {} + +func (x *RegisterRequest) ProtoReflect() protoreflect.Message { + mi := &file_shared_proto_user_user_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterRequest.ProtoReflect.Descriptor instead. +func (*RegisterRequest) Descriptor() ([]byte, []int) { + return file_shared_proto_user_user_proto_rawDescGZIP(), []int{0} +} + +func (x *RegisterRequest) GetAccount() string { + if x != nil { + return x.Account + } + return "" +} + +func (x *RegisterRequest) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +// 注册响应 +type RegisterResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + Account string `protobuf:"bytes,2,opt,name=account,proto3" json:"account,omitempty"` + Response *common.Response `protobuf:"bytes,3,opt,name=response,proto3" json:"response,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RegisterResponse) Reset() { + *x = RegisterResponse{} + mi := &file_shared_proto_user_user_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RegisterResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RegisterResponse) ProtoMessage() {} + +func (x *RegisterResponse) ProtoReflect() protoreflect.Message { + mi := &file_shared_proto_user_user_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RegisterResponse.ProtoReflect.Descriptor instead. +func (*RegisterResponse) Descriptor() ([]byte, []int) { + return file_shared_proto_user_user_proto_rawDescGZIP(), []int{1} +} + +func (x *RegisterResponse) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *RegisterResponse) GetAccount() string { + if x != nil { + return x.Account + } + return "" +} + +func (x *RegisterResponse) GetResponse() *common.Response { + if x != nil { + return x.Response + } + return nil +} + +// 获取用户信息请求 +type GetUserByAccountRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Account string `protobuf:"bytes,1,opt,name=account,proto3" json:"account,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetUserByAccountRequest) Reset() { + *x = GetUserByAccountRequest{} + mi := &file_shared_proto_user_user_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetUserByAccountRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserByAccountRequest) ProtoMessage() {} + +func (x *GetUserByAccountRequest) ProtoReflect() protoreflect.Message { + mi := &file_shared_proto_user_user_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetUserByAccountRequest.ProtoReflect.Descriptor instead. +func (*GetUserByAccountRequest) Descriptor() ([]byte, []int) { + return file_shared_proto_user_user_proto_rawDescGZIP(), []int{2} +} + +func (x *GetUserByAccountRequest) GetAccount() string { + if x != nil { + return x.Account + } + return "" +} + +// 获取用户信息响应 +type GetUserByAccountResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + Account string `protobuf:"bytes,2,opt,name=account,proto3" json:"account,omitempty"` + Response *common.Response `protobuf:"bytes,3,opt,name=response,proto3" json:"response,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetUserByAccountResponse) Reset() { + *x = GetUserByAccountResponse{} + mi := &file_shared_proto_user_user_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetUserByAccountResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserByAccountResponse) ProtoMessage() {} + +func (x *GetUserByAccountResponse) ProtoReflect() protoreflect.Message { + mi := &file_shared_proto_user_user_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetUserByAccountResponse.ProtoReflect.Descriptor instead. +func (*GetUserByAccountResponse) Descriptor() ([]byte, []int) { + return file_shared_proto_user_user_proto_rawDescGZIP(), []int{3} +} + +func (x *GetUserByAccountResponse) GetUserId() string { + if x != nil { + return x.UserId + } + return "" +} + +func (x *GetUserByAccountResponse) GetAccount() string { + if x != nil { + return x.Account + } + return "" +} + +func (x *GetUserByAccountResponse) GetResponse() *common.Response { + if x != nil { + return x.Response + } + return nil +} + +var File_shared_proto_user_user_proto protoreflect.FileDescriptor + +const file_shared_proto_user_user_proto_rawDesc = "" + + "\n" + + "\x1cshared/proto/user/user.proto\x12\x04user\x1a shared/proto/common/common.proto\"G\n" + + "\x0fRegisterRequest\x12\x18\n" + + "\aaccount\x18\x01 \x01(\tR\aaccount\x12\x1a\n" + + "\bpassword\x18\x02 \x01(\tR\bpassword\"s\n" + + "\x10RegisterResponse\x12\x17\n" + + "\auser_id\x18\x01 \x01(\tR\x06userId\x12\x18\n" + + "\aaccount\x18\x02 \x01(\tR\aaccount\x12,\n" + + "\bresponse\x18\x03 \x01(\v2\x10.common.ResponseR\bresponse\"3\n" + + "\x17GetUserByAccountRequest\x12\x18\n" + + "\aaccount\x18\x01 \x01(\tR\aaccount\"{\n" + + "\x18GetUserByAccountResponse\x12\x17\n" + + "\auser_id\x18\x01 \x01(\tR\x06userId\x12\x18\n" + + "\aaccount\x18\x02 \x01(\tR\aaccount\x12,\n" + + "\bresponse\x18\x03 \x01(\v2\x10.common.ResponseR\bresponse2\x9b\x01\n" + + "\vUserService\x129\n" + + "\bRegister\x12\x15.user.RegisterRequest\x1a\x16.user.RegisterResponse\x12Q\n" + + "\x10GetUserByAccount\x12\x1d.user.GetUserByAccountRequest\x1a\x1e.user.GetUserByAccountResponseB\x13Z\x11shared/proto/userb\x06proto3" + +var ( + file_shared_proto_user_user_proto_rawDescOnce sync.Once + file_shared_proto_user_user_proto_rawDescData []byte +) + +func file_shared_proto_user_user_proto_rawDescGZIP() []byte { + file_shared_proto_user_user_proto_rawDescOnce.Do(func() { + file_shared_proto_user_user_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_shared_proto_user_user_proto_rawDesc), len(file_shared_proto_user_user_proto_rawDesc))) + }) + return file_shared_proto_user_user_proto_rawDescData +} + +var file_shared_proto_user_user_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_shared_proto_user_user_proto_goTypes = []any{ + (*RegisterRequest)(nil), // 0: user.RegisterRequest + (*RegisterResponse)(nil), // 1: user.RegisterResponse + (*GetUserByAccountRequest)(nil), // 2: user.GetUserByAccountRequest + (*GetUserByAccountResponse)(nil), // 3: user.GetUserByAccountResponse + (*common.Response)(nil), // 4: common.Response +} +var file_shared_proto_user_user_proto_depIdxs = []int32{ + 4, // 0: user.RegisterResponse.response:type_name -> common.Response + 4, // 1: user.GetUserByAccountResponse.response:type_name -> common.Response + 0, // 2: user.UserService.Register:input_type -> user.RegisterRequest + 2, // 3: user.UserService.GetUserByAccount:input_type -> user.GetUserByAccountRequest + 1, // 4: user.UserService.Register:output_type -> user.RegisterResponse + 3, // 5: user.UserService.GetUserByAccount:output_type -> user.GetUserByAccountResponse + 4, // [4:6] is the sub-list for method output_type + 2, // [2:4] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_shared_proto_user_user_proto_init() } +func file_shared_proto_user_user_proto_init() { + if File_shared_proto_user_user_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_shared_proto_user_user_proto_rawDesc), len(file_shared_proto_user_user_proto_rawDesc)), + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_shared_proto_user_user_proto_goTypes, + DependencyIndexes: file_shared_proto_user_user_proto_depIdxs, + MessageInfos: file_shared_proto_user_user_proto_msgTypes, + }.Build() + File_shared_proto_user_user_proto = out.File + file_shared_proto_user_user_proto_goTypes = nil + file_shared_proto_user_user_proto_depIdxs = nil +} diff --git a/backend/services/user-svc/proto/user.proto b/backend/shared/proto/user/user.proto similarity index 94% rename from backend/services/user-svc/proto/user.proto rename to backend/shared/proto/user/user.proto index 3846fe0..b2f440c 100644 --- a/backend/services/user-svc/proto/user.proto +++ b/backend/shared/proto/user/user.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package user; +option go_package = "shared/proto/user"; + import "shared/proto/common/common.proto"; // 用户服务 diff --git a/backend/shared/proto/user/user_grpc.pb.go b/backend/shared/proto/user/user_grpc.pb.go new file mode 100644 index 0000000..c6cf762 --- /dev/null +++ b/backend/shared/proto/user/user_grpc.pb.go @@ -0,0 +1,167 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.6.1 +// - protoc v6.31.1 +// source: shared/proto/user/user.proto + +package user + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + UserService_Register_FullMethodName = "/user.UserService/Register" + UserService_GetUserByAccount_FullMethodName = "/user.UserService/GetUserByAccount" +) + +// UserServiceClient is the client API for UserService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// 用户服务 +type UserServiceClient interface { + // 注册用户 + Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterResponse, error) + // 获取用户信息 + GetUserByAccount(ctx context.Context, in *GetUserByAccountRequest, opts ...grpc.CallOption) (*GetUserByAccountResponse, error) +} + +type userServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewUserServiceClient(cc grpc.ClientConnInterface) UserServiceClient { + return &userServiceClient{cc} +} + +func (c *userServiceClient) Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(RegisterResponse) + err := c.cc.Invoke(ctx, UserService_Register_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetUserByAccount(ctx context.Context, in *GetUserByAccountRequest, opts ...grpc.CallOption) (*GetUserByAccountResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetUserByAccountResponse) + err := c.cc.Invoke(ctx, UserService_GetUserByAccount_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// UserServiceServer is the server API for UserService service. +// All implementations must embed UnimplementedUserServiceServer +// for forward compatibility. +// +// 用户服务 +type UserServiceServer interface { + // 注册用户 + Register(context.Context, *RegisterRequest) (*RegisterResponse, error) + // 获取用户信息 + GetUserByAccount(context.Context, *GetUserByAccountRequest) (*GetUserByAccountResponse, error) + mustEmbedUnimplementedUserServiceServer() +} + +// UnimplementedUserServiceServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedUserServiceServer struct{} + +func (UnimplementedUserServiceServer) Register(context.Context, *RegisterRequest) (*RegisterResponse, error) { + return nil, status.Error(codes.Unimplemented, "method Register not implemented") +} +func (UnimplementedUserServiceServer) GetUserByAccount(context.Context, *GetUserByAccountRequest) (*GetUserByAccountResponse, error) { + return nil, status.Error(codes.Unimplemented, "method GetUserByAccount not implemented") +} +func (UnimplementedUserServiceServer) mustEmbedUnimplementedUserServiceServer() {} +func (UnimplementedUserServiceServer) testEmbeddedByValue() {} + +// UnsafeUserServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to UserServiceServer will +// result in compilation errors. +type UnsafeUserServiceServer interface { + mustEmbedUnimplementedUserServiceServer() +} + +func RegisterUserServiceServer(s grpc.ServiceRegistrar, srv UserServiceServer) { + // If the following call panics, it indicates UnimplementedUserServiceServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&UserService_ServiceDesc, srv) +} + +func _UserService_Register_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RegisterRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).Register(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_Register_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).Register(ctx, req.(*RegisterRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetUserByAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetUserByAccountRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetUserByAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_GetUserByAccount_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetUserByAccount(ctx, req.(*GetUserByAccountRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// UserService_ServiceDesc is the grpc.ServiceDesc for UserService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var UserService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "user.UserService", + HandlerType: (*UserServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Register", + Handler: _UserService_Register_Handler, + }, + { + MethodName: "GetUserByAccount", + Handler: _UserService_GetUserByAccount_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "shared/proto/user/user.proto", +} diff --git a/backend/test.proto b/backend/test.proto new file mode 100644 index 0000000..3ad0d4b --- /dev/null +++ b/backend/test.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package test; + +option go_package = "test/proto"; + +message TestMessage { + string name = 1; + int32 age = 2; +} diff --git a/backend/test/proto/test.pb.go b/backend/test/proto/test.pb.go new file mode 100644 index 0000000..b3b1a2f --- /dev/null +++ b/backend/test/proto/test.pb.go @@ -0,0 +1,133 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.11 +// protoc v6.31.1 +// source: test.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type TestMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Age int32 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *TestMessage) Reset() { + *x = TestMessage{} + mi := &file_test_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *TestMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TestMessage) ProtoMessage() {} + +func (x *TestMessage) ProtoReflect() protoreflect.Message { + mi := &file_test_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TestMessage.ProtoReflect.Descriptor instead. +func (*TestMessage) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{0} +} + +func (x *TestMessage) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *TestMessage) GetAge() int32 { + if x != nil { + return x.Age + } + return 0 +} + +var File_test_proto protoreflect.FileDescriptor + +const file_test_proto_rawDesc = "" + + "\n" + + "\n" + + "test.proto\x12\x04test\"3\n" + + "\vTestMessage\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x10\n" + + "\x03age\x18\x02 \x01(\x05R\x03ageB\fZ\n" + + "test/protob\x06proto3" + +var ( + file_test_proto_rawDescOnce sync.Once + file_test_proto_rawDescData []byte +) + +func file_test_proto_rawDescGZIP() []byte { + file_test_proto_rawDescOnce.Do(func() { + file_test_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_test_proto_rawDesc), len(file_test_proto_rawDesc))) + }) + return file_test_proto_rawDescData +} + +var file_test_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_test_proto_goTypes = []any{ + (*TestMessage)(nil), // 0: test.TestMessage +} +var file_test_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_test_proto_init() } +func file_test_proto_init() { + if File_test_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_test_proto_rawDesc), len(file_test_proto_rawDesc)), + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_test_proto_goTypes, + DependencyIndexes: file_test_proto_depIdxs, + MessageInfos: file_test_proto_msgTypes, + }.Build() + File_test_proto = out.File + file_test_proto_goTypes = nil + file_test_proto_depIdxs = nil +} diff --git a/prompt/v3.md b/prompt/v3.md new file mode 100644 index 0000000..3d9df4f --- /dev/null +++ b/prompt/v3.md @@ -0,0 +1,45 @@ +设计用户第注册功能,数据库要求: + +``` + +一、表名:user_main + +字段: + +1、id uuidv7 default 主键。 + +2、deleted bool defalut false。 + +3、create_time .... + +4、update_time .... + +二、表名:user_login_account + +1、id uuidv7 default 主键。 + +2、user_id uuidv7 对应 user_main 表的 id。 + +3、account varchat not null。 + +4、deleted bool defalut false。 + +5、create_time .... + +6、update_time .... + +三、表名:user_login_password + +1、id uuidv7 default 主键。 + +2、user_id uuidv7 对应 user_main 表的 id。 + +3、password varchat not null。 + +4、deleted bool defalut false。 + +5、create_time .... + +6、update_time .... + +```