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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/292105.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pycharm复习

1.基础语法 1.字面量 2.注释: 单行注释# 多行注释" " " " " " 3.变量: 变量名 变量值 print:输出多个结果,用逗号隔开 4.数据类型: string字符串int整数fl…

基于boost准标准库的搜索引擎项目

零 项目背景/原理/技术栈 1.介绍boost准标准库 2.项目实现效果 3.搜索引擎宏观架构图 这是一个基于Web的搜索服务架构 该架构优点: 客户端-服务器模型:采用了经典的客户端-服务器模型,用户通过客户端与服务器交互,有助于集中管理和分散计算…

idea从零开发Android 安卓 (超详细)

首先把所有的要准备的说明一下 idea 2023.1 什么版本也都可以操作都是差不多的 gradle 8.7 什么版本也都可以操作都是差不多的 Android SDK 34KPI 下载地址: AndroidDevTools - Android开发工具 Android SDK下载 Android Studio下载 Gradle下载 SDK Tools下载 …

Node | Node.js 版本升级

目录 Step1:下载 Step2:安装 Step3:换源 发现其他博客说的 n 模块不太行,所以老老实实地手动安装 Step1:下载 Node 中文官网:https://nodejs.cn/download 点击后,将会下载得到一个 .msi 文件…

vue3 视频播放功能整体复盘梳理

回顾工作中对视频的处理,让工作中处理的问题的经验固化成成果,不仅仅是完成任务,还能解答任务的知识点。 遇到的问题 1、如何隐藏下载按钮? video 标签中的controlslist属性是可以用来控制播放器上空间的显示,在原来默…

k8s的pod访问service的方式

背景 在k8s中容器访问某个service服务时有两种方式,一种是把每个要访问的service的ip注入到客户端pod的环境变量中,另一种是客户端pod先通过DNS服务器查找对应service的ip地址,然后在通过这个service ip地址访问对应的service服务 pod客户端…

Hive on Spark 配置

目录 1 Hive 引擎简介2 Hive on Spark 配置2.1 在 Hive 所在节点部署 Spark2.2 在hive中创建spark配置文件2.3 向 HDFS上传Spark纯净版 jar 包2.4 修改hive-site.xml文件2.5 Hive on Spark测试2.6 报错 1 Hive 引擎简介 Hive引擎包括:MR(默认&#xff09…

Mistral 7B v0.2 基础模型开源,大模型微调实践来了

Mistral AI在3月24日突然发布并开源了 Mistral 7B v0.2模型,有如下几个特点: 和上一代Mistral v0.1版本相比,上下文窗口长度从8k提升到32k,上下文窗口(context window)是指语言模型在进行预测或生成文本时&…

竞赛 python+深度学习+opencv实现植物识别算法系统

0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 基于深度学习的植物识别算法研究与实现 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:4分工作量:4分创新点:4分 🧿 更多…

jupyter 设置工作目录

本博客主要介绍: 如何为jupyter设置工作目录 1.打开 anaconda prompt , 执行 jupyter notebook --generate-config 执行这个命令后会生成一个配置文件 2. 打开jupyter_notebook_config.py文件编辑 搜索notebook_dir,把这行代码的注释取消,…

Java学习笔记(23)

多线程 并发 并行 多线程实现方式 1.继承Thread类 自己创建一个类extends thread类 Start方法开启线程,自动执行重写之后的run方法 2.实现runable接口 自己创建一个类implements runnable Myrun不能直接使用getname方法,因为这个方法是thread类的方法…

win11 环境配置 之 Jmeter(JDK17版本)

一、安装 JDK 1. 安装 jdk 截至当前最新时间: 2024.3.27 jdk最新的版本 是 官网下载地址: https://www.oracle.com/java/technologies/downloads/ 建议下载 jdk17 另存为到该电脑的 D 盘下,新建jdk文件夹 开始安装到 jdk 文件夹下 2. 配…

C#基础知识总结

C语言、C和C#的区别 ✔ 面向对象编程(OOP): C 是一种过程化的编程语言,它不直接支持面向对象编程。然而,C 是一种支持 OOP 的 C 的超集,它引入了类、对象、继承、多态等概念。C# 是完全面向对象的&#xff…

neo4j相同查询语句一次查询特慢再次查询比较快。

现象&#xff1a; neo4j相同查询语句一次查询特慢再次查询比较快。 分析&#xff1a; 查询语句 //查询同名方法match(path:Method) where id(path) in [244333030] and NOT path:Constructor//是rpc的方法match(rpc_method:Method)<-[:DECLARES]-(rpc_method_cls:Class) -…

实现ls -l 功能,index,rindex函数的使用

index(); rindex();----------------------------------------------------------------- index第一次遇到字符c&#xff0c;rindex最后一次遇到字符c&#xff0c;返回值都是从那个位置开始往后的字符串地址 #include <stdio.h> #include <sys/types.h> #include &…

【2023】kafka入门学习与使用(kafka-2)

目录&#x1f4bb; 一、基本介绍1、产生背景2、 消息队列介绍2.1、消息队列的本质作用2.2、消息队列的使用场景2.3、消息队列的两种模式2.4、消息队列选型&#xff1a; 二、kafka组件1、核心组件概念2、架构3、基本使用3.1、消费消息3.2、单播和多播消息的实现 4、主题和分区4.…

阿里云2核4G服务器租用价格_30元3个月_165元一年_199元

阿里云2核4G服务器租用优惠价格&#xff0c;轻量2核4G服务器165元一年、u1服务器2核4G5M带宽199元一年、云服务器e实例30元3个月&#xff0c;活动链接 aliyunfuwuqi.com/go/aliyun 活动链接如下图&#xff1a; 阿里云2核4G服务器优惠价格 轻量应用服务器2核2G4M带宽、60GB高效…

智慧城市数字孪生,综合治理一屏统览

现代城市作为一个复杂系统&#xff0c;牵一发而动全身&#xff0c;城市化进程中产生新的矛盾和社会问题都会影响整个城市系统的正常运转。智慧城市是应对这些问题的策略之一。城市工作要树立系统思维&#xff0c;从构成城市诸多要素、结构、功能等方面入手&#xff0c;系统推进…

Python面对对象 - 类的反射机制

Python面对对象类的反射机制是面向对象编程语言中比较重要的功能&#xff0c;可以动态获取对象信息以及动态调用对象。通过字符串形式的类名或属性来访问对应类或属性。 一、对象的反射 1. getattr 获取指定字符串名称的对象属性、方法&#xff1a; 当访问的属性不存在时&#…

微服务(基础篇-007-RabbitMQ)

目录 初识MQ(1) 同步通讯&#xff08;1.1&#xff09; 异步通讯&#xff08;1.2&#xff09; MQ常见框架&#xff08;1.3&#xff09; RabbitMQ快速入门(2) RabbitMQ概述和安装&#xff08;2.1&#xff09; 常见消息模型&#xff08;2.2&#xff09; 快速入门&#xff…