自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go項(xiàng)目實(shí)戰(zhàn)-關(guān)于列表分頁的封裝和簡化

開發(fā) 前端
我們會實(shí)現(xiàn)商品模塊的主要功能接口,在其中會實(shí)際應(yīng)用一下我們在搭建項(xiàng)目定制化的響應(yīng)組件中的Pagination,來簡化分頁查詢相關(guān)的操作,在代碼實(shí)現(xiàn)上也比普通的方式更優(yōu)雅一些。

我們實(shí)現(xiàn)了商品模塊中商品分類相關(guān)的功能,這節(jié)我們繼續(xù)商品模塊的開發(fā)來實(shí)現(xiàn)商品詳細(xì)相關(guān)的功能,這些功能在我們梳理出來的功能用例中,我標(biāo)記了出來。

圖片圖片

從功能用例中我們能看到與商品相關(guān)的主要功能有:

  • 商品列表
  • 商品搜索
  • 商品詳情

我們會實(shí)現(xiàn)商品模塊的主要功能接口,在其中會實(shí)際應(yīng)用一下我們在搭建項(xiàng)目定制化的響應(yīng)組件中的Pagination,來簡化分頁查詢相關(guān)的操作,在代碼實(shí)現(xiàn)上也比普通的方式更優(yōu)雅一些。

商品列表

接下來我們來實(shí)現(xiàn)商品列表功能的接口, 當(dāng)然真正商用級別的購物App,商品列表應(yīng)該是通過 Lucene或者是ElasticSearch來實(shí)現(xiàn)的查找的。我們這里沒有這個硬件條件,就先給大家講一下通過數(shù)據(jù)庫查詢實(shí)現(xiàn)功能的邏輯吧。

在購物網(wǎng)站上,我們點(diǎn)擊每個分類的時候,會展示分類下的商品列表。

這個時候有個內(nèi)部邏輯,商品都是掛在到三級分類上的,也就是分類的葉子節(jié)點(diǎn)上。 那么此時我們開發(fā)功能時要能夠兼顧下面幾點(diǎn):

  • 產(chǎn)品的交互邏輯上可能允許用戶點(diǎn)擊一級或者二級分類查看商品列表。
  • 因不同公司產(chǎn)品邏輯而定,沒有絕對,但是我們的功能實(shí)現(xiàn)時要支持上面的情況,假設(shè)用戶選擇了一級或者二級分類,我們的程序需要先查出下面的三級分類,再通過這些三級分類查找對應(yīng)的商品。

以上是業(yè)務(wù)方面的邏輯,在做本功能的時候我還會演示怎么通過我們之前定義分頁組件Pagination,以一個相對優(yōu)雅的寫法寫數(shù)據(jù)庫的分頁查詢。

在 api/controller/commodity.go 中添加商品列表的Controller方法。

// CommoditiesInCategory 分類商品列表
func CommoditiesInCategory(c *gin.Context) {
 categoryId, _ := strconv.ParseInt(c.Query("category_id"), 10, 64)
 pagination := app.NewPagination(c)

 svc := appservice.NewCommodityAppSvc(c)
 commodityList, err := svc.GetCategoryCommodityList(categoryId, pagination)
if err != nil {
if errors.Is(err, errcode.ErrParams) {
   app.NewResponse(c).Error(errcode.ErrParams)
  } else {
   app.NewResponse(c).Error(errcode.ErrServer.WithCause(err))
  }
return
 }

 app.NewResponse(c).SetPagination(pagination).Success(commodityList)
}

我們在Controller方法中除了從URL查詢字符串上獲取商品的分類ID外,還要獲取分頁相關(guān)的請求參數(shù),用它們創(chuàng)建Pagination對象。Pagination 對象會隨著我們的調(diào)用一直往下傳遞,傳到DomainService中,在需要的時候通過其上的方法來獲取offset 和 limit 等信息。

DomainService 中查詢商品列表的邏輯如下:

