From ac6c8aef67920d670078eeed4813839b31e86b77 Mon Sep 17 00:00:00 2001 From: expvintl Date: Sun, 16 Jun 2024 02:08:50 +0800 Subject: [PATCH] init --- .idea/.gitignore | 8 ++ .idea/MossChat.iml | 4 + .idea/dataSources.xml | 12 +++ .idea/inspectionProfiles/Project_Default.xml | 10 +++ .idea/modules.xml | 8 ++ .idea/vcs.xml | 6 ++ api/register.go | 49 ++++++++++ cache/main.go | 51 +++++++++++ config/config.go | 6 ++ db/init.go | 27 ++++++ enums/gender.go | 9 ++ go.mod | 40 +++++++++ go.sum | 94 ++++++++++++++++++++ logger/main.go | 12 +++ main.go | 19 ++++ models/response.go | 7 ++ models/user.go | 85 ++++++++++++++++++ readme.md | 14 +++ route/server.go | 22 +++++ utils/utils.go | 17 ++++ ws/main.go | 5 ++ ws/server.go | 43 +++++++++ 22 files changed, 548 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/MossChat.iml create mode 100644 .idea/dataSources.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 api/register.go create mode 100644 cache/main.go create mode 100644 config/config.go create mode 100644 db/init.go create mode 100644 enums/gender.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 logger/main.go create mode 100644 main.go create mode 100644 models/response.go create mode 100644 models/user.go create mode 100644 readme.md create mode 100644 route/server.go create mode 100644 utils/utils.go create mode 100644 ws/main.go create mode 100644 ws/server.go diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/MossChat.iml b/.idea/MossChat.iml new file mode 100644 index 0000000..7ee078d --- /dev/null +++ b/.idea/MossChat.iml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..988a244 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,12 @@ + + + + + mariadb + true + org.mariadb.jdbc.Driver + jdbc:mariadb://192.168.6.4:3306 + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..1d2e20f --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..90ad91c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/api/register.go b/api/register.go new file mode 100644 index 0000000..4736eb0 --- /dev/null +++ b/api/register.go @@ -0,0 +1,49 @@ +package api + +import ( + "MossChat/models" + "github.com/gin-gonic/gin" + "net/http" +) + +type RegisterReq struct { + Username string `json:"username"` + Password string `json:"password"` + NickName string `json:"nickname"` +} +type UserResponse struct { + Uid uint `json:"uid"` + Username string `json:"username"` + NickName string `json:"nickname"` +} + +func RegisterHandler(ctx *gin.Context) { + req := &RegisterReq{} + if err := ctx.Bind(req); err != nil { + ctx.JSON(http.StatusOK, models.Response{ + Code: 401, + Message: "无效请求!", + Data: nil, + }) + ctx.Abort() + } + user, err := models.CreateUser(req.NickName, req.Password, req.NickName, 0) + if err != nil { + ctx.JSON(http.StatusOK, models.Response{ + Code: -1, + Message: err.Error(), + Data: nil, + }) + ctx.Abort() + } + ctx.JSON(http.StatusOK, models.Response{ + Code: 0, + Message: "注册成功!", + Data: UserResponse{ + Uid: user.ID, + Username: user.Username, + NickName: user.Nickname, + }, + }) + ctx.Next() +} diff --git a/cache/main.go b/cache/main.go new file mode 100644 index 0000000..9d54bfa --- /dev/null +++ b/cache/main.go @@ -0,0 +1,51 @@ +package cache + +import ( + "MossChat/config" + "MossChat/logger" + "MossChat/utils" + "github.com/go-redis/redis" + "time" +) + +var DB *redis.Client + +func InitRedis() { + DB = redis.NewClient(&redis.Options{ + Addr: config.REDIS_ADDR, + DB: 0, + }) + _, err := DB.Ping().Result() + if err != nil { + logger.Log.Println("无法连接到Redis!") + panic(err) + } + logger.Log.Println("已加载redis!") +} + +// GenerateToken 计算新的Token +func GenerateToken(uid int, duration time.Duration) error { + err := DB.Set(utils.ToTokenKey(utils.RandomString(16)), uid, duration).Err() + if err != nil { + return err + } + return nil +} + +// 获取用户ID +func GetUidByToken(token string) (int, error) { + uid, err := DB.Get(utils.ToTokenKey(token)).Int() + if err != nil { + return 0, err + } + return uid, nil +} + +// 移除Token +func RemoveToken(token string) error { + err := DB.Del(utils.ToTokenKey(token)).Err() + if err != nil { + return err + } + return nil +} diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..98bc241 --- /dev/null +++ b/config/config.go @@ -0,0 +1,6 @@ +package config + +const ( + MYSQL_CONFIG = "root:test12311@tcp(localhost:3306)/chatapp?charset=utf8mb4&parseTime=True&loc=Local" + REDIS_ADDR = "localhost:6379" +) \ No newline at end of file diff --git a/db/init.go b/db/init.go new file mode 100644 index 0000000..23e5e53 --- /dev/null +++ b/db/init.go @@ -0,0 +1,27 @@ +package db + +import ( + "MossChat/cache" + "MossChat/config" + "MossChat/logger" + "MossChat/models" + "gorm.io/driver/mysql" + "gorm.io/gorm" +) + +var DB *gorm.DB + +func InitDatabase() { + cache.InitRedis() + db, err := gorm.Open(mysql.Open(config.MYSQL_CONFIG), &gorm.Config{}) + if err != nil { + logger.Log.Println("无法打开数据库!") + panic(err) + } + err = db.AutoMigrate(&models.User{}) + if err != nil { + logger.Log.Println("迁移数据库失败!") + panic(err) + } + DB = db +} diff --git a/enums/gender.go b/enums/gender.go new file mode 100644 index 0000000..2eb5a96 --- /dev/null +++ b/enums/gender.go @@ -0,0 +1,9 @@ +package enums + +type GenderType int + +const ( + Unknown GenderType = iota + Male + Female +) diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..2a7ba2b --- /dev/null +++ b/go.mod @@ -0,0 +1,40 @@ +module MossChat + +go 1.22.1 + +require ( + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gin-gonic/gin v1.10.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.20.0 // indirect + github.com/go-redis/redis v6.15.9+incompatible // indirect + github.com/go-sql-driver/mysql v1.7.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + gorm.io/driver/mysql v1.5.6 // indirect + gorm.io/gorm v1.25.10 // indirect + nhooyr.io/websocket v1.8.11 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..a70bfb0 --- /dev/null +++ b/go.sum @@ -0,0 +1,94 @@ +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= +github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= +github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/mysql v1.5.6 h1:Ld4mkIickM+EliaQZQx3uOJDJHtrd70MxAUqWqlx3Y8= +gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= +gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s= +gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= +nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/logger/main.go b/logger/main.go new file mode 100644 index 0000000..3b3e95b --- /dev/null +++ b/logger/main.go @@ -0,0 +1,12 @@ +package logger + +import ( + "log" + "os" +) + +var Log *log.Logger + +func InitLogger() { + Log = log.New(os.Stdout, "", log.Lshortfile|log.LstdFlags) +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..6d5dd93 --- /dev/null +++ b/main.go @@ -0,0 +1,19 @@ +package main + +import ( + "MossChat/api" + "MossChat/db" + "MossChat/logger" + "MossChat/route" +) + +func main() { + //初始化日志 + logger.InitLogger() + db.InitDatabase() + sv := route.InitWebServer(":1145") + sv.POST("/api/v1/user/register", api.RegisterHandler) + //wsSv := ws.ChatServer{ServerName: "ChatV1", RelativePath: "/chat"} + //wsSv.Bind(sv) + //select {} +} diff --git a/models/response.go b/models/response.go new file mode 100644 index 0000000..1f40b85 --- /dev/null +++ b/models/response.go @@ -0,0 +1,7 @@ +package models + +type Response struct { + Code int `json:"code"` + Message string `json:"message"` + Data interface{} `json:"data"` +} diff --git a/models/user.go b/models/user.go new file mode 100644 index 0000000..34d22d8 --- /dev/null +++ b/models/user.go @@ -0,0 +1,85 @@ +package models + +import ( + "MossChat/db" + "MossChat/enums" + "errors" + "fmt" + "golang.org/x/crypto/bcrypt" + "gorm.io/gorm" +) + +type User struct { + gorm.Model + Username string `json:"username"` + Password string `json:"-"` + Nickname string `json:"nickname"` + Gender enums.GenderType `json:"gender"` + Introduce string `json:"introduce"` + Email string `json:"email"` + Avatar string `json:"avatar"` + IsBanned bool `json:"is_banned"` + Phone string `json:"phone"` +} + +func (user *User) UpdatePassword(password string) error { + bcryptHash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) + if err != nil { + return errors.New("无法加密密码") + } + user.Password = string(bcryptHash) + return nil +} +func (user *User) CheckPassword(password string) error { + return bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)) +} +func (user *User) Delete() error { + if err := db.DB.Delete(user); err != nil { + return errors.New("无法删除该用户") + } + return nil +} + +func CreateUser(username string, password string, nickname string, gender enums.GenderType) (User, error) { + user := User{Username: username, + Nickname: nickname, + Gender: gender, + Introduce: "这个人很懒,什么都没留下。", + } + var count int64 + if err := db.DB.Model(&User{}).Where("username = ?", username).Count(&count).Error; err != nil { + return User{}, errors.New("数据库查询错误") + } + if count != 0 { + return User{}, errors.New("用户已存在") + } + //加密密码 + if err := user.UpdatePassword(password); err != nil { + return User{}, err + } + if err := db.DB.Create(user).Error; err != nil { + return User{}, errors.New("无法创建用户") + } + return user, nil +} + +func DeleteUser(username string) error { + if err := db.DB.Model(&User{}).Where("username = ?", username).Delete(&User{}).Error; err != nil { + return errors.New(fmt.Sprintf("无法创建用户:%s", err.Error())) + } + return nil +} +func GetUserByUsername(username string) (User, error) { + var user User + if err := db.DB.Where("username = ?", username).First(&user).Error; err != nil { + return User{}, errors.New("无法找到用户") + } + return user, nil +} +func GetUserByUid(uid uint) (User, error) { + var user User + if err := db.DB.Where("uid = ?", uid).First(&user).Error; err != nil { + return User{}, errors.New("无法找到用户") + } + return user, nil +} diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..ab6bf84 --- /dev/null +++ b/readme.md @@ -0,0 +1,14 @@ +

