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