// logic/domainservice/commodity.go
// GetCommodityListInCategory 獲取分類下的商品列表
func (cds *CommodityDomainSvc) GetCommodityListInCategory(categoryInfo *do.CommodityCategory, pagination *app.Pagination) ([]*do.Commodity, error) {
 offset := pagination.Offset()
 size := pagination.GetPageSize()

 thirdLevelCategoryIds, err := cds.commodityDao.GetThirdLevelCategories(categoryInfo)
if err != nil {
returnnil, errcode.Wrap("GetCommodityListInCategoryError", err)
 }
 commodityModelList, totalRows, err := cds.commodityDao.GetCommoditiesInCategory(thirdLevelCategoryIds, offset, size)
if err != nil {
returnnil, errcode.Wrap("GetCommodityListInCategoryError", err)
 }
 pagination.SetTotalRows(int(totalRows))

 commodityList := make([]*do.Commodity, 0, len(commodityModelList))
 err = util.CopyProperties(&commodityList, &commodityModelList)
if err != nil {
returnnil, errcode.ErrCoverData.WithCause(err)
 }

return commodityList, nil
}

commodityDao 的 GetThirdLevelCategories 方法就是我們上面說的產(chǎn)品邏輯,拿到一個分類信息后先去獲取一下所有的三級分類。

// GetThirdLevelCategories 查找分類下的所有三級分類ID
func (cd *CommodityDao) GetThirdLevelCategories(categoryInfo *do.CommodityCategory) (categoryIds []int64, err error) {
if categoryInfo.Level == 3 {
return []int64{categoryInfo.ID}, nil
 } elseif categoryInfo.Level == 2 {
  categoryIds, err = cd.getSubCategoryIdList([]int64{categoryInfo.ID})
return
 } elseif categoryInfo.Level == 1 {
var secondCategoryId []int64
  secondCategoryId, err = cd.getSubCategoryIdList([]int64{categoryInfo.ID})
if err != nil {
   return
  }
  categoryIds, err = cd.getSubCategoryIdList(secondCategoryId)
return
 }
return
}

如果分類本身就是三級分類則直接返回,否則還是按照上面說的邏輯把分類下的所有三級分類先找出來。

分頁查詢簡化

查詢商品信息時因?yàn)樾枰猪?,所以我們在CommodityDomainSvc 里先用Pagination獲取分頁數(shù)據(jù)需要的offset 和 limit 參數(shù)。

func (cds *CommodityDomainSvc) GetCommodityListInCategory(categoryInfo *do.CommodityCategory, pagination *app.Pagination) ([]*do.Commodity, error) {
 offset := pagination.Offset()
 size := pagination.GetPageSize()
    .....
    commodityModelList, totalRows, err := cds.commodityDao.GetCommoditiesInCategory(thirdLevelCategoryIds, offset, size)
     if err != nil {
      return nil, errcode.Wrap("GetCommodityListInCategoryError", err)
     }
    pagination.SetTotalRows(int(totalRows))

    ......
}

商品數(shù)據(jù)查詢的Dao方法除了返回商品列表數(shù)據(jù),還會返回滿足條件的總行數(shù),這樣我們把總行數(shù)再設(shè)置到Pagination對象上,因?yàn)镻agination是指針類型,它創(chuàng)建子Controller方法,所以我們在Controller中返回響應(yīng)時直接使用 app.NewResponse(c).SetPagination(pagination) 就能把分頁查詢需要的信息都寫入到響應(yīng)中。

通過這種方式我們能避免需要分頁查詢數(shù)據(jù)的接口對應(yīng)的AppService、DomainService、Dao方法都帶上page、pageSize等參數(shù),只需要在調(diào)用Dao方法查詢數(shù)據(jù)前從Pagination對象對應(yīng)的方法中取出這兩個值即可。同理所有方法的返回值中也不用都帶著totalRow 這個返回值。

責(zé)任編輯:武曉燕 來源: 網(wǎng)管叨bi叨
相關(guān)推薦

2025-04-27 02:22:00

分頁項(xiàng)目開發(fā)

2025-02-10 09:03:29

2024-12-17 09:14:48

項(xiàng)目http 庫API

2025-02-26 09:03:24

2025-01-02 09:02:09

Go項(xiàng)目Token

2022-06-09 10:42:47

GoJSON

2025-03-04 00:00:05

Go項(xiàng)目分類樹

2024-11-13 09:13:45

2025-04-28 01:55:00

工具sqlmockSQL

2022-09-07 09:44:19

loading分頁

2024-11-04 09:02:51

Go項(xiàng)目接口

2025-01-08 09:07:06

2024-12-30 09:12:17

2009-06-04 10:58:15

strutshibernate分頁

2025-03-10 09:07:20

2024-06-20 11:49:52

2024-06-24 08:10:34

Java8表達(dá)式IDE

2020-03-02 00:32:08

Python列表for循環(huán)

2018-11-30 12:11:11

Oracle存儲配置

2024-12-05 09:13:55

Go項(xiàng)目模塊
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號