Go-React做一个todolist(服务端)【一】项目初始化

2024-03-31 04:52

本文主要是介绍Go-React做一个todolist(服务端)【一】项目初始化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

后端仓库地址

地址

项目依赖

# gin
go get -u github.com/gin-gonic/gin
# viper日志
go get -u github.com/spf13/viper
# 数据库和gorm
go get -u gorm.io/driver/mysql
go get -u gorm.io/gorm
# uuid
go get -u github.com/google/uuid
# token
go get -u github.com/golang-jwt/jwt/v5
# 邮箱
go get github.com/jordan-wright/email
# swagger
go get -u github.com/swaggo/swag/cmd/swag
go install github.com/swaggo/swag/cmd/swag@latest
go get -u github.com/swaggo/files
go get -u github.com/swaggo/gin-swagger# base64验证码
go get -u github.com/mojocn/base64Captcha
# gokit 工具集合
go get github.com/songzhibin97/gkit

项目结构搭建

先执行 go mod init ToDoList
在这里插入图片描述

初始化模块

在initialize/index.go中

package initializeimport ("ToDoList/global""fmt"
)func Works() {// 读取配置文件global.GVA_VIPER = Viper()// 初始化缓存组件Cache.InitCache()// 初始化数据库并注册表global.GVA_DB = GormMysql.InitGormMysql()GormMysql.TableInit()// 启动服务global.GVA_SERVER = GinEngine.InitEngine()if global.GVA_SERVER != nil {// 注册中间件GinEngine.InitMiddleware()// 注册路由GinEngine.InitRouter()// 运行服务global.GVA_SERVER.Run(fmt.Sprintf(":%s", global.GVA_CONFIG.App.Port))}
}

在这里插入图片描述

gin初始化

在initialize/gin.go中

package initializeimport ("ToDoList/docs""ToDoList/global""ToDoList/middleware""ToDoList/router""github.com/gin-gonic/gin"swaggerFiles "github.com/swaggo/files"ginSwagger "github.com/swaggo/gin-swagger"
)type ginEngine struct{}// 初始化中间件
func (receiver ginEngine) InitMiddleware() {// cors跨域中间件global.GVA_SERVER.Use(middleware.CorsByRules())// swagger中间件docs.SwaggerInfo.BasePath = global.GVA_CONFIG.App.RouterPrefixglobal.GVA_SERVER.GET(global.GVA_CONFIG.App.RouterPrefix+"/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
}// 初始化路由
func (receiver *ginEngine) InitRouter() {// 全局路由前缀globalRouterGroup := global.GVA_SERVER.Group(global.GVA_CONFIG.App.RouterPrefix)router.UserRouter.InitUserRouter(globalRouterGroup)
}// 初始化Gin引擎
func (receiver *ginEngine) InitEngine() *gin.Engine {r := gin.Default()return r
}var GinEngine = new(ginEngine)

gorm初始化

在initialize/gorm.go中

