diff --git a/.gitignore b/.gitignore index 9d915e3..6706d79 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ yarn-debug.log* yarn-error.log* /public/uploads/ config.yaml +*.pb.go # Editor directories and files .idea diff --git a/api/user.go b/api/user.go new file mode 100644 index 0000000..fbe2b00 --- /dev/null +++ b/api/user.go @@ -0,0 +1,53 @@ +package api + +import ( + "context" + "fmt" + grpcClient "go-desk-service/grpc-client" + "go-desk-service/libs" + userpb "go-desk-service/proto/gen" + "log" + "net/http" + "time" + + "github.com/gin-gonic/gin" +) + +type User struct { +} + +type LoginRequestParams struct { + Username string `form:"username" json:"username" uri:"username" xml:"username" binding:"required"` + Password string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"` +} + +func (*User) Login(ctx *gin.Context) { + var res *libs.ErrorInfo + var paramsJson LoginRequestParams + if err := ctx.ShouldBindJSON(¶msJson); err != nil { + res = libs.ErrorCode["ParamsError"] + fmt.Println(err) + ctx.JSON(http.StatusBadRequest, gin.H{ + "code": res.Code, + "msg": res.Msg, + "data": res.Data, + }) + return + } + // 获取当前的grpc连接 + client := grpcClient.GetUserClient() + ctx1, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + loginResp, err := client.Login(ctx1, &userpb.LoginRequest{ + Username: paramsJson.Username, + Password: paramsJson.Password, + }) + if err != nil { + log.Fatalf("登录失败: %v", err) + } + ctx.JSON(http.StatusBadRequest, gin.H{ + "code": 200, + "msg": "登录成功", + "data": loginResp, + }) +} diff --git a/cmd/main.go b/cmd/main.go index fb86ee4..39bdb24 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -3,6 +3,7 @@ package main import ( "fmt" "go-desk-service/config" + grpcClient "go-desk-service/grpc-client" "go-desk-service/libs" "go-desk-service/router" "log" @@ -23,6 +24,7 @@ func main() { go handleShutdownSignals() libs.Connect() + grpcClient.UserClientInit() app := gin.Default() router.Init(app) app.Run(":" + strconv.Itoa(appConfig.Port)) diff --git a/config/index.go b/config/index.go index 45d628a..4d96eff 100644 --- a/config/index.go +++ b/config/index.go @@ -11,6 +11,7 @@ type AppConfig struct { Database DatabaseConfig `yaml:"database"` WorkerID int64 `yaml:"workerID"` DatacenterID int64 `yaml:"datacenterID"` + GrpcUrl string `yaml:"grpcUrl"` } type DatabaseConfig struct { diff --git a/go.mod b/go.mod index 6516271..2bfa85a 100644 --- a/go.mod +++ b/go.mod @@ -42,6 +42,8 @@ require ( golang.org/x/sync v0.16.0 // indirect golang.org/x/sys v0.35.0 // indirect golang.org/x/text v0.28.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect + google.golang.org/grpc v1.75.0 // indirect google.golang.org/protobuf v1.36.8 // indirect gorm.io/driver/postgres v1.6.0 // indirect gorm.io/gorm v1.30.2 // indirect diff --git a/go.sum b/go.sum index 8297196..82418b3 100644 --- a/go.sum +++ b/go.sum @@ -126,6 +126,10 @@ golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= +google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= diff --git a/grpc-client/user_client.go b/grpc-client/user_client.go new file mode 100644 index 0000000..27597cc --- /dev/null +++ b/grpc-client/user_client.go @@ -0,0 +1,36 @@ +package grpcClient + +import ( + "fmt" + "go-desk-service/config" + userpb "go-desk-service/proto/gen" + "log" + + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +var UserClient userpb.UserServiceClient + +func UserClientInit() { + appConfig, err := config.LoadConfig() + if err != nil { + fmt.Println(err) + fmt.Println("读取配置失败") + } + + conn, err := grpc.NewClient( + appConfig.GrpcUrl, // gRPC服务器地址 + grpc.WithTransportCredentials(insecure.NewCredentials()), // 使用非安全连接(测试用) + ) + if err != nil { + log.Fatalf("连接失败: %v", err) + } + defer conn.Close() + client := userpb.NewUserServiceClient(conn) + UserClient = client +} + +func GetUserClient() userpb.UserServiceClient { + return UserClient +} diff --git a/libs/error_code.go b/libs/error_code.go new file mode 100644 index 0000000..b38170c --- /dev/null +++ b/libs/error_code.go @@ -0,0 +1,22 @@ +package libs + +type ErrorInfo struct { + Code int + Data any + Msg string +} + +var ErrorCode = map[string]*ErrorInfo{ + "LoginFailed": {Code: 0, Data: "", Msg: "账号异常"}, + "LoginSuccessful": {Code: 200, Data: "", Msg: "登录成功"}, + "NetworkTimeout": {Code: 1, Data: "", Msg: "网络超时"}, + "AccountHasBeenTakenOffline": {Code: 2, Data: "", Msg: "账号已下线,请重新登录"}, + "OtherError": {Code: 3, Data: "", Msg: "其他错误"}, + "TransferSuccessful": {Code: 200, Data: "", Msg: "转账成功"}, + "TransferFailed": {Code: 4, Data: "", Msg: "转账失败"}, + "AccountRequiresEmailVerification": {Code: 0, Data: "", Msg: "账号需要邮箱验证"}, + "AccountRequiresSMSVerification": {Code: 0, Data: "", Msg: "账号需要短信验证"}, + "AccountRequiresRobotVerification": {Code: 0, Data: "", Msg: "账号需要机器人验证"}, + "BrowserOpenFail": {Code: 0, Data: "", Msg: "浏览器开启失败"}, + "AccountFailed": {Code: 0, Data: "", Msg: "账号不存在"}, +} diff --git a/proto/user.proto b/proto/user.proto new file mode 100644 index 0000000..c9af424 --- /dev/null +++ b/proto/user.proto @@ -0,0 +1,56 @@ +syntax = "proto3"; + +package user; +option go_package = "./proto/gen;userpb"; + +// 登录请求 +message LoginRequest { + string username = 1; + string password = 2; +} + +// 登录响应 +message LoginResponse { + int64 user_id = 1; + string username = 2; + string email = 3; + string access_token = 4; + int32 expires_in = 5; // token过期时间(秒) +} + +// 用户注册请求 +message RegisterRequest { + string username = 1; + string password = 2; + string email = 3; + string nickname = 4; + string phone = 5; +} + +// 用户注册响应 +message RegisterResponse { + int64 user_id = 1; + string username = 2; + string email = 3; +} + +// 令牌验证请求 +message ValidateTokenRequest { + string access_token = 1; +} + +// 令牌验证响应 +message ValidateTokenResponse { + int64 user_id = 1; + bool is_valid = 2; +} + +// 用户服务定义 +service UserService { + // 用户登录 + rpc Login(LoginRequest) returns (LoginResponse); + // 用户注册 + rpc Register(RegisterRequest) returns (RegisterResponse); + // 验证访问令牌 + rpc ValidateToken(ValidateTokenRequest) returns (ValidateTokenResponse); +} \ No newline at end of file diff --git a/router/index.go b/router/index.go index d3ae91c..2455c87 100644 --- a/router/index.go +++ b/router/index.go @@ -4,8 +4,10 @@ import "github.com/gin-gonic/gin" var routerTest Test var websocks Websocks +var user User func Init(app *gin.Engine) { routerTest.Init(app) websocks.Init(app) + user.Init(app) } diff --git a/router/user.go b/router/user.go new file mode 100644 index 0000000..df10d81 --- /dev/null +++ b/router/user.go @@ -0,0 +1,16 @@ +package router + +import ( + "go-desk-service/api" + + "github.com/gin-gonic/gin" +) + +type User struct{} + +var ApiUser api.User + +func (*User) Init(app *gin.Engine) { + group := app.Group("/user") + group.POST("/login", ApiUser.Login) +}