今天做了文件接口迁移,说白了就是复制黏贴

很想记录一下项目的某个大功能的结构

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
│  init.go

├─dao
│ init.go
│ project.go

├─dto
│ project.go

├─handler
│ project.go

├─model
│ apply.go
│ form.go
│ project.go
│ review.go
│ rule.go
│ workflow.go

├─router
│ project.go

├─service
│ ├─gw
│ │ service.go
│ │
│ └─upload
│ upload.go

└─utils
utils.go

internal/appproject

  • dao

    写一些数据库的操作和初始化

    在这里写的是最底层的代码—基本CRUD的实现

    下面有个很巧妙的初始化形式

    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
    // init.go
    var (
    Project = &project{}
    )

    func InitPG(db *gorm.DB) error {
    err := Project.Init(db)
    if err != nil {
    return err
    }

    return err
    }
    // project.go
    type project struct {
    *gorm.DB
    }

    func (u *project) Init(db *gorm.DB) (err error) {
    u.DB = db
    return db.AutoMigrate(&model.Project{}, &model.ProjectUser{}
    }

    func (u *project) CreateProject(p *model.Project) error {
    return u.DB.Create(p).Error
    }

    func (u *project) DeleteProject(id string) error {
    return u.DB.Where("id = ?", id).Delete(&model.Project{}).Error
    }

    这里使用结构的形式,将直白的*gorm.DB转化为项目私有的形式

    后面再使用方法的形式来调用 u.DB.方法名

    如果是其他包调用就使用dao.Project.方法名

  • dto data transfer object

    数据传输对象

    这个包放置的是数据传入和传出的的对象

    因为对象,所以用结构体表示

    因为传输,所以大多用JSON格式传输

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    type KVMap struct {
    Key string `json:"key"`
    Value string `json:"value"`
    }

    type CreateProjectRequest struct {
    Name string `json:"name" valid:"required"`
    Type string `json:"type" valid:"required"`
    Desc string `json:"desc" valid:"required"`
    }

    type UpdateProjectRequest struct {
    Name string `json:"name" valid:"required"`
    Desc string `json:"desc" valid:"required"`
    Status string `json:"status" valid:"required"`
    }
  • handler

    路由函数的操作

    ​ 这里的函数切记别太长,主要实现的是某个功能,如果这个A功能由其他BCD功能组成,不如把BCD功能拆开来成一个个函数,放入service包中

    ​ 同时,如果这个功能很简单,只有数据库的操作,不妨直接把数据库的操作写在这里,不用特地写到dao包里

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    func HandleProjectList(r flamego.Render, c flamego.Context, auth auth.Info) {
    projectIds := rbac.GetStaffRelatedProjects(auth.StaffId)
    var resp []dto.ProjectListResponse
    err := dao.Project.WithContext(c.Request().Context()).
    Model(&model.Project{}).
    Where("id IN (?)", projectIds).
    Order("created_at desc").
    Find(&resp).Error
    if err != nil {
    response.ServiceErr(r, err)
    return
    }
    response.HTTPSuccess(r, &resp)
    }
  • model

    数据库使用的模型

  • router

    路由

    1
    2
    3
    4
    5
    6
    7
    func AppProjectInit(e *flamego.Flame) {
    e.Group("/project", func() {
    e.Combo("").
    Get(handler.HandleProjectList). // 项目列表
    Post(binding.JSON(dto.CreateProjectRequest{}), handler.HandleCreateProject) // 创建项目

    }

    Combo表示同一页面的不同方法

    同时可以使用Group来分类功能的

  • service

    • gw

      gw是关于网络的包

    这里主要实现的是一些外来的功能接入,比如ParseExcel等。

  • init.go 整个功能的初始化