github.com/chanxuehong/wechat@v0.0.0-20230222024006-36f0325263cd/mp/shakearound/device/search.go (about)

     1  package device
     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:分页查询所有设备信息;3:分页查询某次申请的所有设备信息
    12  	DeviceIdentifiers []*DeviceIdentifier `json:"device_identifiers,omitempty"` // 指定的设备 ; 当type为1时,此项为必填
    13  	ApplyId           *int64              `json:"apply_id,omitempty"`           // 批次ID,申请设备ID时所返回的批次ID;当type为3时,此项为必填
    14  	Begin             *int                `json:"begin,omitempty"`              // 设备列表的起始索引值
    15  	Count             *int                `json:"count,omitempty"`              // 待查询的设备数量,不能超过50个
    16  }
    17  
    18  func NewSearchQuery1(deviceIdentifiers []*DeviceIdentifier) *SearchQuery {
    19  	return &SearchQuery{
    20  		Type:              1,
    21  		DeviceIdentifiers: deviceIdentifiers,
    22  	}
    23  }
    24  
    25  func NewSearchQuery2(begin, count int) *SearchQuery {
    26  	return &SearchQuery{
    27  		Type:  2,
    28  		Begin: util.Int(begin),
    29  		Count: util.Int(count),
    30  	}
    31  }
    32  
    33  func NewSearchQuery3(applyId int64, begin, count int) *SearchQuery {
    34  	return &SearchQuery{
    35  		Type:    3,
    36  		ApplyId: util.Int64(applyId),
    37  		Begin:   util.Int(begin),
    38  		Count:   util.Int(count),
    39  	}
    40  }
    41  
    42  type SearchResult struct {
    43  	TotalCount int      `json:"total_count"` // 商户名下的设备总量
    44  	ItemCount  int      `json:"item_count"`  // 查询的设备数量
    45  	Devices    []Device `json:"devices"`     // 查询的设备信息列表
    46  }
    47  
    48  type DeviceBase struct {
    49  	DeviceId int64  `json:"device_id"`
    50  	UUID     string `json:"uuid"`
    51  	Major    int    `json:"major"`
    52  	Minor    int    `json:"minor"`
    53  }
    54  
    55  type Device struct {
    56  	DeviceBase
    57  	Comment string `json:"comment"`  // 设备的备注信息
    58  	PageIds string `json:"page_ids"` // 与此设备关联的页面ID列表,用逗号隔开
    59  	Status  int    `json:"status"`   // 激活状态,0:未激活,1:已激活(但不活跃),2:活跃
    60  	PoiId   int64  `json:"poi_id"`   // 设备关联的门店ID,关联门店后,在门店1KM的范围内有优先摇出信息的机会。门店相关信息具体可查看门店相关的接口文档
    61  }
    62  
    63  // 查询设备列表.
    64  func Search(clt *core.Client, query *SearchQuery) (rslt *SearchResult, err error) {
    65  	var result struct {
    66  		core.Error
    67  		SearchResult `json:"data"`
    68  	}
    69  
    70  	incompleteURL := "https://api.weixin.qq.com/shakearound/device/search?access_token="
    71  	if err = clt.PostJSON(incompleteURL, query, &result); err != nil {
    72  		return
    73  	}
    74  
    75  	if result.ErrCode != core.ErrCodeOK {
    76  		err = &result.Error
    77  		return
    78  	}
    79  
    80  	result.SearchResult.ItemCount = len(result.SearchResult.Devices)
    81  	rslt = &result.SearchResult
    82  	return
    83  }
    84  
    85  // DeviceIterator
    86  //
    87  //	iter, err := NewDeviceIterator(*core.Client, *SearchQuery)
    88  //	if err != nil {
    89  //	    // TODO: 增加你的代码
    90  //	}
    91  //
    92  //	for iter.HasNext() {
    93  //	    items, err := iter.NextPage()
    94  //	    if err != nil {
    95  //	        // TODO: 增加你的代码
    96  //	    }
    97  //	    // TODO: 增加你的代码
    98  //	}
    99  type DeviceIterator struct {
   100  	clt *core.Client
   101  
   102  	nextQuery *SearchQuery // 下一次查询参数
   103  
   104  	lastSearchResult *SearchResult // 最近一次获取的数据
   105  	nextPageCalled   bool          // NextPage() 是否调用过
   106  }
   107  
   108  func (iter *DeviceIterator) TotalCount() int {
   109  	return iter.lastSearchResult.TotalCount
   110  }
   111  
   112  func (iter *DeviceIterator) HasNext() bool {
   113  	if !iter.nextPageCalled { // 第一次调用需要特殊对待
   114  		return iter.lastSearchResult.ItemCount > 0 ||
   115  			*iter.nextQuery.Begin < iter.lastSearchResult.TotalCount
   116  	}
   117  
   118  	return *iter.nextQuery.Begin < iter.lastSearchResult.TotalCount
   119  }
   120  
   121  func (iter *DeviceIterator) NextPage() (devices []Device, err error) {
   122  	if !iter.nextPageCalled { // 第一次调用需要特殊对待
   123  		iter.nextPageCalled = true
   124  
   125  		devices = iter.lastSearchResult.Devices
   126  		return
   127  	}
   128  
   129  	rslt, err := Search(iter.clt, iter.nextQuery)
   130  	if err != nil {
   131  		return
   132  	}
   133  
   134  	*iter.nextQuery.Begin += rslt.ItemCount
   135  	iter.lastSearchResult = rslt
   136  
   137  	devices = rslt.Devices
   138  	return
   139  }
   140  
   141  func NewDeviceIterator(clt *core.Client, query *SearchQuery) (iter *DeviceIterator, err error) {
   142  	if query.Type != 2 {
   143  		err = errors.New("Unsupported SearchQuery.Type")
   144  		return
   145  	}
   146  
   147  	// 逻辑上相当于第一次调用 DeviceIterator.NextPage, 因为第一次调用 DeviceIterator.HasNext 需要数据支撑, 所以提前获取了数据
   148  
   149  	rslt, err := Search(clt, query)
   150  	if err != nil {
   151  		return
   152  	}
   153  
   154  	*query.Begin += rslt.ItemCount
   155  
   156  	iter = &DeviceIterator{
   157  		clt: clt,
   158  
   159  		nextQuery: query,
   160  
   161  		lastSearchResult: rslt,
   162  		nextPageCalled:   false,
   163  	}
   164  	return
   165  }