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

     1  package material
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/chanxuehong/wechat/mp/core"
     7  )
     8  
     9  // 删除永久素材.
    10  func Delete(clt *core.Client, mediaId string) (err error) {
    11  	const incompleteURL = "https://api.weixin.qq.com/cgi-bin/material/del_material?access_token="
    12  
    13  	var request = struct {
    14  		MediaId string `json:"media_id"`
    15  	}{
    16  		MediaId: mediaId,
    17  	}
    18  	var result core.Error
    19  	if err = clt.PostJSON(incompleteURL, &request, &result); err != nil {
    20  		return
    21  	}
    22  	if result.ErrCode != core.ErrCodeOK {
    23  		err = &result
    24  		return
    25  	}
    26  	return
    27  }
    28  
    29  // 公众号永久素材总数信息
    30  type MaterialCountInfo struct {
    31  	VoiceCount int `json:"voice_count"`
    32  	VideoCount int `json:"video_count"`
    33  	ImageCount int `json:"image_count"`
    34  	NewsCount  int `json:"news_count"`
    35  }
    36  
    37  // 获取素材总数数据.
    38  func GetMaterialCount(clt *core.Client) (info *MaterialCountInfo, err error) {
    39  	const incompleteURL = "https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token="
    40  
    41  	var result struct {
    42  		core.Error
    43  		MaterialCountInfo
    44  	}
    45  	if err = clt.GetJSON(incompleteURL, &result); err != nil {
    46  		return
    47  	}
    48  	if result.ErrCode != core.ErrCodeOK {
    49  		err = &result.Error
    50  		return
    51  	}
    52  	info = &result.MaterialCountInfo
    53  	return
    54  }
    55  
    56  type BatchGetResult struct {
    57  	TotalCount int            `json:"total_count"` // 该类型的素材的总数
    58  	ItemCount  int            `json:"item_count"`  // 本次调用获取的素材的数量
    59  	Items      []MaterialInfo `json:"item"`        // 本次调用获取的素材列表
    60  }
    61  
    62  type MaterialInfo struct {
    63  	MediaId    string `json:"media_id"`    // 素材id
    64  	Name       string `json:"name"`        // 文件名称
    65  	UpdateTime int64  `json:"update_time"` // 最后更新时间
    66  	URL        string `json:"url"`         // 当获取的列表是图片素材列表时, 该字段是图片的URL
    67  }
    68  
    69  // 获取素材列表.
    70  //
    71  //	materialType: 素材的类型, 图片(image), 视频(video), 语音 (voice)
    72  //	offset:       从全部素材的该偏移位置开始返回, 0表示从第一个素材
    73  //	count:        返回素材的数量, 取值在1到20之间
    74  func BatchGet(clt *core.Client, materialType string, offset, count int) (rslt *BatchGetResult, err error) {
    75  	const incompleteURL = "https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token="
    76  
    77  	switch materialType {
    78  	case MaterialTypeImage, MaterialTypeVideo, MaterialTypeVoice, MaterialTypeNews:
    79  	default:
    80  		err = fmt.Errorf("Incorrect materialType: %s", materialType)
    81  		return
    82  	}
    83  
    84  	if offset < 0 {
    85  		err = fmt.Errorf("Incorrect offset: %d", offset)
    86  		return
    87  	}
    88  	if count <= 0 {
    89  		err = fmt.Errorf("Incorrect count: %d", count)
    90  		return
    91  	}
    92  
    93  	var request = struct {
    94  		MaterialType string `json:"type"`
    95  		Offset       int    `json:"offset"`
    96  		Count        int    `json:"count"`
    97  	}{
    98  		MaterialType: materialType,
    99  		Offset:       offset,
   100  		Count:        count,
   101  	}
   102  	var result struct {
   103  		core.Error
   104  		BatchGetResult
   105  	}
   106  	if err = clt.PostJSON(incompleteURL, &request, &result); err != nil {
   107  		return
   108  	}
   109  	if result.ErrCode != core.ErrCodeOK {
   110  		err = &result.Error
   111  		return
   112  	}
   113  	rslt = &result.BatchGetResult
   114  	return
   115  }
   116  
   117  // =====================================================================================================================
   118  
   119  // MaterialIterator
   120  //
   121  //	iter, err := NewMaterialIterator(clt, MaterialTypeImage, 0, 10)
   122  //	if err != nil {
   123  //	    // TODO: 增加你的代码
   124  //	}
   125  //
   126  //	for iter.HasNext() {
   127  //	    items, err := iter.NextPage()
   128  //	    if err != nil {
   129  //	        // TODO: 增加你的代码
   130  //	    }
   131  //	    // TODO: 增加你的代码
   132  //	}
   133  type MaterialIterator struct {
   134  	clt *core.Client
   135  
   136  	materialType string
   137  	nextOffset   int
   138  	count        int
   139  
   140  	lastBatchGetResult *BatchGetResult
   141  	nextPageCalled     bool
   142  }
   143  
   144  func (iter *MaterialIterator) TotalCount() int {
   145  	return iter.lastBatchGetResult.TotalCount
   146  }
   147  
   148  func (iter *MaterialIterator) HasNext() bool {
   149  	if !iter.nextPageCalled {
   150  		return iter.lastBatchGetResult.ItemCount > 0 || iter.nextOffset < iter.lastBatchGetResult.TotalCount
   151  	}
   152  	return iter.nextOffset < iter.lastBatchGetResult.TotalCount
   153  }
   154  
   155  func (iter *MaterialIterator) NextPage() (items []MaterialInfo, err error) {
   156  	if !iter.nextPageCalled {
   157  		iter.nextPageCalled = true
   158  		items = iter.lastBatchGetResult.Items
   159  		return
   160  	}
   161  
   162  	rslt, err := BatchGet(iter.clt, iter.materialType, iter.nextOffset, iter.count)
   163  	if err != nil {
   164  		return
   165  	}
   166  
   167  	iter.lastBatchGetResult = rslt
   168  	iter.nextOffset += rslt.ItemCount
   169  
   170  	items = rslt.Items
   171  	return
   172  }
   173  
   174  func NewMaterialIterator(clt *core.Client, materialType string, offset, count int) (iter *MaterialIterator, err error) {
   175  	// 逻辑上相当于第一次调用 MaterialIterator.NextPage,
   176  	// 因为第一次调用 MaterialIterator.HasNext 需要数据支撑, 所以提前获取了数据
   177  	rslt, err := BatchGet(clt, materialType, offset, count)
   178  	if err != nil {
   179  		return
   180  	}
   181  
   182  	iter = &MaterialIterator{
   183  		clt: clt,
   184  
   185  		materialType: materialType,
   186  		nextOffset:   offset + rslt.ItemCount,
   187  		count:        count,
   188  
   189  		lastBatchGetResult: rslt,
   190  		nextPageCalled:     false,
   191  	}
   192  	return
   193  }