github.com/chanxuehong/wechat@v0.0.0-20230222024006-36f0325263cd/mp/user/list.go (about) 1 package user 2 3 import ( 4 "net/url" 5 6 "github.com/chanxuehong/wechat/mp/core" 7 ) 8 9 // 获取用户列表返回的数据结构 10 type ListResult struct { 11 TotalCount int `json:"total"` // 关注该公众账号的总用户数 12 ItemCount int `json:"count"` // 拉取的OPENID个数, 最大值为10000 13 14 Data struct { 15 OpenIdList []string `json:"openid,omitempty"` 16 } `json:"data"` // 列表数据, OPENID的列表 17 18 // 拉取列表的最后一个用户的OPENID, 如果 next_openid == "" 则表示没有了用户数据 19 NextOpenId string `json:"next_openid"` 20 } 21 22 // List 获取用户列表. 23 // 24 // NOTE: 每次最多能获取 10000 个用户, 可以多次指定 nextOpenId 来获取以满足需求, 如果 nextOpenId == "" 则表示从头获取 25 func List(clt *core.Client, nextOpenId string) (rslt *ListResult, err error) { 26 var incompleteURL string 27 if nextOpenId == "" { 28 incompleteURL = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=" 29 } else { 30 incompleteURL = "https://api.weixin.qq.com/cgi-bin/user/get?next_openid=" + url.QueryEscape(nextOpenId) + "&access_token=" 31 } 32 33 var result struct { 34 core.Error 35 ListResult 36 } 37 if err = clt.GetJSON(incompleteURL, &result); err != nil { 38 return 39 } 40 if result.ErrCode != core.ErrCodeOK { 41 err = &result.Error 42 return 43 } 44 rslt = &result.ListResult 45 return 46 } 47 48 // ===================================================================================================================== 49 50 // UserIterator 51 // 52 // iter, err := NewUserIterator(clt, "NextOpenId") 53 // if err != nil { 54 // // TODO: 增加你的代码 55 // } 56 // 57 // for iter.HasNext() { 58 // openids, err := iter.NextPage() 59 // if err != nil { 60 // // TODO: 增加你的代码 61 // } 62 // // TODO: 增加你的代码 63 // } 64 type UserIterator struct { 65 clt *core.Client 66 67 lastListResult *ListResult 68 nextPageCalled bool 69 } 70 71 func (iter *UserIterator) TotalCount() int { 72 return iter.lastListResult.TotalCount 73 } 74 75 func (iter *UserIterator) HasNext() bool { 76 if !iter.nextPageCalled { 77 return iter.lastListResult.ItemCount > 0 || iter.lastListResult.NextOpenId != "" 78 } 79 return iter.lastListResult.NextOpenId != "" 80 } 81 82 func (iter *UserIterator) NextPage() (openIdList []string, err error) { 83 if !iter.nextPageCalled { 84 iter.nextPageCalled = true 85 openIdList = iter.lastListResult.Data.OpenIdList 86 return 87 } 88 89 rslt, err := List(iter.clt, iter.lastListResult.NextOpenId) 90 if err != nil { 91 return 92 } 93 94 iter.lastListResult = rslt 95 96 openIdList = rslt.Data.OpenIdList 97 return 98 } 99 100 // NewUserIterator 获取用户遍历器, 从 nextOpenId 开始遍历, 如果 nextOpenId == "" 则表示从头遍历. 101 func NewUserIterator(clt *core.Client, nextOpenId string) (iter *UserIterator, err error) { 102 // 逻辑上相当于第一次调用 UserIterator.NextPage, 103 // 因为第一次调用 UserIterator.HasNext 需要数据支撑, 所以提前获取了数据 104 rslt, err := List(clt, nextOpenId) 105 if err != nil { 106 return 107 } 108 109 iter = &UserIterator{ 110 clt: clt, 111 lastListResult: rslt, 112 nextPageCalled: false, 113 } 114 return 115 }