github.com/chanxuehong/wechat@v0.0.0-20230222024006-36f0325263cd/mp/shakearound/relation/search.go (about) 1 package relation 2 3 import ( 4 "errors" 5 6 "github.com/chanxuehong/wechat/internal/util" 7 "github.com/chanxuehong/wechat/mp/core" 8 "github.com/chanxuehong/wechat/mp/shakearound/device" 9 ) 10 11 type SearchQuery struct { 12 Type int `json:"type"` // 查询方式。1: 查询设备的关联关系;2:查询页面的关联关系 13 DeviceIdentifier *device.DeviceIdentifier `json:"device_identifier,omitempty"` // 指定的设备;当type为1时,此项为必填 14 PageId *int64 `json:"page_id,omitempty"` // 指定的页面id;当type为2时,此项为必填 15 Begin *int `json:"begin,omitempty"` // 关联关系列表的起始索引值;当type为2时,此项为必填 16 Count *int `json:"count,omitempty"` // 待查询的关联关系数量,不能超过50个;当type为2时,此项为必填 17 } 18 19 func NewSearchQuery1(deviceIdentifier *device.DeviceIdentifier) *SearchQuery { 20 return &SearchQuery{ 21 Type: 1, 22 DeviceIdentifier: deviceIdentifier, 23 } 24 } 25 26 func NewSearchQuery1X(deviceIdentifier *device.DeviceIdentifier, begin, count int) *SearchQuery { 27 return &SearchQuery{ 28 Type: 1, 29 DeviceIdentifier: deviceIdentifier, 30 Begin: util.Int(begin), 31 Count: util.Int(count), 32 } 33 } 34 35 func NewSearchQuery2(pageId int64, begin, count int) *SearchQuery { 36 return &SearchQuery{ 37 Type: 2, 38 PageId: util.Int64(pageId), 39 Begin: util.Int(begin), 40 Count: util.Int(count), 41 } 42 } 43 44 type SearchResult struct { 45 TotalCount int `json:"total_count"` // 设备或页面的关联关系总数 46 ItemCount int `json:"item_count"` // 查询的关联关系数量 47 Relations []Relation `json:"relations"` // 查询的关联关系列表 48 } 49 50 type Relation struct { 51 device.DeviceBase 52 PageId int64 `json:"page_id"` 53 } 54 55 // 查询设备与页面的关联关系. 56 func Search(clt *core.Client, query *SearchQuery) (rslt *SearchResult, err error) { 57 var result struct { 58 core.Error 59 SearchResult `json:"data"` 60 } 61 62 incompleteURL := "https://api.weixin.qq.com/shakearound/relation/search?access_token=" 63 if err = clt.PostJSON(incompleteURL, query, &result); err != nil { 64 return 65 } 66 67 if result.ErrCode != core.ErrCodeOK { 68 err = &result.Error 69 return 70 } 71 72 result.SearchResult.ItemCount = len(result.SearchResult.Relations) 73 rslt = &result.SearchResult 74 return 75 } 76 77 // RelationIterator 78 // 79 // iter, err := NewRelationIterator(*core.Client, *SearchQuery) 80 // if err != nil { 81 // // TODO: 增加你的代码 82 // } 83 // 84 // for iter.HasNext() { 85 // items, err := iter.NextPage() 86 // if err != nil { 87 // // TODO: 增加你的代码 88 // } 89 // // TODO: 增加你的代码 90 // } 91 type RelationIterator struct { 92 clt *core.Client 93 94 nextQuery *SearchQuery // 下一次查询参数 95 96 lastSearchResult *SearchResult // 最近一次获取的数据 97 nextPageCalled bool // NextPage() 是否调用过 98 } 99 100 func (iter *RelationIterator) TotalCount() int { 101 return iter.lastSearchResult.TotalCount 102 } 103 104 func (iter *RelationIterator) HasNext() bool { 105 if !iter.nextPageCalled { // 第一次调用需要特殊对待 106 return iter.lastSearchResult.ItemCount > 0 || 107 *iter.nextQuery.Begin < iter.lastSearchResult.TotalCount 108 } 109 110 return *iter.nextQuery.Begin < iter.lastSearchResult.TotalCount 111 } 112 113 func (iter *RelationIterator) NextPage() (relations []Relation, err error) { 114 if !iter.nextPageCalled { // 第一次调用需要特殊对待 115 iter.nextPageCalled = true 116 117 relations = iter.lastSearchResult.Relations 118 return 119 } 120 121 rslt, err := Search(iter.clt, iter.nextQuery) 122 if err != nil { 123 return 124 } 125 126 *iter.nextQuery.Begin += rslt.ItemCount 127 iter.lastSearchResult = rslt 128 129 relations = rslt.Relations 130 return 131 } 132 133 func NewRelationIterator(clt *core.Client, query *SearchQuery) (iter *RelationIterator, err error) { 134 if query.Begin == nil { 135 err = errors.New("nil SearchQuery.Begin") 136 return 137 } 138 if query.Count == nil { 139 err = errors.New("nil SearchQuery.Count") 140 return 141 } 142 143 // 逻辑上相当于第一次调用 RelationIterator.NextPage, 因为第一次调用 RelationIterator.HasNext 需要数据支撑, 所以提前获取了数据 144 145 rslt, err := Search(clt, query) 146 if err != nil { 147 return 148 } 149 150 *query.Begin += rslt.ItemCount 151 152 iter = &RelationIterator{ 153 clt: clt, 154 155 nextQuery: query, 156 157 lastSearchResult: rslt, 158 nextPageCalled: false, 159 } 160 return 161 }