package initializeimport ("ToDoList/global""ToDoList/model""fmt""gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/logger""gorm.io/gorm/schema""log""os""time"
)type gormMysql struct{}func (receiver *gormMysql) TableInit() {err := global.GVA_DB.AutoMigrate(model.User{},model.Backlog{},)if err != nil {fmt.Println("注册表发生错误:", err)panic("初始化表失败")}fmt.Println("~~~The database table is successfully registered~~~")
}func (receiver *gormMysql) InitGormMysql() *gorm.DB {password := global.GVA_CONFIG.Mysql.Passwordusername := global.GVA_CONFIG.Mysql.Usernameport := global.GVA_CONFIG.Mysql.PortdbName := global.GVA_CONFIG.Mysql.Dbnamedsn := fmt.Sprintf("%s:%s@tcp(127.0.0.1:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", username, password, port, dbName)db, err := gorm.Open(mysql.New(mysql.Config{DSN:                       dsn,   // DSN data source nameDefaultStringSize:         256,   // string 类型字段的默认长度 如果该字段是字符串并作为主键会造成索引超长DisableDatetimePrecision:  true,  // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持DontSupportRenameIndex:    true,  // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引DontSupportRenameColumn:   true,  // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置}), &gorm.Config{ //连接的配置SkipDefaultTransaction: false, // 默认false,增删改都是事务操作来保证数据一致性,能提升一点性能NamingStrategy: schema.NamingStrategy{TablePrefix:         "",    // 如果设置了会给每个表名加前缀SingularTable:       true,  // 单数表名,如果false会在表明后加sNameReplacer:        nil,   // 字符转转换器,转换字段名NoLowerCase:         false, //当设置为true时,NoLowerCase选项将禁用表名和列名的蛇形命名转换。保持表名和列名的原始大小写形式。IdentifierMaxLength: 0,     //不限制数据库标识符(如表名、列名)的最大长度。},Logger: logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), // io writerlogger.Config{SlowThreshold:             time.Second,   // Slow SQL thresholdLogLevel:                  logger.Silent, // Log levelIgnoreRecordNotFoundError: true,          // Ignore ErrRecordNotFound error for loggerParameterizedQueries:      true,          // Don't include params in the SQL logColorful:                  false,         // Disable color},), // 可以自定义日志DisableForeignKeyConstraintWhenMigrating: true, //true时,建表将不会建立物理外键,代码中我们采用逻辑外键提升数据库操作效率})if err != nil {panic(err.Error())}sqlDB, _ := db.DB()sqlDB.SetMaxIdleConns(global.GVA_CONFIG.Mysql.MaxIdleConns)sqlDB.SetMaxOpenConns(global.GVA_CONFIG.Mysql.MaxOpenConns)return db
}var GormMysql = new(gormMysql)

缓存kit初始化

在initialize/cache.go中

package initializeimport ("ToDoList/global""ToDoList/util""github.com/songzhibin97/gkit/cache/local_cache"
)type cache struct{}func (receiver *cache) InitCache() {dr, err := util.BasicUtils.ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime)if err != nil {panic(err)}global.BlackCache = local_cache.NewCache(local_cache.SetDefaultExpire(dr),)
}var Cache = new(cache)

读取配置文件Viper初始化

package initializeimport ("ToDoList/enum""ToDoList/global""flag""fmt""github.com/fsnotify/fsnotify""github.com/gin-gonic/gin""github.com/spf13/viper"
)// Viper //
// 优先级: 命令行 > 环境变量 > 默认值
// Author [SliverHorn](https://github.com/SliverHorn)
func Viper(path ...string) *viper.Viper {var configFile stringif len(path) == 0 {flag.StringVar(&configFile, "c", "", "choose config file.")flag.Parse()if configFile == "" { // 判断命令行参数是否为空switch gin.Mode() {case gin.DebugMode:configFile = enum.ConfigDefaultFilefmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.Mode(), enum.ConfigDebugFile)case gin.ReleaseMode:configFile = enum.ConfigReleaseFilefmt.Printf("您正在使用gin模式的%s环境名称,config的路径为", gin.Mode(), enum.ConfigReleaseFile)case gin.TestMode:configFile = enum.ConfigTestFilefmt.Printf("您正在使用gin模式的%s环境名称,config的路径为%s\n", gin.Mode(), enum.ConfigTestFile)}} else { // 命令行参数不为空 将值赋值于configfmt.Printf("您正在使用命令行的-c参数传递的值,config的路径为%s\n", configFile)}} else { // 函数传递的可变参数的第一个值赋值于configconfigFile = path[0]fmt.Printf("您正在使用func Viper()传递的值,config的路径为%s\n", configFile)}// 初始化Viper對象v := viper.New()// 设置配置文件的路径v.SetConfigFile(configFile)// 配置文件类型v.SetConfigType("yaml")err := v.ReadInConfig()if err != nil {panic(fmt.Errorf("Fatal error config file: %s \n", err))}// 当配置文件变化调用此hookv.OnConfigChange(func(e fsnotify.Event) {fmt.Println("config file changed:", e.Name)if err = v.Unmarshal(&global.GVA_CONFIG); err != nil {fmt.Println(err)}})// 配置文件变动会重读不必重启服务v.WatchConfig()if err = v.Unmarshal(&global.GVA_CONFIG); err != nil {panic(err)}return v
}

模型

用户

package modelimport ("github.com/google/uuid""gorm.io/gorm"
)type User struct {gorm.ModelUsername   string    `json:"userName" gorm:"comment:用户名"`NickName   string    `json:"nickName" gorm:"comment:昵称"`Password   string    `json:"password" gorm:"comment:密码"`Identity   string    `json:"身份" gorm:"comment:用户身份"`Email      string    `json:"email" gorm:"comment:用户邮箱"`UUID       uuid.UUID `json:"uuid" gorm:"index;comment:用户UUID"`Avatar     string    `json:"avatar" gorm:"comment:用户头像;default:https://fancyfish.top/hero.jpg"`ThemeColor string    `json:"themeColor" gorm:"comment:用户主题颜色"`Enable     bool      `json:"enable" gorm:"comment:用户是否可用;default:true"`Backlog    Backlog
}func (receiver User) TableName() string {return "user"
}

待办事项

package modelimport ("gorm.io/gorm"
)type Backlog struct {gorm.ModelBacklogContent  string    `json:"backlogContent" gorm:"comment:代办事项内容"`Completed       bool      `json:"completed" gorm:"comment:是否完成;default:false"`UserId          uint      `json:"user_id"`ParentId        *uint     `json:"parent_id"`ChildrenBacklog []Backlog `gorm:"foreignkey:ParentId;"`
}func (receiver Backlog) TableName() string {return "backlog"
}

路由

package routerimport ("ToDoList/api""github.com/gin-gonic/gin"
)type userRouter struct{}func (receiver userRouter) InitUserRouter(R *gin.RouterGroup) {r := R.Group("user"){r.POST("register", api.UserApi.Register)r.POST("login", api.UserApi.Login)r.POST("change_password", api.UserApi.ChangePassword)r.PUT("set_userinfo", api.UserApi.SetSelfInfo)r.GET("get_userInfo", api.UserApi.GetUserInfo)r.POST("get_captcha", api.UserApi.GetCaptcha)}
}var UserRouter = new(userRouter)

这篇关于Go-React做一个todolist(服务端)【一】项目初始化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/863433

相关文章

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

SpringBoot项目中报错The field screenShot exceeds its maximum permitted size of 1048576 bytes.的问题及解决

《SpringBoot项目中报错ThefieldscreenShotexceedsitsmaximumpermittedsizeof1048576bytes.的问题及解决》这篇文章... 目录项目场景问题描述原因分析解决方案总结项目场景javascript提示:项目相关背景:项目场景:基于Spring

解决Maven项目idea找不到本地仓库jar包问题以及使用mvn install:install-file

《解决Maven项目idea找不到本地仓库jar包问题以及使用mvninstall:install-file》:本文主要介绍解决Maven项目idea找不到本地仓库jar包问题以及使用mvnin... 目录Maven项目idea找不到本地仓库jar包以及使用mvn install:install-file基

springboot项目如何开启https服务

《springboot项目如何开启https服务》:本文主要介绍springboot项目如何开启https服务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录springboot项目开启https服务1. 生成SSL证书密钥库使用keytool生成自签名证书将

HTML5中的Microdata与历史记录管理详解

《HTML5中的Microdata与历史记录管理详解》Microdata作为HTML5新增的一个特性,它允许开发者在HTML文档中添加更多的语义信息,以便于搜索引擎和浏览器更好地理解页面内容,本文将探... 目录html5中的Mijscrodata与历史记录管理背景简介html5中的Microdata使用M

html5的响应式布局的方法示例详解

《html5的响应式布局的方法示例详解》:本文主要介绍了HTML5中使用媒体查询和Flexbox进行响应式布局的方法,简要介绍了CSSGrid布局的基础知识和如何实现自动换行的网格布局,详细内容请阅读本文,希望能对你有所帮助... 一 使用媒体查询响应式布局        使用的参数@media这是常用的

HTML5表格语法格式详解

《HTML5表格语法格式详解》在HTML语法中,表格主要通过table、tr和td3个标签构成,本文通过实例代码讲解HTML5表格语法格式,感兴趣的朋友一起看看吧... 目录一、表格1.表格语法格式2.表格属性 3.例子二、不规则表格1.跨行2.跨列3.例子一、表格在html语法中,表格主要通过< tab

Java数组初始化的五种方式

《Java数组初始化的五种方式》数组是Java中最基础且常用的数据结构之一,其初始化方式多样且各具特点,本文详细讲解Java数组初始化的五种方式,分析其适用场景、优劣势对比及注意事项,帮助避免常见陷阱... 目录1. 静态初始化:简洁但固定代码示例核心特点适用场景注意事项2. 动态初始化:灵活但需手动管理代

将Java项目提交到云服务器的流程步骤

《将Java项目提交到云服务器的流程步骤》所谓将项目提交到云服务器即将你的项目打成一个jar包然后提交到云服务器即可,因此我们需要准备服务器环境为:Linux+JDK+MariDB(MySQL)+Gi... 目录1. 安装 jdk1.1 查看 jdk 版本1.2 下载 jdk2. 安装 mariadb(my

Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n