From 8a8e222059185a218733e91ff389b0eed6ee31f4 Mon Sep 17 00:00:00 2001 From: icode-Cong Date: Sun, 13 Aug 2023 21:19:44 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=86Dao=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 3 ++ go.sum | 20 ++++++++++ main.go | 8 ++++ models/common.go | 45 +++++++++++++++++++++ models/mysql.go | 35 ++++++++++++++++ models/user.go | 81 ++++++++++++++++++++++++++++++++++++++ models/video.go | 73 ++++++++++++++++++++++++++++++++++ resources/application.yaml | 6 +++ 8 files changed, 271 insertions(+) create mode 100644 models/common.go create mode 100644 models/mysql.go create mode 100644 models/user.go create mode 100644 models/video.go create mode 100644 resources/application.yaml diff --git a/go.mod b/go.mod index 186ab0fb..6dc316db 100644 --- a/go.mod +++ b/go.mod @@ -17,10 +17,13 @@ require ( github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/validator/v10 v10.11.0 // indirect + github.com/go-sql-driver/mysql v1.5.0 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/imkira/go-interpol v1.1.0 // indirect + github.com/jinzhu/gorm v1.9.16 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.15.0 // indirect github.com/leodido/go-urn v1.2.1 // indirect diff --git a/go.sum b/go.sum index f953d3c4..98f7ac76 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,17 @@ +github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= github.com/fasthttp/websocket v1.4.3-rc.6 h1:omHqsl8j+KXpmzRjF8bmzOSYJ8GnS0E3efi1wYT+niY= github.com/fasthttp/websocket v1.4.3-rc.6/go.mod h1:43W9OM2T8FeXpCWMsBd9Cb7nE2CACNqNvCqQCoty/Lc= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= @@ -30,6 +34,9 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2BOGlCyvTqsp/xIw= github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= +github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= @@ -49,6 +56,11 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= +github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= +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.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= @@ -67,12 +79,14 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -137,7 +151,9 @@ github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcm github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -146,9 +162,12 @@ golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f h1:OeJjE6G4dgCY4PIXvIRQbE golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -163,6 +182,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/main.go b/main.go index 7eb95018..9e2a1852 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "github.com/RaymondCode/simple-demo/models" "github.com/RaymondCode/simple-demo/service" "github.com/gin-gonic/gin" ) @@ -8,6 +9,13 @@ import ( func main() { go service.RunMessageServer() + // 初始化配置,如MySQL等 + err := models.InitProject() + if err != nil { + panic(err) + } + defer models.Close() + r := gin.Default() initRouter(r) diff --git a/models/common.go b/models/common.go new file mode 100644 index 00000000..d7557fbd --- /dev/null +++ b/models/common.go @@ -0,0 +1,45 @@ +package models + +import ( + "os" + + "gopkg.in/yaml.v3" +) + +type MySQLConfig struct { + UserName string `yaml:"userName"` + Password string `yaml:"password"` + DBName string `yaml:"dbname"` + Url string `yaml:"url"` + Port string `yaml:"port"` +} + +type GlobalConfig struct { + MySQLConf MySQLConfig `yaml:"mysql"` +} + +func (c *GlobalConfig) getConf() *GlobalConfig { + yamlFile, err := os.ReadFile("resources/application.yaml") + if err != nil { + panic(err) + } + err = yaml.Unmarshal(yamlFile, c) + if err != nil { + panic(err) + } + return c +} + +func InitProject() (err error) { + var c GlobalConfig + conf := c.getConf() + err = InitMySql(conf.MySQLConf) + if err != nil { + panic(err) + } + return nil +} + +func Close() { + CloseMySQL() +} diff --git a/models/mysql.go b/models/mysql.go new file mode 100644 index 00000000..6bd6619f --- /dev/null +++ b/models/mysql.go @@ -0,0 +1,35 @@ +package models + +import ( + "fmt" + + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/mysql" +) + +const DRIVER = "mysql" + +var SqlSession *gorm.DB + +func InitMySql(conf MySQLConfig) (err error) { + dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", + conf.UserName, + conf.Password, + conf.Url, + conf.Port, + conf.DBName, + ) + SqlSession, err = gorm.Open(DRIVER, dsn) + if err != nil { + panic(err) + } + SqlSession.AutoMigrate(&User{}, &Video{}) + return SqlSession.DB().Ping() +} + +func CloseMySQL() { + err := SqlSession.Close() + if err != nil { + panic(err) + } +} diff --git a/models/user.go b/models/user.go new file mode 100644 index 00000000..18a4ac40 --- /dev/null +++ b/models/user.go @@ -0,0 +1,81 @@ +package models + +import ( + "sync" +) + +type User struct { + UserId int64 `gorm:"primary_key"` + Name string + // FollowingCount int64 `gorm:"default:(-)"` + // FollowerCount int64 `gorm:"default:(-)"` + Password string + // Avatar string `gorm:"default:(-)"` + // BackgroundImage string `gorm:"default:(-)"` + Signature string + // TotalFavorited int64 `gorm:"default:(-)"` + // WorkCount int64 `gorm:"default:(-)"` + // FavoriteCount int64 `gorm:"default:(-)"` + // CreateAt time.Time + // DeleteAt time.Time +} + +type UserDao struct{} + +var userDao *UserDao +var userOnce sync.Once + +func NewUserDaoInstance() *UserDao { + userOnce.Do( + func() { + userDao = &UserDao{} + }, + ) + return userDao +} + +/* +* +根据用户名和密码,创建一个新的User,返回UserId +*/ +func (*UserDao) CreateUser(user *User) (int64, error) { + /*user := User{Name: username, Password: password, FollowingCount: 0, FollowerCount: 0, CreateAt: time.Now()}*/ + + result := SqlSession.Create(&user) + + if result.Error != nil { + return -1, result.Error + } + + return user.UserId, nil +} + +/* +* +根据用户名,查找用户实体 +*/ +func (*UserDao) FindUserByName(username string) (*User, error) { + user := User{Name: username} + + result := SqlSession.Where("name = ?", username).First(&user) + err := result.Error + if err != nil { + return nil, err + } + return &user, err +} + +/* +* +根据用户id,查找用户实体 +*/ +func (d *UserDao) FindUserById(id int64) (*User, error) { + user := User{UserId: id} + + result := SqlSession.Where("user_id = ?", id).First(&user) + err := result.Error + if err != nil { + return nil, err + } + return &user, err +} diff --git a/models/video.go b/models/video.go new file mode 100644 index 00000000..0e3ecf4c --- /dev/null +++ b/models/video.go @@ -0,0 +1,73 @@ +package models + +import ( + "fmt" + "sync" + "time" +) + +type Video struct { + VideoId int64 `gorm:"primaryKey"` + UserId int64 + PlayUrl string + CoverUrl string + FavoriteCount int64 + CommentCount int64 + // Title string `gorm:"default:(-)"` + CreateAt time.Time + UpdateAt time.Time + DeleteAt time.Time +} + +type VideoDao struct { +} + +var videoDao *VideoDao +var videoOnce sync.Once //单例模式,只生成一个VideoDao实例,提高性能 + +func NewVideoDaoInstance() *VideoDao { + videoOnce.Do( + func() { + videoDao = &VideoDao{} + }) + return videoDao +} + +/* +* +根据videoid,查找video实体 +*/ +func (d *VideoDao) FindVideoById(id int64) (*Video, error) { + video := Video{VideoId: id} + + result := SqlSession.Where("Video_id = ?", id).First(&video) + err := result.Error + if err != nil { + return nil, err + } + return &video, err +} + +// 根据UserId,查出Video列表 +func (*VideoDao) QueryVideoByUserId(userId int64) ([]*Video, error) { + var videos []*Video + err := SqlSession.Where("user_id = ?", userId).Find(&videos).Error + if err != nil { + fmt.Println("查询Video列表失败") + return nil, err + } + return videos, nil +} + +// 根据时间和需要查询的条数,获取video列表 +func (*VideoDao) QueryVideo(date *string, limit int) []*Video { + fmt.Println(*date) + var VideoList []*Video + SqlSession.Where("create_at < ?", *date).Order("create_at desc").Find(&VideoList) + if len(VideoList) <= limit { + fmt.Println(VideoList) + return VideoList + } + fmt.Println(VideoList) + return VideoList[0:limit] +} diff --git a/resources/application.yaml b/resources/application.yaml new file mode 100644 index 00000000..6e0339df --- /dev/null +++ b/resources/application.yaml @@ -0,0 +1,6 @@ +mysql: + url: 127.0.0.1 + port: 3306 + userName: #your_mysql_userName + password: #your_mysql_passWord + dbname: titok \ No newline at end of file From c4865d95db744f3293d477e86d42970f6014c517 Mon Sep 17 00:00:00 2001 From: icode-Cong Date: Sun, 13 Aug 2023 21:22:55 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E5=B0=86application.yaml=E6=94=BE=E5=85=A5?= =?UTF-8?q?igorne=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 82c4ca1c..d59fbc73 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,6 @@ # Go workspace file go.work -.idea \ No newline at end of file +.idea + +application.yaml \ No newline at end of file From 52e918bf7f298ad295c0515db762cdc459a5475a Mon Sep 17 00:00:00 2001 From: liuyue Date: Mon, 14 Aug 2023 22:53:46 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=86token=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E7=9A=84=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controller/token.go | 35 +++++++++++++++++++++++++++++++++++ go.mod | 2 ++ go.sum | 4 ++++ test/token_test.go | 23 +++++++++++++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 controller/token.go create mode 100644 test/token_test.go diff --git a/controller/token.go b/controller/token.go new file mode 100644 index 00000000..247380fd --- /dev/null +++ b/controller/token.go @@ -0,0 +1,35 @@ +package controller + +import ( + "time" + + "github.com/golang-jwt/jwt/v4" +) + +func GenerateToken(username string) (string, error) { + expireDuration, _ := time.ParseDuration("23h59m59s") + expireTime := time.Now().Add(expireDuration) + claims := jwt.StandardClaims{ + Audience: username, + ExpiresAt: expireTime.Unix(), + IssuedAt: time.Now().Unix(), + Issuer: "tiktok", + NotBefore: time.Now().Unix(), + } + token, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString([]byte("tik tok")) + return token, err +} + +func ParseToken(token string) (string, error) { + tokenClaims, err := jwt.ParseWithClaims(token, &jwt.StandardClaims{}, func(token *jwt.Token) (interface{}, error) { + return []byte("tik tok"), nil + }) + + if err == nil && tokenClaims != nil { + if claims, ok := tokenClaims.Claims.(*jwt.StandardClaims); ok && tokenClaims.Valid { + return claims.Audience, nil + } + } + + return "", err +} diff --git a/go.mod b/go.mod index 6dc316db..aea5438a 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,8 @@ require ( github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/validator/v10 v10.11.0 // indirect github.com/go-sql-driver/mysql v1.5.0 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang-jwt/jwt/v5 v5.0.0 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/gorilla/websocket v1.4.2 // indirect diff --git a/go.sum b/go.sum index 98f7ac76..ebc4ebfc 100644 --- a/go.sum +++ b/go.sum @@ -36,6 +36,10 @@ github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2B github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= +github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= diff --git a/test/token_test.go b/test/token_test.go new file mode 100644 index 00000000..9c9ecbf1 --- /dev/null +++ b/test/token_test.go @@ -0,0 +1,23 @@ +package test + +import ( + "fmt" + "testing" + + "github.com/RaymondCode/simple-demo/controller" +) + +func TestToken(t *testing.T) { + token, err := controller.GenerateToken("user") + if err != nil { + t.Error("GenerateToken error") + } + fmt.Println("token:", token) + username, err := controller.ParseToken(token) + if err != nil { + t.Error("ParseToken error") + } + if username != "user" { + t.Errorf("expect username, but got %s", username) + } +} From 71028380b95f4ff3003ec278a1bec8ce70259de2 Mon Sep 17 00:00:00 2001 From: lazypool <3416382833@qq.com> Date: Tue, 15 Aug 2023 13:01:43 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E5=AE=9E=E7=8E=B0Register=E5=92=8CLogin?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controller/user.go | 102 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 77 insertions(+), 25 deletions(-) diff --git a/controller/user.go b/controller/user.go index 72fc57ec..8cbfd5ba 100644 --- a/controller/user.go +++ b/controller/user.go @@ -1,9 +1,9 @@ package controller import ( + "github.com/RaymondCode/simple-demo/service" "github.com/gin-gonic/gin" "net/http" - "sync/atomic" ) // usersLoginInfo use map to store user info, and key is username+password for demo @@ -21,12 +21,16 @@ var usersLoginInfo = map[string]User{ var userIdSequence = int64(1) -type UserLoginResponse struct { - Response +type UserIdTokenResponse struct { UserId int64 `json:"user_id,omitempty"` Token string `json:"token"` } +type UserRegisterLoginResponse struct { + Response + UserIdTokenResponse +} + type UserResponse struct { Response User User `json:"user"` @@ -36,46 +40,94 @@ func Register(c *gin.Context) { username := c.Query("username") password := c.Query("password") - token := username + password + userIdTokenResponse, err := RegisterService(username, password) - if _, exist := usersLoginInfo[token]; exist { - c.JSON(http.StatusOK, UserLoginResponse{ - Response: Response{StatusCode: 1, StatusMsg: "User already exist"}, + if err != nil { + c.JSON(http.StatusOK, UserRegisterLoginResponse{ + Response: Response{ + StatusCode: 1, + StatusMsg: err.Error(), + }, }) } else { - atomic.AddInt64(&userIdSequence, 1) - newUser := User{ - Id: userIdSequence, - Name: username, - } - usersLoginInfo[token] = newUser - c.JSON(http.StatusOK, UserLoginResponse{ - Response: Response{StatusCode: 0}, - UserId: userIdSequence, - Token: username + password, + c.JSON(http.StatusOK, UserRegisterLoginResponse{ + Response: Response{StatusCode: 0}, + UserIdTokenResponse: userIdTokenResponse, }) } } +func RegisterService(username string, password string) (UserIdTokenResponse, error) { + var userIdTokenResponse = UserIdTokenResponse{} + + err := service.IsUserLegal(username, password) + if err != nil { + return userIdTokenResponse, err + } + + userId, err := service.CreateRegisterUser(username, password) + if err != nil { + return userIdTokenResponse, err + } + + token, err := GenerateToken(username) + if err != nil { + return userIdTokenResponse, err + } + + userIdTokenResponse = UserIdTokenResponse{ + UserId: userId, + Token: token, + } + return userIdTokenResponse, nil +} + func Login(c *gin.Context) { username := c.Query("username") password := c.Query("password") - token := username + password + userIdTokenResponse, err := LoginService(username, password) - if user, exist := usersLoginInfo[token]; exist { - c.JSON(http.StatusOK, UserLoginResponse{ - Response: Response{StatusCode: 0}, - UserId: user.Id, - Token: token, + if err != nil { + c.JSON(http.StatusOK, UserRegisterLoginResponse{ + Response: Response{ + StatusCode: 1, + StatusMsg: err.Error(), + }, }) } else { - c.JSON(http.StatusOK, UserLoginResponse{ - Response: Response{StatusCode: 1, StatusMsg: "User doesn't exist"}, + c.JSON(http.StatusOK, UserRegisterLoginResponse{ + Response: Response{StatusCode: 0}, + UserIdTokenResponse: userIdTokenResponse, }) } } +func LoginService(username string, password string) (UserIdTokenResponse, error) { + var userIdTokenResponse = UserIdTokenResponse{} + + err := service.IsUserLegal(username, password) + if err != nil { + return userIdTokenResponse, err + } + + userId, err := service.FindLoginUser(username, password) + if err != nil { + return userIdTokenResponse, err + } + + token, err := GenerateToken(username) + if err != nil { + return userIdTokenResponse, err + } + + userIdTokenResponse = UserIdTokenResponse{ + UserId: userId, + Token: token, + } + return userIdTokenResponse, nil +} + func UserInfo(c *gin.Context) { token := c.Query("token") From f6e6da2a8ca18b784efc6c1603bb28c5b6e1098f Mon Sep 17 00:00:00 2001 From: lazypool <3416382833@qq.com> Date: Tue, 15 Aug 2023 13:02:09 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- service/common.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 service/common.go diff --git a/service/common.go b/service/common.go new file mode 100644 index 00000000..0a812371 --- /dev/null +++ b/service/common.go @@ -0,0 +1,16 @@ +package service + +import "errors" + +var ( + ErrorUserNameNull = errors.New("用户名为空") + ErrorUserNameExtend = errors.New("用户名长度不符合规范") + ErrorPasswordNull = errors.New("密码为空") + ErrorPasswordLength = errors.New("密码长度不符合规范") + ErrorUserExit = errors.New("用户已存在") + ErrorFullPossibility = errors.New("用户不存在,账号或密码出错") + ErrorNullPointer = errors.New("空指针异常") + ErrorPasswordFalse = errors.New("密码错误") + ErrorRelationExit = errors.New("关注已存在") + ErrorRelationNull = errors.New("关注不存在") +) From b18d1c904a7930c489ad45a08f46e29dcfa7a252 Mon Sep 17 00:00:00 2001 From: lazypool <3416382833@qq.com> Date: Tue, 15 Aug 2023 13:02:34 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E5=AE=9E=E7=8E=B0user=E7=9A=84service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- service/user.go | 83 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 service/user.go diff --git a/service/user.go b/service/user.go new file mode 100644 index 00000000..1336eb96 --- /dev/null +++ b/service/user.go @@ -0,0 +1,83 @@ +package service + +import ( + "github.com/RaymondCode/simple-demo/models" + "golang.org/x/crypto/bcrypt" +) + +const ( + MaxUsernameLength = 32 + MaxPasswordLength = 32 + MinPasswordLength = 6 +) + +func IsUserLegal(username string, password string) error { + if username == "" { + return ErrorUserNameNull + } + if len(username) > MaxUsernameLength { + return ErrorUserNameExtend + } + if password == "" { + return ErrorPasswordNull + } + if len(password) > MaxPasswordLength || len(password) < MinPasswordLength { + return ErrorPasswordLength + } + return nil +} + +func isUserExistByName(username string) bool { + if _, err := models.NewUserDaoInstance().FindUserByName(username); err != nil { + return false + } + return true +} + +func CreateRegisterUser(username string, password string) (int64, error) { + newPassword, _ := HashAndSalt(password) + newUser := models.User{ + Name: username, + Password: newPassword, + } + if isUserExistByName(username) { + return -1, ErrorUserExit + } else { + userId, err := models.NewUserDaoInstance().CreateUser(&newUser) + if err != nil { + panic(err) + } + return userId, err + } +} + +func FindLoginUser(username string, password string) (int64, error) { + login, err := models.NewUserDaoInstance().FindUserByName(username) + if err != nil { + return -1, ErrorFullPossibility + } + if !ComparePasswords(login.Password, password) { + return -1, ErrorPasswordFalse + } + return login.UserId, nil +} + +func HashAndSalt(pwdstr string) (string, error) { + pwd := []byte(pwdstr) + hash, err := bcrypt.GenerateFromPassword(pwd, bcrypt.MinCost) + if err != nil { + return "", err + } + pwdHash := string(hash) + return pwdHash, nil +} + +func ComparePasswords(pwdHash string, pwdPlain string) bool { + hash := []byte(pwdHash) + plain := []byte(pwdPlain) + err := bcrypt.CompareHashAndPassword(hash, plain) + if err != nil { + return false + } + return true +} From 5d761a7c7368589f41971e36fc08b3276622fc05 Mon Sep 17 00:00:00 2001 From: lazypool <3416382833@qq.com> Date: Tue, 15 Aug 2023 13:03:16 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=BE=AA=E7=8E=AF?= =?UTF-8?q?=E5=BC=95=E7=94=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.go | 3 -- service/message.go | 73 ---------------------------------------------- 2 files changed, 76 deletions(-) delete mode 100644 service/message.go diff --git a/main.go b/main.go index 9e2a1852..fe60736a 100644 --- a/main.go +++ b/main.go @@ -2,13 +2,10 @@ package main import ( "github.com/RaymondCode/simple-demo/models" - "github.com/RaymondCode/simple-demo/service" "github.com/gin-gonic/gin" ) func main() { - go service.RunMessageServer() - // 初始化配置,如MySQL等 err := models.InitProject() if err != nil { diff --git a/service/message.go b/service/message.go deleted file mode 100644 index 9ba9cdaf..00000000 --- a/service/message.go +++ /dev/null @@ -1,73 +0,0 @@ -package service - -import ( - "encoding/json" - "fmt" - "github.com/RaymondCode/simple-demo/controller" - "io" - "net" - "sync" -) - -var chatConnMap = sync.Map{} - -func RunMessageServer() { - listen, err := net.Listen("tcp", "127.0.0.1:9090") - if err != nil { - fmt.Printf("Run message sever failed: %v\n", err) - return - } - - for { - conn, err := listen.Accept() - if err != nil { - fmt.Printf("Accept conn failed: %v\n", err) - continue - } - - go process(conn) - } -} - -func process(conn net.Conn) { - defer conn.Close() - - var buf [256]byte - for { - n, err := conn.Read(buf[:]) - if n == 0 { - if err == io.EOF { - break - } - fmt.Printf("Read message failed: %v\n", err) - continue - } - - var event = controller.MessageSendEvent{} - _ = json.Unmarshal(buf[:n], &event) - fmt.Printf("Receive Message:%+v\n", event) - - fromChatKey := fmt.Sprintf("%d_%d", event.UserId, event.ToUserId) - if len(event.MsgContent) == 0 { - chatConnMap.Store(fromChatKey, conn) - continue - } - - toChatKey := fmt.Sprintf("%d_%d", event.ToUserId, event.UserId) - writeConn, exist := chatConnMap.Load(toChatKey) - if !exist { - fmt.Printf("User %d offline\n", event.ToUserId) - continue - } - - pushEvent := controller.MessagePushEvent{ - FromUserId: event.UserId, - MsgContent: event.MsgContent, - } - pushData, _ := json.Marshal(pushEvent) - _, err = writeConn.(net.Conn).Write(pushData) - if err != nil { - fmt.Printf("Push message failed: %v\n", err) - } - } -}