跳到主要内容
版本:2.8.x(Latest)

查询单词分页列表使用GET方式,并且提供一些入参:

字段名类型jsonvalid描述
Wordstringjson:"word"length:1,100模糊查询单词
Pageintjson:"page"min:1页码,默认1
Sizeintjson:"size"between:1,100每页数量,默认10

添加Api


首先,我们定义一个结构体保存一个单词的字段。

api/words/v1/words_struct.go

package v1  

import "github.com/gogf/gf/v2/os/gtime"

type List struct {
Id uint `json:"id"`
Word string `json:"word"`
Definition string `json:"definition"`
ProficiencyLevel uint `json:"proficiencyLevel"`
}

ListRes中返回一个List切片,表示单词列表,Total表示所有单词数量,返回给前端方便做分页操作。

api/words/v1/words.go

...

type ListReq struct {
g.Meta `path:"words" method:"get" sm:"列表" tags:"单词"`
Word string `json:"word" v:"length:1,100" dc:"模糊查询单词"`
Page int `json:"page" v:"min:1" dc:"页码,默认1"`
Size int `json:"size" v:"between:1,100" dc:"每页数量,默认10"`
}

type ListRes struct {
List []List `json:"list"`
Total uint `json:"total"`
}

编写Logic


先定义一个Query结构体,用作查询列表入参,严格遵循每一层重新定义数据结构。

internal/model/words.go

...

type WordQuery struct {
Uid uint
Word string
Page int
Size int
}

internal/logic/words/words.go

...

func List(ctx context.Context, query *model.WordQuery) (list []entity.Words, total uint, err error) {
if query == nil {
query = &model.WordQuery{}
}
// 对于查询初始值的处理
if query.Page == 0 {
query.Page = 1
}
if query.Size == 0 {
query.Size = 15
}

// 组成查询链
db := dao.Words.Ctx(ctx)
if query.Uid > 0 {
db = db.Where("uid", query.Uid)
}

// 模糊查询
if len(query.Word) != 0 {
db = db.WhereLike("word", fmt.Sprintf("%%%s%%", query.Word))
}
db = db.Order("created_at desc, id desc").Page(query.Page, query.Size)

data, totalInt, err := db.AllAndCount(true)
if err != nil {
return
}

list = []entity.Words{}
_ = data.Structs(&list)
total = uint(totalInt)

return
}

上述代码用到了db.WhereLike("word", fmt.Sprintf("%%%s%%", query.Word)),它是模糊查询的意思,最终会生成word LIKE '%{word}%' 子句。

AllAndCount用于同时查询数据记录列表及总数量,一般用于分页查询场景中,简化分页查询逻辑。

Controller调用Logic


internal/controller/words/words_v1_list.go

package words  

import (
"context"

"star/api/words/v1"
"star/internal/logic/users"
"star/internal/logic/words"
"star/internal/model"
)

func (c *ControllerV1) List(ctx context.Context, req *v1.ListReq) (res *v1.ListRes, err error) {
uid, err := users.GetUid(ctx)
if err != nil {
return nil, err
}

query := &model.WordQuery{
Uid: uid,
Word: req.Word,
Page: req.Page,
Size: req.Size,
}
wordList, total, err := words.List(ctx, query)
if err != nil {
return nil, err
}

var list []v1.List
for _, v := range wordList {
list = append(list, v1.List{
Id: v.Id,
Word: v.Word,
Definition: v.Definition,
ProficiencyLevel: model.ProficiencyLevel(v.ProficiencyLevel),
})
}

return &v1.ListRes{
List: list,
Total: total,
}, nil
}

接口测试


$ curl -X GET http://127.0.0.1:8000/v1/words \
-H "Authorization: eyJhbGci...5U" \
-H "Content-Type: application/json" \

{
    "code": 0,
    "message": "",
    "data": {
        "list": [
            {
                "id": 1,
                "word": "example_update",
                "definition": "A representative form or pattern.",
                "proficiencyLevel": 3
            }
        ],
        "total": 1
    }
}