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  }