概述

本项目来源于Qimi老师的小清单项目——基于gin+gorm开发的练手小项目,通过该项目可初识go web开发该有的姿势。笔者对代码有些许修改,以下是项目成功运行的截图,主要功能有添加,删除,确认,查看待办事项等(所以是小项目啦~)

项目结构树

这个项目虽然比较小,但是还是可以用企业级代码结构去划分,以下是项目结构树:

1
2
3
4
5
6
7
8
9
├─controllers
├─dao
├─models
├─routers
├─static
│ ├─css
│ ├─fonts
│ └─js
└─template


划分项目结构,利于代码组织和可维护,也有利于团队协作。

后端源码

main.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import (
"bubble/dao"
"bubble/models"
"bubble/routers"
)

func main() {

err := dao.InitMySQL()
if err != nil {
panic(err)
}

err = dao.DB.AutoMigrate(&models.Todo{})
if err != nil {
panic(err)
}
r := routers.SetupRouter()
err = r.Run()
if err != nil {
panic(err)
}
}

controller.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package controllers

import (
"bubble/models"
"github.com/gin-gonic/gin"
"net/http"
)

//url -->controller -->logic -->model
//请求来了 -->控制器 -->业务逻辑 -->模型层的增删改查

func IndexHandler(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", nil)

}

func CreateTodo(c *gin.Context) {
var todo models.Todo
err := c.BindJSON(&todo)
if err != nil {
panic(err)
}
if err := models.CTodo(&todo); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, gin.H{
"code": 200,
"msg": "success",
"data": todo,
})
}
}

func GetTodo(c *gin.Context) {

if todoList, err := models.GTodo(); err != nil {
c.JSON(http.StatusBadRequest, err.Error())
} else {
c.JSON(http.StatusOK, todoList)
}
}

func UpdateTodo(c *gin.Context) {
id, ok := c.Params.Get("id")
if !ok {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的id"})
return
}
todo, err := models.UTodo(id)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
err = c.BindJSON(&todo)
if err != nil {
panic(err)
}
if err = models.STodo(todo); err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, todo)
}
}

func DeleteTodo(c *gin.Context) {
id, ok := c.Params.Get("id")
if !ok {
c.JSON(http.StatusOK, gin.H{"error": "无效的id"})
return
}
if err := models.DTodo(id); err != nil {
c.JSON(http.StatusOK, gin.H{"error": err.Error()})
} else {
c.JSON(http.StatusOK, gin.H{id: "deleted"})
}
}

mysql.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package dao

import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)

var DB *gorm.DB

func InitMySQL() (err error) {
dsn := "root:@tcp(127.0.0.1:3306)/bubble?charset=utf8mb4&parseTime=True&loc=Local"
DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
return err
}

todo.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package models

import (
"bubble/dao"
)

// Todo Model
type Todo struct {
ID int `json:"id"`
Title string `json:"title"`
Status bool `json:"status"`
}

//Todo 增删改查

// CTodo 创建todo
func CTodo(todo *Todo) (err error) {
if err = dao.DB.Create(&todo).Error; err != nil {
return err
}
return
}

// GTodo 查询todo
func GTodo() (todoList []*Todo, err error) {
err = dao.DB.Find(&todoList).Error
return
}

func UTodo(id string) (todo *Todo, err error) {
if err := dao.DB.Where("id=?", id).First(&todo).Error; err != nil {
return nil, err
}
return
}

func STodo(todo *Todo) (err error) {
err = dao.DB.Save(&todo).Error
return
}

func DTodo(id string) (err error) {
err = dao.DB.Where("id=?", id).Delete(&Todo{}).Error
return
}

routers.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package routers

import (
"bubble/controllers"
"github.com/gin-gonic/gin"
)

func SetupRouter() *gin.Engine {
r := gin.Default()
r.Static("/static", "static")
r.LoadHTMLGlob("template/*")
r.GET("/", controllers.IndexHandler)

v1Group := r.Group("/v1")
{
v1Group.POST("/todo", controllers.CreateTodo)

v1Group.GET("todo/", controllers.GetTodo)

v1Group.PUT("todo/:id", controllers.UpdateTodo)

v1Group.DELETE("todo/:id", controllers.DeleteTodo)
}

return r
}

学习使用

前后端所有源码都已经上传至我的资源里:https://download.csdn.net/download/m0_63230155/88064315?spm=1001.2014.3001.5503,供其他小伙伴学习使用,这个是免费下载的!