![]() |
#2
schtg2025-01-29 06:57
|
25号晚上1点多钟,脑子突然灵光一闪,那个问题不费吹灰之力就解决了,之前求助deepseek也没有解决。我把解决方法反哺给deepseek了,以后有同样问题它就可以正确解答了。
今天,微信公众号的素材管理模块的工作总算是完成了(有待完善),赶紧发上来分享给大家,就当是祝大家新年快乐。。。
谈谈开发思路,供感兴趣的狐友参考。
微信的素材管理有7个功能接口,新增临时素材,获取临时素材(这两个没有对我开放权限),新增永久素材,获取永久素材,删除永久素材,获取素材总数, 获取素材列表。因为功能差不多,所以我把他们整合到一个类里面,建立一个自定义类materials,分别用append,get,delete,getcount,getlist方法来实现这几个功能。还有一个uploadimg方法,是用来上传图文信息里的图片的,就是这个玩意让我苦思冥想很久。。。
现在把这个materials类的代码发上来,有感兴趣的,可以私信我要源代码,我的myclass有点大好像不能上传

这里是主要代码:

**************************************************
*-- 类: materials (d:\my documents\visual foxpro 项目\myclass.vcx)
*-- 父类: custom
*-- 基类: custom
*-- 时间戳: 01/28/25 11:06:06 PM
*
DEFINE CLASS materials AS custom
*-- 微信素材库api网址
apiurl = ""
*-- 上传素材的类型,默认为image。
type = "image"
Name = "materials"
*-- 新增永久素材
PROCEDURE append
*!* 新增临时素材 http请求方式:POST/FORM,使用https https://api.weixin./cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
*!* 获取临时素材 http请求方式: GET,https调用 https://api.weixin./cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
*!* 新增永久素材 http请求方式: POST,https协议 https://api.weixin./cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
*!* 获取永久素材 http请求方式: POST,https协议 https://api.weixin./cgi-bin/material/get_material?access_token=ACCESS_TOKEN
*!* 删除永久素材 http请求方式: POST https://api.weixin./cgi-bin/material/del_material?access_token=ACCESS_TOKEN
*!* 获取素材总数 http请求方式: GET https://api.weixin./cgi-bin/material/get_materialcount?access_token=ACCESS_TOKEN
*!* 获取素材列表 http请求方式: POST https://api.weixin./cgi-bin/material/batchget_material?access_token=ACCESS_TOKEN
*!* 素材的格式大小等要求
*!* 图片(image): 10M,支持bmp/png/jpeg/jpg/gif格式
*!* 语音(voice):2M,播放长度不超过60s,mp3/wma/wav/amr格式
*!* 视频(video):10MB,支持MP4格式
*!* 缩略图(thumb):64KB,支持JPG格式
PARAMETERS mediafile
*!* 如果没有给mediafile参数
IF PARAMETERS()=0
DO CASE
CASE this.type="image"
mediafile=GETFILE("bmp|jpeg|jpg|png|gif")
CASE this.type="voice"
mediafile=GETFILE("mp3|wma|wav|amr")
CASE this.type="video"
mediafile=GETFILE("mp4")
CASE this.type="thumb"
mediafile=GETFILE("jpg")
OTHERWISE
MESSAGEBOX("微信素材只支持图片、语音、视频和缩略图!",0+16,"请设置正确的素材type!")
RETURN
ENDCASE
ENDIF
*!* 检查文件大小并设置mine类型
opart=NEWOBJECT("part","myclass")
opart.fieldname="media" &&设定接口字段名为media
cstr=FILETOSTR(mediafile)
nlen=LEN(cstr)
DO CASE
CASE this.type="image"
IF nlen>10*1024*1024 OR nlen=0
MESSAGEBOX("文件大小超过 10MB!",0+16,"上传失败!")
RELEASE opart
RETURN
ENDIF
opart.contenttype="image/"+IIF(LOWER(JUSTEXT(mediafile))="jpg","jpeg",LOWER(JUSTEXT(mediafile)))
CASE this.type="voice"
IF nlen>2*1024*1024 OR nlen=0
MESSAGEBOX("文件大小超过 2MB!",0+16,"上传失败!")
RELEASE opart
RETURN
ENDIF
opart.contenttype="audio/"+ICASE(LOWER(JUSTEXT(mediafile))="mp3","mpeg",LOWER(JUSTEXT(mediafile))="wma","x-ms-wma",LOWER(JUSTEXT(mediafile)))
CASE this.type="video"
IF nlen>10*1024*1024 OR nlen=0
MESSAGEBOX("文件大小超过 10MB!",0+16,"上传失败!")
RELEASE opart
RETURN
ENDIF
opart.contenttype="video/mp4"
CASE this.type="thumb"
IF nlen>64*1024 OR nlen=0
MESSAGEBOX("文件大小超过 64KB!",0+16,"上传失败!")
RELEASE opart
RETURN
ENDIF
opart.contenttype="image/jpeg"
OTHERWISE
MESSAGEBOX("微信素材只支持图片、语音、视频和缩略图!",0+16,"请设置正确的素材type!")
RELEASE oport
RETURN
ENDCASE
opart.attachment=mediafile
*!* 准备请求体
omultipart=NEWOBJECT("multipart","myclass")
omultipart.parts.add(opart)
*!* 下面这段逻辑有点问题,没考虑好在什么环境下使用
IF this.type="video/mp4" &&微信要求上传视频时还要提交视频描述信息,json结构
opart2=NEWOBJECT("part","myclass")
opart2.contenttype="application/json"
opart2.fieldname="description"
opart2.append("id","description")
*!* 构建json格式数据,格式如下
*!* {
*!* "title":VIDEO_TITLE,
*!* "introduction":INTRODUCTION
*!* }
*!* ojson应该在此方法前构建好,这里就当是检查是否遗漏
* IF EMPTY(opart2.content)
ojson=NEWOBJECT("json","myclass")
ctitle=INPUTBOX("请在文本框中输入您想显示的视频标题!","请提供视频的标题!")
ojson.add("title",ctitle)
cdescription=INPUTBOX("请在文本框中输入您想显示的视频描述,越详细越好。","请提供视频的描述!")
ojson.add("introduction",cdescription)
opart2.content=ojson.generate()
RELEASE ojson
* ENDIF
omultipart.parts.add(opart2)
ENDIF
*!*
omultipart.setrequestheader()
omultipart.setrequestbody()
lcheader=omultipart.contenttype+omultipart.boundary
lcbody=CREATEBINARY(omultipart.requestbody)
STRTOFILE(lcbody,"request_body.txt") && debug,成功后注释掉。
RELEASE opart,omultipart
this.apiurl="https://api.weixin./cgi-bin/material/add_material?access_token=ACCESS_TOKEN&type=TYPE"
this.apiurl=STRTRAN(this.apiurl,"ACCESS_TOKEN",otoken.access_token)
this.apiurl=STRTRAN(this.apiurl,"TYPE",this.type)
* 准备发送 HTTP POST 请求
LOCAL loHTTP, lcResponse
*loHTTP = CREATEOBJECT("WinHttp.WinHttpRequest.5.1")
lohttp=NEWOBJECT("microsoft.xmlhttp")
*loHTTP.SetProxy(2, "127.0.0.1:8888") && 设置代理,方便调试,没问题后可以注释掉
loHTTP.Open("POST", this.apiurl, .F.)
*loHTTP.SetRequestHeader("Accept-Encoding","gzip, deflate, br")
*loHttp.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
loHTTP.SetRequestHeader("Content-Type", lcHeader)
*loHTTP.SetRequestHeader("Content-Length", LEN(lcbody))
loHTTP.Send(lcBody)
WAIT "数据上传中。。。" WINDOW AT 25,90 TIMEOUT 5
lcresponse=lohttp.responsetext
RELEASE lohttp
* 获得服务器响应文本,调试用,完成后可以注释掉
STRTOFILE(lcresponse,"response.txt")
MODIFY FILE response.txt nowait
ENDPROC
*-- 删除永久素材
PROCEDURE delete
*!* 新增临时素材 http请求方式:POST/FORM,使用https https://api.weixin./cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
*!* 获取临时素材 http请求方式: GET,https调用 https://api.weixin./cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
*!* 新增永久素材 http请求方式: POST,https协议 https://api.weixin./cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
*!* 获取永久素材 http请求方式: POST,https协议 https://api.weixin./cgi-bin/material/get_material?access_token=ACCESS_TOKEN
*!* 删除永久素材 http请求方式: POST https://api.weixin./cgi-bin/material/del_material?access_token=ACCESS_TOKEN
*!* 获取素材总数 http请求方式: GET https://api.weixin./cgi-bin/material/get_materialcount?access_token=ACCESS_TOKEN
*!* 获取素材列表 http请求方式: POST https://api.weixin./cgi-bin/material/batchget_material?access_token=ACCESS_TOKEN
PARAMETERS media_id
this.apiurl="https://api.weixin./cgi-bin/material/del_material?access_token=ACCESS_TOKEN"
this.apiurl=STRTRAN(this.apiurl,"ACCESS_TOKEN",otoken.access_token)
ohttp.open("POST",lcurl,.f.)
cjson="{"+["]+"media_id"+[": ]+["]+media_id+["]+"}"
ohttp.send(cjson)
WAIT "正在连接服务器。。。" WINDOW AT 25,90 TIMEOUT 3
STRTOFILE(ohttp.responsetext,"response.txt")
MODIFY FILE response.txt nowait
RELEASE ohttp
ENDPROC
*-- 获取永久素材的总数
PROCEDURE getcount
*!* 新增临时素材 http请求方式:POST/FORM,使用https https://api.weixin./cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
*!* 获取临时素材 http请求方式: GET,https调用 https://api.weixin./cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
*!* 新增永久素材 http请求方式: POST,https协议 https://api.weixin./cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
*!* 获取永久素材 http请求方式: POST,https协议 https://api.weixin./cgi-bin/material/get_material?access_token=ACCESS_TOKEN
*!* 删除永久素材 http请求方式: POST https://api.weixin./cgi-bin/material/del_material?access_token=ACCESS_TOKEN
*!* 获取素材总数 http请求方式: GET https://api.weixin./cgi-bin/material/get_materialcount?access_token=ACCESS_TOKEN
*!* 获取素材列表 http请求方式: POST https://api.weixin./cgi-bin/material/batchget_material?access_token=ACCESS_TOKEN
this.apiurl="https://api.weixin./cgi-bin/material/get_materialcount?access_token=ACCESS_TOKEN"
this.apiurl=STRTRAN(this.apiurl,"ACCESS_TOKEN",otoken.access_token)
lohttp=NEWOBJECT("microsoft.xmlhttp")
lohttp.open("GET",this.apiurl,.f.)
lohttp.send()
WAIT "发送请求。。。" WINDOW AT 25,90 TIMEOUT 3
lcresponse=lohttp.responsetext
RELEASE lohttp
* 获得服务器响应文本,调试用
STRTOFILE(lcresponse,"response.txt")
MODIFY FILE response.txt nowait
*!* 返回说明
*!* {
*!* "voice_count":COUNT,
*!* "video_count":COUNT,
*!* "image_count":COUNT,
*!* "news_count":COUNT
*!* }
ENDPROC
*-- 获取指定类型的素材列表
PROCEDURE getlist
*!* 新增临时素材 http请求方式:POST/FORM,使用https https://api.weixin./cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
*!* 获取临时素材 http请求方式: GET,https调用 https://api.weixin./cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
*!* 新增永久素材 http请求方式: POST,https协议 https://api.weixin./cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
*!* 获取永久素材 http请求方式: POST,https协议 https://api.weixin./cgi-bin/material/get_material?access_token=ACCESS_TOKEN
*!* 删除永久素材 http请求方式: POST https://api.weixin./cgi-bin/material/del_material?access_token=ACCESS_TOKEN
*!* 获取素材总数 http请求方式: GET https://api.weixin./cgi-bin/material/get_materialcount?access_token=ACCESS_TOKEN
*!* 获取素材列表 http请求方式: POST https://api.weixin./cgi-bin/material/batchget_material?access_token=ACCESS_TOKEN
this.apiurl="https://api.weixin./cgi-bin/material/batchget_material?access_token=ACCESS_TOKEN"
this.apiurl=STRTRAN(this.apiurl,"ACCESS_TOKEN",otoken.access_token)
ojson=NEWOBJECT("json","myclass")
ojson.Add("image","type")
ojson.Add(0,"offset")
ojson.Add(1,"count")
cjson=ojson.generate()
ohttp.open("POST",lcurl,.f.)
ohttp.send(cjson)
WAIT "正在连接服务器。。。" WINDOW AT 25,90 TIMEOUT 3
STRTOFILE(ohttp.responsetext,"response.txt")
MODIFY FILE response.txt nowait
RELEASE ojson,ohttp
ENDPROC
*-- 获取永久素材
PROCEDURE get
*!* 新增临时素材 http请求方式:POST/FORM,使用https https://api.weixin./cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
*!* 获取临时素材 http请求方式: GET,https调用 https://api.weixin./cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
*!* 新增永久素材 http请求方式: POST,https协议 https://api.weixin./cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
*!* 获取永久素材 http请求方式: POST,https协议 https://api.weixin./cgi-bin/material/get_material?access_token=ACCESS_TOKEN
*!* 删除永久素材 http请求方式: POST https://api.weixin./cgi-bin/material/del_material?access_token=ACCESS_TOKEN
*!* 获取素材总数 http请求方式: GET https://api.weixin./cgi-bin/material/get_materialcount?access_token=ACCESS_TOKEN
*!* 获取素材列表 http请求方式: POST https://api.weixin./cgi-bin/material/batchget_material?access_token=ACCESS_TOKEN
PARAMETERS media_id
this.apiurl="https://api.weixin./cgi-bin/material/get_material?access_token=ACCESS_TOKEN"
this.apiurl=STRTRAN(this.apiurl,"ACCESS_TOKEN",otoken.access_token)
ohttp.open("POST",lcurl,.f.)
cjson="{"+["]+"media_id"+[": ]+["]+media_id+["]+"}"
ohttp.send(cjson)
WAIT "正在连接服务器。。。" WINDOW AT 25,90 TIMEOUT 3
STRTOFILE(ohttp.responsetext,"response.txt")
MODIFY FILE response.txt nowait
RELEASE ohttp
ENDPROC
*-- 新增临时素材
PROCEDURE appendtemp
*!* 新增临时素材 http请求方式:POST/FORM,使用https https://api.weixin./cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
*!* 获取临时素材 http请求方式: GET,https调用 https://api.weixin./cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
*!* 新增永久素材 http请求方式: POST,https协议 https://api.weixin./cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
*!* 获取永久素材 http请求方式: POST,https协议 https://api.weixin./cgi-bin/material/get_material?access_token=ACCESS_TOKEN
*!* 删除永久素材 http请求方式: POST https://api.weixin./cgi-bin/material/del_material?access_token=ACCESS_TOKEN
*!* 获取素材总数 http请求方式: GET https://api.weixin./cgi-bin/material/get_materialcount?access_token=ACCESS_TOKEN
*!* 获取素材列表 http请求方式: POST https://api.weixin./cgi-bin/material/batchget_material?access_token=ACCESS_TOKEN
this.apiurl="https://api.weixin./cgi-bin/media/upload"
ENDPROC
*-- 获取临时素材
PROCEDURE gettemp
*!* 新增临时素材 http请求方式:POST/FORM,使用https https://api.weixin./cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
*!* 获取临时素材 http请求方式: GET,https调用 https://api.weixin./cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
*!* 新增永久素材 http请求方式: POST,https协议 https://api.weixin./cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
*!* 获取永久素材 http请求方式: POST,https协议 https://api.weixin./cgi-bin/material/get_material?access_token=ACCESS_TOKEN
*!* 删除永久素材 http请求方式: POST https://api.weixin./cgi-bin/material/del_material?access_token=ACCESS_TOKEN
*!* 获取素材总数 http请求方式: GET https://api.weixin./cgi-bin/material/get_materialcount?access_token=ACCESS_TOKEN
*!* 获取素材列表 http请求方式: POST https://api.weixin./cgi-bin/material/batchget_material?access_token=ACCESS_TOKEN
this.apiurl="https://api.weixin./cgi-bin/media/get"
ENDPROC
*-- 新增图文信息内的图片素材
PROCEDURE uploadimg
*!* 新增临时素材 http请求方式:POST/FORM,使用https https://api.weixin./cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
*!* 获取临时素材 http请求方式: GET,https调用 https://api.weixin./cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
*!* 新增永久素材 http请求方式: POST,https协议 https://api.weixin./cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
*!* 获取永久素材 http请求方式: POST,https协议 https://api.weixin./cgi-bin/material/get_material?access_token=ACCESS_TOKEN
*!* 删除永久素材 http请求方式: POST https://api.weixin./cgi-bin/material/del_material?access_token=ACCESS_TOKEN
*!* 获取素材总数 http请求方式: GET https://api.weixin./cgi-bin/material/get_materialcount?access_token=ACCESS_TOKEN
*!* 获取素材列表 http请求方式: POST https://api.weixin./cgi-bin/material/batchget_material?access_token=ACCESS_TOKEN
*!* 上传图文信息内的图片至微信公众号服务器,成功则返回图片的网址。图片仅支持jpg和png格式,不超过1M。
*!* 使用者拿到图片的网址后应保存在表中,方便日后读取。
PARAMETERS lcimgpng
IF PARAMETERS()=0
lcimgpng=GETFILE("jpg|png")
ENDIF
* 检查文件大小及内容
lnFileSize = LEN(FILETOSTR(lcimgpng))
IF lnFileSize > 1 * 1024 * 1024 OR lnFileSize=0
MESSAGEBOX("文件大小超过 1MB!",0+16,"上传失败!")
RETURN
ENDIF
* 准备上传诸元:接口字段名,附件,content-type,生成所需post的二进制数据流lcbody
opart=NEWOBJECT("part","myclass")
opart.fieldname="media" &&设定接口字段名为media
opart.attachment=lcimgpng
IF JUSTEXT(lcimgpng)="JPG"
opart.contenttype="image/jpg"
ENDIF
IF JUSTEXT(lcimgpng)="PNG"
opart.contenttype="image/png"
ENDIF
omultipart=NEWOBJECT("multipart","myclass")
omultipart.parts.add(opart)
omultipart.setrequestheader()
omultipart.setrequestbody()
lcheader=omultipart.contenttype+omultipart.boundary
lcbody=CREATEBINARY(omultipart.requestbody)
STRTOFILE(lcbody,"request_body.txt") && debug,成功后注释掉。
RELEASE opart,omultipart
lcAccessToken = otoken.access_token && otoken是public对象,用来获得令牌access_token
this.apiurl="https://api.weixin./cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN"
this.apiurl=STRTRAN(this.apiurl,"ACCESS_TOKEN",lcaccesstoken)
* 准备发送 HTTP POST 请求的函数
LOCAL loHTTP, lcResponse
*loHTTP = CREATEOBJECT("WinHttp.WinHttpRequest.5.1")
lohttp=NEWOBJECT("microsoft.xmlhttp")
*loHTTP.SetProxy(2, "127.0.0.1:8888") && 设置代理,方便调试,没问题后可以注释掉
loHTTP.Open("POST", this.apiurl, .F.)
*loHTTP.SetRequestHeader("Accept-Encoding","gzip, deflate, br")
*loHttp.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
loHTTP.SetRequestHeader("Content-Type", lcHeader)
*loHTTP.SetRequestHeader("Content-Length", LEN(lcbody))
loHTTP.Send(lcBody)
WAIT "数据上传中。。。" WINDOW AT 25,90 TIMEOUT 5
lcresponse=lohttp.responsetext
RELEASE lohttp
* 获得服务器响应文本,调试用
STRTOFILE(lcresponse,"response.txt")
MODIFY FILE response.txt nowait
ENDPROC
PROCEDURE Init
*this.result=NEWOBJECT("json","myclass")
*!* this.AddObject("paras","keyvalue")
*!* this.AddObject("result","json")
ENDPROC
ENDDEFINE
*
*-- EndDefine: materials
**************************************************