This commit is contained in:
expvintl 2024-06-16 02:08:50 +08:00
commit ac6c8aef67
22 changed files with 548 additions and 0 deletions

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

4
.idea/MossChat.iml Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="Go" enabled="true" />
</module>

12
.idea/dataSources.xml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="@192.168.6.4" uuid="4bdf6a40-20a7-4cfa-afc2-e3ee1a5609c1">
<driver-ref>mariadb</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.mariadb.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mariadb://192.168.6.4:3306</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

View File

@ -0,0 +1,10 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="GoDfaErrorMayBeNotNil" enabled="true" level="WARNING" enabled_by_default="true">
<functions>
<function importPath="MossChat/models" name="CreateUser" />
</functions>
</inspection_tool>
</profile>
</component>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/MossChat.iml" filepath="$PROJECT_DIR$/.idea/MossChat.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

49
api/register.go Normal file
View File

@ -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()
}

51
cache/main.go vendored Normal file
View File

@ -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
}

6
config/config.go Normal file
View File

@ -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"
)

27
db/init.go Normal file
View File

@ -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
}

9
enums/gender.go Normal file
View File

@ -0,0 +1,9 @@
package enums
type GenderType int
const (
Unknown GenderType = iota
Male
Female
)

40
go.mod Normal file
View File

@ -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
)

94
go.sum Normal file
View File

@ -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=

12
logger/main.go Normal file
View File

@ -0,0 +1,12 @@
package logger
import (
"log"
"os"
)
var Log *log.Logger
func InitLogger() {
Log = log.New(os.Stdout, "", log.Lshortfile|log.LstdFlags)
}

19
main.go Normal file
View File

@ -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 {}
}

7
models/response.go Normal file
View File

@ -0,0 +1,7 @@
package models
type Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data"`
}

85
models/user.go Normal file
View File

@ -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
}

14
readme.md Normal file
View File

@ -0,0 +1,14 @@
<h1 align="center">MossChat</h1>
<p align="center">一个基本聊天服务器后端实现</p>
<hr/>
> 该项目仍在开发,甚至无法使用....
**TODO:**
- [ ] 🔑登录/注册
- [ ] 💬基础聊天
- [ ] 🧑‍🤝‍🧑群组支持
- [ ] 🗣️私聊支持
等等....

22
route/server.go Normal file
View File

@ -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
}

17
utils/utils.go Normal file
View File

@ -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)
}

5
ws/main.go Normal file
View File

@ -0,0 +1,5 @@
package ws
func InitWS() {
}

43
ws/server.go Normal file
View File

@ -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))
}
}