github.com/chanxuehong/wechat@v0.0.0-20230222024006-36f0325263cd/mp/shakearound/page/search.go (about) 1 package page 2 3 import ( 4 "errors" 5 6 "github.com/chanxuehong/wechat/internal/util" 7 "github.com/chanxuehong/wechat/mp/core" 8 ) 9 10 type SearchQuery struct { 11 Type int `json:"type"` // 查询类型。1: 查询页面id列表中的页面信息;2:分页查询所有页面信息 12 PageIds []int64 `json:"page_ids,omitempty"` // 指定页面的id列表;当type为1时,此项为必填 13 Begin *int `json:"begin,omitempty"` // 页面列表的起始索引值;当type为2时,此项为必填 14 Count *int `json:"count,omitempty"` // 待查询的页面数量,不能超过50个;当type为2时,此项为必填 15 } 16 17 func NewSearchQuery1(pageIds []int64) *SearchQuery { 18 return &SearchQuery{ 19 Type: 1, 20 PageIds: pageIds, 21 } 22 } 23 24 func NewSearchQuery2(begin, count int) *SearchQuery { 25 return &SearchQuery{ 26 Type: 2, 27 Begin: util.Int(begin), 28 Count: util.Int(count), 29 } 30 } 31 32 type SearchResult struct { 33 TotalCount int `json:"total_count"` // 商户名下的页面总数 34 ItemCount int `json:"item_count"` // 查询的页面数量 35 Pages []Page `json:"pages"` // 查询的页面信息列表 36 } 37 38 type Page struct { 39 PageId int64 `json:"page_id"` // 摇周边页面唯一ID 40 Title string `json:"title"` // 在摇一摇页面展示的主标题 41 Description string `json:"description"` // 在摇一摇页面展示的副标题 42 PageURL string `json:"page_url"` // 跳转链接 43 IconURL string `json:"icon_url"` // 在摇一摇页面展示的图片 44 Comment string `json:"comment"` // 页面的备注信息 45 } 46 47 // 查询页面列表. 48 func Search(clt *core.Client, query *SearchQuery) (rslt *SearchResult, err error) { 49 var result struct { 50 core.Error 51 SearchResult `json:"data"` 52 } 53 54 incompleteURL := "https://api.weixin.qq.com/shakearound/page/search?access_token=" 55 if err = clt.PostJSON(incompleteURL, query, &result); err != nil { 56 return 57 } 58 59 if result.ErrCode != core.ErrCodeOK { 60 err = &result.Error 61 return 62 } 63 64 result.SearchResult.ItemCount = len(result.SearchResult.Pages) 65 rslt = &result.SearchResult 66 return 67 } 68 69 // PageIterator 70 // 71 // iter, err := NewPageIterator(*core.Client, *SearchQuery) 72 // if err != nil { 73 // // TODO: 增加你的代码 74 // } 75 // 76 // for iter.HasNext() { 77 // items, err := iter.NextPage() 78 // if err != nil { 79 // // TODO: 增加你的代码 80 // } 81 // // TODO: 增加你的代码 82 // } 83 type PageIterator struct { 84 clt *core.Client 85 86 nextQuery *SearchQuery // 下一次查询参数 87 88 lastSearchResult *SearchResult // 最近一次获取的数据 89 nextPageCalled bool // NextPage() 是否调用过 90 } 91 92 func (iter *PageIterator) TotalCount() int { 93 return iter.lastSearchResult.TotalCount 94 } 95 96 func (iter *PageIterator) HasNext() bool { 97 if !iter.nextPageCalled { // 第一次调用需要特殊对待 98 return iter.lastSearchResult.ItemCount > 0 || 99 *iter.nextQuery.Begin < iter.lastSearchResult.TotalCount 100 } 101 102 return *iter.nextQuery.Begin < iter.lastSearchResult.TotalCount 103 } 104 105 func (iter *PageIterator) NextPage() (pages []Page, err error) { 106 if !iter.nextPageCalled { // 第一次调用需要特殊对待 107 iter.nextPageCalled = true 108 109 pages = iter.lastSearchResult.Pages 110 return 111 } 112 113 rslt, err := Search(iter.clt, iter.nextQuery) 114 if err != nil { 115 return 116 } 117 118 *iter.nextQuery.Begin += rslt.ItemCount 119 iter.lastSearchResult = rslt 120 121 pages = rslt.Pages 122 return 123 } 124 125 func NewPageIterator(clt *core.Client, query *SearchQuery) (iter *PageIterator, err error) { 126 if query.Type != 2 { 127 err = errors.New("Unsupported SearchQuery.Type") 128 return 129 } 130 131 // 逻辑上相当于第一次调用 PageIterator.NextPage, 因为第一次调用 PageIterator.HasNext 需要数据支撑, 所以提前获取了数据 132 133 rslt, err := Search(clt, query) 134 if err != nil { 135 return 136 } 137 138 *query.Begin += rslt.ItemCount 139 140 iter = &PageIterator{ 141 clt: clt, 142 143 nextQuery: query, 144 145 lastSearchResult: rslt, 146 nextPageCalled: false, 147 } 148 return 149 }