go18/book/v3/handlers/book.go

181 lines
4.6 KiB
Go
Raw Normal View History

2025-05-11 12:08:25 +08:00
package handlers
import (
"net/http"
"strconv"
"122.51.31.227/go-course/go18/book/v3/config"
2025-05-11 15:09:56 +08:00
"122.51.31.227/go-course/go18/book/v3/controllers"
2025-05-11 12:08:25 +08:00
"122.51.31.227/go-course/go18/book/v3/models"
"github.com/gin-gonic/gin"
)
var Book = &BookApiHandler{}
type BookApiHandler struct {
}
func (h *BookApiHandler) Registry(r gin.IRouter) {
// Book Restful API
// List of books
r.GET("/api/books", h.listBook)
// Create new book
// Body: HTTP Entity
r.POST("/api/books", h.createBook)
// Get book by book number
r.GET("/api/books/:bn", h.getBook)
// Update book
r.PUT("/api/books/:bn", h.updateBook)
// Delete book
r.DELETE("/api/books/:bn", h.deleteBook)
}
// 实现后端分页的
func (h *BookApiHandler) listBook(ctx *gin.Context) {
set := &models.BookSet{}
// List<*Book>
// *Set[T]
// types.New[*Book]()
// 给默认值
pn, ps := 1, 20
// /api/books?page_number=1&page_size=20
pageNumber := ctx.Query("page_number")
if pageNumber != "" {
pnInt, err := strconv.ParseInt(pageNumber, 10, 64)
if err != nil {
ctx.JSON(400, gin.H{"code": 400, "message": err.Error()})
return
}
pn = int(pnInt)
}
pageSize := ctx.Query("page_size")
if pageSize != "" {
psInt, err := strconv.ParseInt(pageSize, 10, 64)
if err != nil {
ctx.JSON(400, gin.H{"code": 400, "message": err.Error()})
return
}
ps = int(psInt)
}
query := config.DB().Model(&models.Book{})
// 关键字过滤
kws := ctx.Query("keywords")
if kws != "" {
// where title like %kws%
query = query.Where("title LIKE ?", "%"+kws+"%")
}
// 其他过滤条件
// select * from books
// 通过sql的offset limte 来实现分页
// offset (page_number -1) * page_size, limit page_size
// 2 offset 20, 20
// 3 offset 40, 20
// 4 offset 3 * 20, 20
offset := (pn - 1) * ps
if err := query.Count(&set.Total).Offset(int(offset)).Limit(int(ps)).Find(&set.Items).Error; err != nil {
ctx.JSON(500, gin.H{"code": 500, "message": err.Error()})
return
}
// 获取总数, 总共多少个, 总共有多少页
ctx.JSON(200, set)
}
func (h *BookApiHandler) createBook(ctx *gin.Context) {
// payload, err := io.ReadAll(ctx.Request.Body)
// if err != nil {
// ctx.JSON(400, gin.H{"code": 400, "message": err.Error()})
// return
// }
// defer ctx.Request.Body.Close()
// // {"title": "Go语言"}
// c.Request.Header.Get(key)
// ctx.GetHeader("Authincation")
// new(Book)
bookSpecInstance := &models.BookSpec{}
// // 通过JSON的 Struct Tag
// // bookInstance.Title = "Go语言"
// if err := json.Unmarshal(payload, bookInstance); err != nil {
// ctx.JSON(400, gin.H{"code": 400, "message": err.Error()})
// return
// }
// 获取到bookInstance
// 参数是不是为空
if err := ctx.BindJSON(bookSpecInstance); err != nil {
ctx.JSON(400, gin.H{"code": 400, "message": err.Error()})
return
}
// 有没有能够检查某个字段是否是必须填
// Gin 集成 validator这个库, 通过 struct tag validate 来表示这个字段是否允许为空
// validate:"required"
// 在数据Bind的时候这个逻辑会自动运行
// if bookSpecInstance.Author == "" {
// ctx.JSON(400, gin.H{"code": 400, "message": err.Error()})
// return
// }
bookInstance := &models.Book{BookSpec: *bookSpecInstance}
// 数据入库(Grom), 补充自增Id的值
if err := config.DB().Save(bookInstance).Error; err != nil {
ctx.JSON(400, gin.H{"code": 500, "message": err.Error()})
return
}
// 返回响应
ctx.JSON(http.StatusCreated, bookInstance)
}
func (h *BookApiHandler) getBook(ctx *gin.Context) {
2025-05-11 15:09:56 +08:00
book, err := controllers.Book.GetBook(ctx, controllers.NewGetBookRequest(ctx.Param("bn")))
if err != nil {
ctx.JSON(400, gin.H{"code": 400, "message": err.Error()})
2025-05-11 12:08:25 +08:00
return
}
2025-05-11 15:09:56 +08:00
ctx.JSON(200, book)
2025-05-11 12:08:25 +08:00
}
func (h *BookApiHandler) updateBook(ctx *gin.Context) {
bnStr := ctx.Param("bn")
bn, err := strconv.ParseInt(bnStr, 10, 64)
if err != nil {
ctx.JSON(400, gin.H{"code": 400, "message": err.Error()})
return
}
// 读取body里面的参数
bookInstance := &models.Book{
Id: uint(bn),
}
// 获取到bookInstance
if err := ctx.BindJSON(&bookInstance.BookSpec); err != nil {
ctx.JSON(400, gin.H{"code": 400, "message": err.Error()})
return
}
if err := config.DB().Where("id = ?", bookInstance.Id).Updates(bookInstance).Error; err != nil {
ctx.JSON(400, gin.H{"code": 400, "message": err.Error()})
return
}
ctx.JSON(200, bookInstance)
}
func (h *BookApiHandler) deleteBook(ctx *gin.Context) {
if err := config.DB().Where("id = ?", ctx.Param("bn")).Delete(&models.Book{}).Error; err != nil {
ctx.JSON(400, gin.H{"code": 400, "message": err.Error()})
return
}
ctx.JSON(http.StatusNoContent, "ok")
}