MossChat

+

一个基本聊天服务器后端实现

+
+ +> 该项目仍在开发,甚至无法使用.... + +**TODO:** + +- [ ] 🔑登录/注册 +- [ ] 💬基础聊天 +- [ ] 🧑‍🤝‍🧑群组支持 +- [ ] 🗣️私聊支持 + +等等.... \ No newline at end of file diff --git a/route/server.go b/route/server.go new file mode 100644 index 0000000..35c8b31 --- /dev/null +++ b/route/server.go @@ -0,0 +1,22 @@ +package route + +import ( + "MossChat/logger" + "github.com/gin-gonic/gin" +) + +var WebSv *gin.Engine + +func InitWebServer(bind string) *gin.Engine { + router := gin.Default() + go func() { + err := router.Run(bind) + if err != nil { + logger.Log.Println("无法绑定Web服务器! 原因:", err) + return + } + WebSv = router + logger.Log.Println("Web服务器运行在", bind) + }() + return router +} diff --git a/utils/utils.go b/utils/utils.go new file mode 100644 index 0000000..b64940c --- /dev/null +++ b/utils/utils.go @@ -0,0 +1,17 @@ +package utils + +import ( + "fmt" + "math/rand" +) + +func RandomString(length int) string { + arr := make([]rune, length) + for i := range arr { + arr[i] = 'a' + rune(rand.Intn(26)) + } + return string(arr) +} +func ToTokenKey(token string) string { + return fmt.Sprintf("token_%s", token) +} diff --git a/ws/main.go b/ws/main.go new file mode 100644 index 0000000..af4bf14 --- /dev/null +++ b/ws/main.go @@ -0,0 +1,5 @@ +package ws + +func InitWS() { + +} diff --git a/ws/server.go b/ws/server.go new file mode 100644 index 0000000..d92d47e --- /dev/null +++ b/ws/server.go @@ -0,0 +1,43 @@ +package ws + +import ( + "MossChat/logger" + "fmt" + "github.com/gin-gonic/gin" + "log" + "nhooyr.io/websocket" +) + +type ChatServer struct { + ServerName string + RelativePath string + ctx *gin.Context +} + +func (sv *ChatServer) Bind(engine *gin.Engine) *ChatServer { + engine.GET(sv.RelativePath, func(context *gin.Context) { + options := websocket.AcceptOptions{ + InsecureSkipVerify: true, + } + accept, err := websocket.Accept(context.Writer, context.Request, &options) + if err != nil { + logger.Log.Println("无法接受请求!:", err) + return + } + go sv.HandleConnections(accept) + sv.ctx = context + }) + logger.Log.Println("已创建Websocket聊天服务器:", sv.ServerName, "在", sv.RelativePath) + return sv +} +func (sv *ChatServer) HandleConnections(conn *websocket.Conn) { + defer conn.CloseNow() + for { + _, dat, err := conn.Read(sv.ctx) + if websocket.CloseStatus(err) == websocket.StatusNormalClosure || websocket.CloseStatus(err) == websocket.StatusNoStatusRcvd { + log.Println("Websocket连接已关闭!") + return + } + fmt.Println(string(dat)) + } +}