gin项目结构
# gin项目结构
# 01.基础服务封装
# 1.1 目录结构
.
├── Readme.md
├── config // 配置文件
├── controller // CLD:服务入口,负责处理路由、参数校验、请求转发
├── service // CLD:逻辑(服务)层,负责业务逻辑处理
├── dao // CLD:负责数据与存储相关功能(mysql、redis、ES等)
│ ├── mysql
│ └── redis
├── model // 模型
├── logging // 日志处理
├── main.go // 项目启动入口
├── middleware // 中间件
├── pkg // 公共服务
├── router // 路由
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1.2 main.go
package main
import (
setting "bamboo.com/pipeline/Go-assault-squad/config"
"bamboo.com/pipeline/Go-assault-squad/dao/mysql"
"bamboo.com/pipeline/Go-assault-squad/dao/redis"
log "bamboo.com/pipeline/Go-assault-squad/logging"
"bamboo.com/pipeline/Go-assault-squad/pkg/jobs"
"bamboo.com/pipeline/Go-assault-squad/router"
"fmt"
"os"
)
func main() {
if len(os.Args) < 2 {
fmt.Println("need config file.eg: config.yaml")
return
}
// 1.加载配置
setting.Init(os.Args[1])
// 2.初始化日志
log.Init()
// 3.初始化mysql
mysql.Init(setting.Conf.MySQLConfig);
// 4.如果参数为 migrate就初始化表结构
if len(os.Args) >= 3 && os.Args[2] == "migrate" {
mysql.AutoMigrateDB()
fmt.Println("run AutoMigrate success!")
return
}
// 5.初始化redis
redis.Init(setting.Conf.RedisConfig);
// 6.初始化定时任务
jobs.InitJobs()
// 7.注册路由
r := router.InitRouter()
r.Run(fmt.Sprintf(":%d", setting.Conf.Port))
}
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
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
# 1.3 middleware/auth.go
package middleware
import (
"bamboo.com/pipeline/Go-assault-squad/controller"
"github.com/gin-gonic/gin"
)
// JWTAuthMiddleware 基于JWT的认证中间件
func AuthMiddleware() func(c *gin.Context) {
return func(c *gin.Context) {
// 客户端携带Token有三种方式 1.放在请求头 2.放在请求体 3.放在URI
// token验证成功,返回c.Next继续,否则返回c.Abort()直接返回
authHeader := c.Request.Header.Get("Authorization")
if authHeader == "" {
controller.ResponseError(c, controller.CodeNeedLogin)
c.Abort()
return
}
// 将当前请求的userID信息保存到请求的上下文c上
//c.Set(controller.CtxUserIDKey, mc.UserID)
c.Next() // 后续的处理请求的函数中 可以用过c.Get(CtxUserIDKey) 来获取当前请求的用户信息
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1.4 middleware/logger_mw.go
package middleware
import (
"fmt"
"github.com/gin-gonic/gin"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
"github.com/rifflock/lfshook"
"github.com/sirupsen/logrus"
"os"
"path"
"time"
)
var (
logFilePath = "./"
logFileName = "system.log"
)
func LoggerMiddleware() gin.HandlerFunc {
// 日志文件
fileName := path.Join(logFilePath, logFileName)
// 写入文件
src, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err != nil {
fmt.Println("err", err)
}
// 实例化
logger := logrus.New()
//设置日志级别
logger.SetLevel(logrus.DebugLevel)
//设置输出
logger.Out = src
// 设置 rotatelogs
logWriter, err := rotatelogs.New(
// 分割后的文件名称
fileName+".%Y%m%d.log",
// 生成软链,指向最新日志文件
rotatelogs.WithLinkName(fileName),
// 设置最大保存时间(7天)
rotatelogs.WithMaxAge(7*24*time.Hour),
// 设置日志切割时间间隔(1天)
rotatelogs.WithRotationTime(24*time.Hour),
)
writeMap := lfshook.WriterMap{
logrus.InfoLevel: logWriter,
logrus.FatalLevel: logWriter,
logrus.DebugLevel: logWriter,
logrus.WarnLevel: logWriter,
logrus.ErrorLevel: logWriter,
logrus.PanicLevel: logWriter,
}
logger.AddHook(lfshook.NewHook(writeMap, &logrus.JSONFormatter{
TimestampFormat: "2006-01-02 15:04:05",
}))
return func(c *gin.Context) {
//开始时间
startTime := time.Now()
//处理请求
c.Next()
//结束时间
endTime := time.Now()
// 执行时间
latencyTime := endTime.Sub(startTime)
//请求方式
reqMethod := c.Request.Method
//请求路由
reqUrl := c.Request.RequestURI
//状态码
statusCode := c.Writer.Status()
//请求ip
clientIP := c.ClientIP()
// 日志格式
logger.WithFields(logrus.Fields{
"status_code": statusCode,
"latency_time": latencyTime,
"client_ip": clientIP,
"req_method": reqMethod,
"req_uri": reqUrl,
}).Info()
}
}
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# 02.加载配置
# 2.1 config/config.local.yaml
mode: "dev"
#mode: "release"
port: 8084
log:
level: "info"
web_log_name: "web.log"
log_file_path: "./log/"
mysql:
host: 127.0.0.1
port: 3306
user: "root"
password: "1"
dbname: "gindb"
max_open_conns: 200
max_idle_conns: 50
redis:
host: 127.0.0.1
port: 6379
password: ""
db: 0
pool_size: 100
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2.2 config/settings.go
package config
import (
"fmt"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
)
var Conf = new(AppConfig)
type AppConfig struct {
Mode string `mapstructure:"mode"`
Port int `mapstructure:"port"`
*LogConfig `mapstructure:"log"`
*MySQLConfig `mapstructure:"mysql"`
*RedisConfig `mapstructure:"redis"`
}
type LogConfig struct {
Level string `mapstructure:"level"`
WebLogName string `mapstructure:"web_log_name"`
LogFilePath string `mapstructure:"log_file_path"`
}
type MySQLConfig struct {
Host string `mapstructure:"host"`
User string `mapstructure:"user"`
Password string `mapstructure:"password"`
DB string `mapstructure:"dbname"`
Port int `mapstructure:"port"`
MaxOpenConns int `mapstructure:"max_open_conns"`
MaxIdleConns int `mapstructure:"max_idle_conns"`
}
type RedisConfig struct {
Host string `mapstructure:"host"`
Password string `mapstructure:"password"`
Port int `mapstructure:"port"`
DB int `mapstructure:"db"`
PoolSize int `mapstructure:"pool_size"`
MinIdleConns int `mapstructure:"min_idle_conns"`
}
var (
devFilePath string = "./config/config.dev.yaml"
releaseFilePath string = "./config/config.dev.yaml"
localFilePath string = "./config/config.local.yaml"
)
func Init(mode string) {
var filePath string
if mode == "dev" {
filePath = devFilePath
}else if mode == "release" {
filePath = releaseFilePath
}else { // local
filePath = localFilePath
}
fmt.Println()
viper.SetConfigFile(filePath)
err := viper.ReadInConfig() // 读取配置信息
if err != nil {
// 读取配置信息失败
panic(fmt.Sprintf("viper.ReadInConfig failed, err:%v\n", err))
}
// 把读取到的配置信息反序列化到 Conf 变量中
if err := viper.Unmarshal(Conf); err != nil {
fmt.Printf("viper.Unmarshal failed, err:%v\n", err)
}
viper.WatchConfig()
viper.OnConfigChange(func(in fsnotify.Event) {
fmt.Println("配置文件修改了...")
if err := viper.Unmarshal(Conf); err != nil {
panic(fmt.Sprintf("viper.Unmarshal failed, err:%v\n", err))
}
})
}
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
77
78
79
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
77
78
79
# 03.初始化日志
# 3.1 logging/logger.go
package logging
import (
setting "bamboo.com/pipeline/Go-assault-squad/config"
"fmt"
"github.com/sirupsen/logrus"
"os"
)
var WebLog *logrus.Logger
func Init() {
initWebLog()
}
func initWebLog() {
WebLog = initLog(setting.Conf.LogConfig.WebLogName)
}
// 初始化日志句柄
func initLog(logFileName string) *logrus.Logger{
log := logrus.New()
log.Formatter = &logrus.JSONFormatter{
TimestampFormat: "2006-01-02 15:04:05",
}
logFilePath := setting.Conf.LogFilePath
logName := logFilePath + logFileName
var f *os.File
var err error
//判断日志文件夹是否存在,不存在则创建
if _, err := os.Stat(logFilePath); os.IsNotExist(err) {
os.MkdirAll(logFilePath, os.ModePerm)
}
//判断日志文件是否存在,不存在则创建,否则就直接打开
if _, err := os.Stat(logName); os.IsNotExist(err) {
f, err = os.Create(logName)
} else {
f, err = os.OpenFile(logName,os.O_APPEND|os.O_WRONLY, os.ModeAppend)
}
if err != nil {
fmt.Println("open log file failed")
}
log.Out = f
log.Level = logrus.InfoLevel
return log
}
/*
---- 日志写入测试 ----
WebLog.WithFields(logrus.Fields{
"data" : "访问/hello",
}).Info("测试写入info")
---- 写入结构如下 ----
{"data":"访问/hello","level":"info","msg":"测试写入info","time":"2021-12-29 18:15:54"}
*/
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
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
# 04.初始化mysql
# 4.1 dao/mysql/mysql.go
package mysql
import (
"database/sql"
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
setting "bamboo.com/pipeline/Go-assault-squad/config"
)
var DBConn *gorm.DB
func Init(cfg *setting.MySQLConfig) {
dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
cfg.User, cfg.Password, cfg.Host, cfg.DB)
sqlDB, err := sql.Open("mysql", dsn)
if err != nil {
panic(fmt.Sprintf("sql.Open err, \v", err))
}
sqlDB.SetMaxOpenConns(cfg.MaxOpenConns) //最大连接数
sqlDB.SetMaxOpenConns(cfg.MaxIdleConns)
gormDB, err := gorm.Open(mysql.New(mysql.Config{
Conn: sqlDB,
}), &gorm.Config{
DisableForeignKeyConstraintWhenMigrating: true, //禁用外键生成
})
if err != nil {
panic(fmt.Sprintf("链接数据库失败\v", err))
}
DBConn = gormDB
}
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
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
# 4.2 dao/mysql/auto_migrate.go
- 迁移表结构
package mysql
import "bamboo.com/pipeline/Go-assault-squad/model"
func AutoMigrateDB() {
DBConn.AutoMigrate(
&model.Pipeline{},
&model.PipelineStatus{},
)
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 05.初始化redis
# 5.1 dao/redis/redis.go
package redis
import (
setting "bamboo.com/pipeline/Go-assault-squad/config"
"fmt"
"github.com/go-redis/redis"
)
var (
RedisClient *redis.Client
Nil = redis.Nil
)
// Init 初始化连接
func Init(cfg *setting.RedisConfig) {
RedisClient = redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%d", cfg.Host, cfg.Port),
Password: cfg.Password, // no password set
DB: cfg.DB, // use default DB
PoolSize: cfg.PoolSize,
MinIdleConns: cfg.MinIdleConns,
})
_, err := RedisClient.Ping().Result()
if err != nil {
panic(fmt.Sprintf("redis connect err, \v", err))
}
}
func Close() {
_ = RedisClient.Close()
}
/*
---- 测试写入和获取字符串 ----
RedisClient.Set("username", "zhangsan", 0).Err()
username, _ := RedisClient.Get("username").Result()
fmt.Println(username) // zhangsan
*/
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
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
# 06.定时任务
# 6.1 pkg/jobs/cron.go
package jobs
import (
"github.com/robfig/cron"
)
var mainCron *cron.Cron
func init() {
mainCron = cron.New()
mainCron.Start()
}
func InitJobs() {
// 每5s钟调度一次,并传参
mainCron.AddJob(
"*/50 * * * * ?",
TestJob{Id: 1, Name: "zhangsan"},
)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 6.2 pkg/jobs/test_task.go
package jobs
import "fmt"
type TestJob struct {
Id int
Name string
}
func (this TestJob) Run() {
fmt.Println(this.Id, this.Name)
fmt.Println("testJob1...")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 07.注册路由
# 7.1 router/init_router.go
package router
import (
"github.com/gin-gonic/gin"
)
func InitRouter() *gin.Engine {
r := gin.Default()
//r.Use(middleware.LoggerMiddleware())
SetupApiRouters(r)
return r
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 7.2 router/api_router.go
package router
import (
"bamboo.com/pipeline/Go-assault-squad/controller"
"github.com/gin-gonic/gin"
)
func SetupApiRouters(r *gin.Engine) {
v1 := r.Group("/api/v1")
//v1.Use(middleware.AuthMiddleware())
v1.GET("pipeline/:id", controller.GetPipelineDetailHandler)
v1.GET("pipeline", controller.GetPipelineListHandler)
v1.POST("pipeline", controller.CreatePipelineHandler)
v1.PUT("pipeline", controller.UpdatePipelineHandler)
v1.DELETE("pipeline/:id", controller.DeletePipelineHandler)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 08.CLD分层处理
# 8.1 C: controller/pipeline.go
package controller
import (
"bamboo.com/pipeline/Go-assault-squad/model"
"bamboo.com/pipeline/Go-assault-squad/service"
"github.com/gin-gonic/gin"
"strconv"
)
//获取pipeline详情
func GetPipelineDetailHandler(c *gin.Context) {
// pipelineIdStr := c.Query("pipeline_id")
// pipelineIdStr := c.DefaultQuery("pipeline_id", "")
pipelineIdStr := c.Param("id") // 获取URL参数
pipelineId, err := strconv.ParseInt(pipelineIdStr, 10, 64)
if err != nil {
ResponseError(c, CodeInvalidParam)
}
// 查数据库
data, err := service.GetPipelineById(pipelineId)
if err != nil {
ResponseError(c, CodeServerBusy)
return
}
ResponseSuccess(c, data)
}
//创建pipeline数据
func CreatePipelineHandler(c *gin.Context) {
p := new(model.Pipeline)
if err := c.ShouldBindJSON(p); err != nil {
ResponseError(c, CodeInvalidParam)
return
}
if err := service.CreatePipeline(p); err != nil {
ResponseError(c, CodeServerBusy)
return
}
ResponseSuccess(c, nil)
}
//获取pipeline列表信息
func GetPipelineListHandler(c *gin.Context) {
page, size := GetPageInfo(c) // 获取分页参数
data, err := service.GetPipelineList(page, size)
if err != nil {
ResponseError(c, CodeServerBusy)
return
}
ResponseSuccess(c, data)
}
//修改pipeline信息
func UpdatePipelineHandler(c *gin.Context) {
p := new(model.ParamPipeline)
if err := c.ShouldBindJSON(p); err != nil {
ResponseError(c, CodeInvalidParam)
return
}
if err := service.UpdatePipeline(p); err != nil {
ResponseError(c, CodeServerBusy)
return
}
ResponseSuccess(c, nil)
}
//删除指定pipeline_id
func DeletePipelineHandler(c *gin.Context) {
pipelineIdStr := c.Param("id") // 获取URL参数
pipelineId, err := strconv.ParseInt(pipelineIdStr, 10, 64)
if err != nil {
ResponseError(c, CodeInvalidParam)
}
if service.DeletePipelineById(pipelineId) != nil {
ResponseError(c, CodeServerBusy)
return
}
ResponseSuccess(c, nil)
}
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
77
78
79
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
77
78
79
# 8.2 L: service/pipeline.go
package controller
import (
"bamboo.com/pipeline/Go-assault-squad/model"
"bamboo.com/pipeline/Go-assault-squad/service"
"github.com/gin-gonic/gin"
"strconv"
)
//获取pipeline详情
func GetPipelineDetailHandler(c *gin.Context) {
// pipelineIdStr := c.Query("pipeline_id")
// pipelineIdStr := c.DefaultQuery("pipeline_id", "")
pipelineIdStr := c.Param("id") // 获取URL参数
pipelineId, err := strconv.ParseInt(pipelineIdStr, 10, 64)
if err != nil {
ResponseError(c, CodeInvalidParam)
}
// 查数据库
data, err := service.GetPipelineById(pipelineId)
if err != nil {
ResponseError(c, CodeServerBusy)
return
}
ResponseSuccess(c, data)
}
//创建pipeline数据
func CreatePipelineHandler(c *gin.Context) {
p := new(model.Pipeline)
if err := c.ShouldBindJSON(p); err != nil {
ResponseError(c, CodeInvalidParam)
return
}
if err := service.CreatePipeline(p); err != nil {
ResponseError(c, CodeServerBusy)
return
}
ResponseSuccess(c, nil)
}
//获取pipeline列表信息
func GetPipelineListHandler(c *gin.Context) {
page, size := GetPageInfo(c) // 获取分页参数
data, err := service.GetPipelineList(page, size)
if err != nil {
ResponseError(c, CodeServerBusy)
return
}
ResponseSuccess(c, data)
}
//修改pipeline信息
func UpdatePipelineHandler(c *gin.Context) {
p := new(model.ParamPipeline)
if err := c.ShouldBindJSON(p); err != nil {
ResponseError(c, CodeInvalidParam)
return
}
if err := service.UpdatePipeline(p); err != nil {
ResponseError(c, CodeServerBusy)
return
}
ResponseSuccess(c, nil)
}
//删除指定pipeline_id
func DeletePipelineHandler(c *gin.Context) {
pipelineIdStr := c.Param("id") // 获取URL参数
pipelineId, err := strconv.ParseInt(pipelineIdStr, 10, 64)
if err != nil {
ResponseError(c, CodeInvalidParam)
}
if service.DeletePipelineById(pipelineId) != nil {
ResponseError(c, CodeServerBusy)
return
}
ResponseSuccess(c, nil)
}
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
77
78
79
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
77
78
79
# 8.3 D: dao/mysql/pipeline.go
package mysql
import "bamboo.com/pipeline/Go-assault-squad/model"
// 获取pipeline详情,根据id
func GetPipelineById(pipelineId int64) (pipeline *model.Pipeline, err error) {
pipeline = &model.Pipeline{Id: pipelineId}
err = DBConn.First(&pipeline).Error
return
}
// 获取匹pipeline状态
func GetPipelineStatusById(pipelineId int64) (pipeline_status *model.PipelineStatus, err error) {
// 获取pipeline_status信息
pipeline_status = &model.PipelineStatus{Id: pipelineId}
err = DBConn.First(&pipeline_status).Error
return
}
// 创建pipeline
func CreatePipeline(p *model.Pipeline) (err error) {
err = DBConn.Create(p).Error
return
}
// 获取pipeline列表
func GetPipelineList(page, size int) (pipelines []*model.Pipeline, err error) {
pipelines = []*model.Pipeline{}
err = DBConn.Limit( size ).Offset( (page-1) * size ).Find(&pipelines).Error
return
}
// 更新pipeline信息:PipelineId、Name
func UpdatePipeline(p *model.ParamPipeline) (err error) {
oldPipeline := &model.Pipeline{Id: p.Id}
newPipeline := &model.Pipeline{Id: p.Id, PipelineId: p.PipelineId, Name: p.Name}
err = DBConn.Model(&oldPipeline).Updates(newPipeline).Error
return
}
// 删除流水线信息根据:PipelineId
func DeletePipelineById(pipelineId int64) (err error) {
pipeline := &model.Pipeline{Id: pipelineId}
err = DBConn.Delete(&pipeline).Error
return
}
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
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
# 09.model
# 9.1 model/pipeline.go
package model
type Pipeline struct {
Id int64 `gorm:"primary_key" json:"id"`
Status int64 `json:"status"`
PipelineId int `gorm:"not null" json:"pipeline_id" binding:"required"`
Name string `gorm:"size:100;not null" json:"name" binding:"required"` //设置字段的大小为255个字节
Desc string `json:"desc"`
StatusName string `gorm:"-" json:"status_name"`
}
func (Pipeline) TableName() string {
return "pipeline"
}
//修改pipeline时携带参数
type ParamPipeline struct {
Id int64 `json:"id" binding:"required"`
PipelineId int `json:"pipeline_id" binding:"required"`
Name string `json:"name" binding:"required"`
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 9.2 model/pipeline_status.go
package model
type PipelineStatus struct {
Id int64 `gorm:"primary_key"`
Status string
}
func (PipelineStatus) TableName() string {
return "pipeline_status"
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 10.Restful返回
# 10.1 controller/code.go
package controller
type ResCode int64
const (
CodeSuccess ResCode = 1000
CodeInvalidParam ResCode = 1001
CodeUserExist ResCode = 1002
CodeUserNotExist ResCode = 1003
CodeInvalidPassword ResCode = 1004
CodeServerBusy ResCode = 1005
CodeNeedLogin ResCode = 1006
CodeInvalidToken ResCode = 1007
)
var codeMsgMap = map[ResCode]string{
CodeSuccess: "success",
CodeInvalidParam: "请求参数错误",
CodeUserExist: "用户名已存在",
CodeUserNotExist: "用户名不存在",
CodeInvalidPassword: "用户名或密码错误",
CodeServerBusy: "服务繁忙",
CodeNeedLogin: "需要登录",
CodeInvalidToken: "无效的token",
}
func (c ResCode) Msg() string {
msg, ok := codeMsgMap[c]
if !ok {
msg = codeMsgMap[CodeServerBusy]
}
return msg
}
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
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
# 10.2 controller/response.go
package controller
import (
"github.com/gin-gonic/gin"
"net/http"
)
/*
{
"code": 10000, // 程序中的错误码
"msg": xx, // 提示信息
"data": {}, // 数据
}
*/
type ResponseData struct {
Code ResCode `json:"code"`
Msg interface{} `json:"msg"`
Data interface{} `json:"data,omitempty"`
}
func ResponseError(c *gin.Context, code ResCode) {
c.JSON(http.StatusOK, &ResponseData{
Code: code,
Msg: code.Msg(),
Data: nil,
})
}
func ResponseErrorWithMsg(c *gin.Context, code ResCode, msg interface{}) {
c.JSON(http.StatusOK, &ResponseData{
Code: code,
Msg: msg,
Data: nil,
})
}
func ResponseSuccess(c *gin.Context, data interface{}) {
c.JSON(http.StatusOK, &ResponseData{
Code: CodeSuccess,
Msg: CodeSuccess.Msg(),
Data: data,
})
}
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
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
# 10.3 controller/request.go分页
package controller
import (
"github.com/gin-gonic/gin"
"strconv"
)
func GetPageInfo(c *gin.Context) (int, int) {
pageStr := c.DefaultQuery("page", "1")
sizeStr := c.DefaultQuery("size", "10")
var (
page int
size int
err error
)
page, err = strconv.Atoi(pageStr)
if err != nil {
page = 1
}
size, err = strconv.Atoi(sizeStr)
if err != nil {
size = 10
}
return page, size
}
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
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
上次更新: 2022/06/29, 00:08:43