/**!
* 微信内置浏览器的Javascript API,功能包括:
*
* 1、分享到微信朋友圈
* 2、分享给微信好友
* 3、分享到腾讯微博
* 4、新的分享接口,包含朋友圈、好友、微博的分享(for iOS)
* 5、隐藏/显示右上角的菜单入口
* 6、隐藏/显示底部浏览器工具栏
* 7、获取当前的网络状态
* 8、调起微信客户端的图片播放组件
* 9、关闭公众平台Web页面
*
* @author zhaoxianlie(http://www.baidufe.com)
*/
var WeixinApi = (function () {
"use strict";
/**
* 分享到微信朋友圈
* @param {Object} data 待分享的信息
* @p-config {String} appId 公众平台的appId(服务号可用)
* @p-config {String} imgUrl 图片地址
* @p-config {String} link 链接地址
* @p-config {String} desc 描述
* @p-config {String} title 分享的标题
*
* @param {Object} callbacks 相关回调方法
* @p-config {Boolean} async ready方法是否需要异步执行,默认false
* @p-config {Function} ready(argv) 就绪状态
* @p-config {Function} dataLoaded(data) 数据加载完成后调用,async为true时有用,也可以为空
* @p-config {Function} cancel(resp) 取消
* @p-config {Function} fail(resp) 失败
* @p-config {Function} confirm(resp) 成功
* @p-config {Function} all(resp) 无论成功失败都会执行的回调
*/
function weixinShareTimeline(data, callbacks) {
callbacks = callbacks || {};
var shareTimeline = function (theData) {
WeixinJSBridge.invoke('shareTimeline', {
"appid":theData.appId ? theData.appId : '',
"img_url":theData.imgUrl,
"link":theData.link,
"desc":theData.title,
"title":theData.desc, // 注意这里要分享出去的内容是desc
"img_width":"640",
"img_height":"640"
}, function (resp) {
switch (resp.err_msg) {
// share_timeline:cancel 用户取消
case 'share_timeline:cancel':
callbacks.cancel && callbacks.cancel(resp);
break;
// share_timeline:confirm 发送成功
case 'share_timeline:confirm':
case 'share_timeline:ok':
callbacks.confirm && callbacks.confirm(resp);
break;
// share_timeline:fail 发送失败
case 'share_timeline:fail':
default:
callbacks.fail && callbacks.fail(resp);
break;
}
// 无论成功失败都会执行的回调
callbacks.all && callbacks.all(resp);
});
};
WeixinJSBridge.on('menu:share:timeline', function (argv) {
if (callbacks.async && callbacks.ready) {
window["_wx_loadedCb_"] = callbacks.dataLoaded || new Function();
if(window["_wx_loadedCb_"].toString().indexOf("_wx_loadedCb_") > 0) {
window["_wx_loadedCb_"] = new Function();
}
callbacks.dataLoaded = function (newData) {
window["_wx_loadedCb_"](newData);
shareTimeline(newData);
};
// 然后就绪
callbacks.ready && callbacks.ready(argv);
} else {
// 就绪状态
callbacks.ready && callbacks.ready(argv);
shareTimeline(data);
}
});
}
/**
* 发送给微信上的好友
* @param {Object} data 待分享的信息
* @p-config {String} appId 公众平台的appId(服务号可用)
* @p-config {String} imgUrl 图片地址
* @p-config {String} link 链接地址
* @p-config {String} desc 描述
* @p-config {String} title 分享的标题
*
* @param {Object} callbacks 相关回调方法
* @p-config {Boolean} async ready方法是否需要异步执行,默认false
* @p-config {Function} ready(argv) 就绪状态
* @p-config {Function} dataLoaded(data) 数据加载完成后调用,async为true时有用,也可以为空
* @p-config {Function} cancel(resp) 取消
* @p-config {Function} fail(resp) 失败
* @p-config {Function} confirm(resp) 成功
* @p-config {Function} all(resp) 无论成功失败都会执行的回调
*/
function weixinSendAppMessage(data, callbacks) {
callbacks = callbacks || {};
var sendAppMessage = function (theData) {
WeixinJSBridge.invoke('sendAppMessage', {
"appid":theData.appId ? theData.appId : '',
"img_url":theData.imgUrl,
"link":theData.link,
"desc":theData.desc,
"title":theData.title,
"img_width":"640",
"img_height":"640"
}, function (resp) {
switch (resp.err_msg) {
// send_app_msg:cancel 用户取消
case 'send_app_msg:cancel':
callbacks.cancel && callbacks.cancel(resp);
break;
// send_app_msg:confirm 发送成功
case 'send_app_msg:confirm':
case 'send_app_msg:ok':
callbacks.confirm && callbacks.confirm(resp);
break;
// send_app_msg:fail 发送失败
case 'send_app_msg:fail':
default:
callbacks.fail && callbacks.fail(resp);
break;
}
// 无论成功失败都会执行的回调
callbacks.all && callbacks.all(resp);
});
};
WeixinJSBridge.on('menu:share:appmessage', function (argv) {
if (callbacks.async && callbacks.ready) {
window["_wx_loadedCb_"] = callbacks.dataLoaded || new Function();
if(window["_wx_loadedCb_"].toString().indexOf("_wx_loadedCb_") > 0) {
window["_wx_loadedCb_"] = new Function();
}
callbacks.dataLoaded = function (newData) {
window["_wx_loadedCb_"](newData);
sendAppMessage(newData);
};
// 然后就绪
callbacks.ready && callbacks.ready(argv);
} else {
// 就绪状态
callbacks.ready && callbacks.ready(argv);
sendAppMessage(data);
}
});
}
/**
* 分享到腾讯微博
* @param {Object} data 待分享的信息
* @p-config {String} link 链接地址
* @p-config {String} desc 描述
*
* @param {Object} callbacks 相关回调方法
* @p-config {Boolean} async ready方法是否需要异步执行,默认false
* @p-config {Function} ready(argv) 就绪状态
* @p-config {Function} dataLoaded(data) 数据加载完成后调用,async为true时有用,也可以为空
* @p-config {Function} cancel(resp) 取消
* @p-config {Function} fail(resp) 失败
* @p-config {Function} confirm(resp) 成功
* @p-config {Function} all(resp) 无论成功失败都会执行的回调
*/
function weixinShareWeibo(data, callbacks) {
callbacks = callbacks || {};
var shareWeibo = function (theData) {
WeixinJSBridge.invoke('shareWeibo', {
"content":theData.desc,
"url":theData.link
}, function (resp) {
switch (resp.err_msg) {
// share_weibo:cancel 用户取消
case 'share_weibo:cancel':
callbacks.cancel && callbacks.cancel(resp);
break;
// share_weibo:confirm 发送成功
case 'share_weibo:confirm':
case 'share_weibo:ok':
callbacks.confirm && callbacks.confirm(resp);
break;
// share_weibo:fail 发送失败
case 'share_weibo:fail':
default:
callbacks.fail && callbacks.fail(resp);
break;
}
// 无论成功失败都会执行的回调
callbacks.all && callbacks.all(resp);
});
};
WeixinJSBridge.on('menu:share:weibo', function (argv) {
if (callbacks.async && callbacks.ready) {
window["_wx_loadedCb_"] = callbacks.dataLoaded || new Function();
if(window["_wx_loadedCb_"].toString().indexOf("_wx_loadedCb_") > 0) {
window["_wx_loadedCb_"] = new Function();
}
callbacks.dataLoaded = function (newData) {
window["_wx_loadedCb_"](newData);
shareWeibo(newData);
};
// 然后就绪
callbacks.ready && callbacks.ready(argv);
} else {
// 就绪状态
callbacks.ready && callbacks.ready(argv);
shareWeibo(data);
}
});
}
/**
* 新的分享接口
* @param {Object} data 待分享的信息
* @p-config {String} appId 公众平台的appId(服务号可用)
* @p-config {String} imgUrl 图片地址
* @p-config {String} link 链接地址
* @p-config {String} desc 描述
* @p-config {String} title 分享的标题
*
* @param {Object} callbacks 相关回调方法
* @p-config {Boolean} async ready方法是否需要异步执行,默认false
* @p-config {Function} ready(argv,shareTo) 就绪状态
* @p-config {Function} dataLoaded(data) 数据加载完成后调用,async为true时有用,也可以为空
* @p-config {Function} cancel(resp,shareTo) 取消
* @p-config {Function} fail(resp,shareTo) 失败
* @p-config {Function} confirm(resp,shareTo) 成功
* @p-config {Function} all(resp,shareTo) 无论成功失败都会执行的回调
*/
function weixinGeneralShare(data, callbacks) {
callbacks = callbacks || {};
var generalShare = function (general,theData) {
// 如果是分享到朋友圈,则需要把title和desc交换一下
if(general.shareTo == 'timeline') {
var title = theData.title;
theData.title = theData.desc || title;
theData.desc = title;
}
// 分享出去
general.generalShare({
"appid":theData.appId ? theData.appId : '',
"img_url":theData.imgUrl,
"link":theData.link,
"desc":theData.desc,
"title":theData.title,
"img_width":"640",
"img_height":"640"
}, function (resp) {
switch (resp.err_msg) {
// general_share:cancel 用户取消
case 'general_share:cancel':
callbacks.cancel && callbacks.cancel(resp ,general.shareTo);
break;
// general_share:confirm 发送成功
case 'general_share:confirm':
case 'general_share:ok':
callbacks.confirm && callbacks.confirm(resp ,general.shareTo);
break;
// general_share:fail 发送失败
case 'general_share:fail':
default:
callbacks.fail && callbacks.fail(resp ,general.shareTo);
break;
}
// 无论成功失败都会执行的回调
callbacks.all && callbacks.all(resp ,general.shareTo);
});
};
WeixinJSBridge.on('menu:general:share', function (general) {
if (callbacks.async && callbacks.ready) {
window["_wx_loadedCb_"] = callbacks.dataLoaded || new Function();
if(window["_wx_loadedCb_"].toString().indexOf("_wx_loadedCb_") > 0) {
window["_wx_loadedCb_"] = new Function();
}
callbacks.dataLoaded = function (newData) {
window["_wx_loadedCb_"](newData);
generalShare(general,newData);
};
// 然后就绪
callbacks.ready && callbacks.ready(general,general.shareTo);
} else {
// 就绪状态
callbacks.ready && callbacks.ready(general,general.shareTo);
generalShare(general,data);
}
});
}
/**
* 加关注(此功能只是暂时先加上,不过因为权限限制问题,不能用,如果你的站点是部署在*.qq.com下,也许可行)
* @param {String} appWeixinId 微信公众号ID
* @param {Object} callbacks 回调方法
* @p-config {Function} fail(resp) 失败
* @p-config {Function} confirm(resp) 成功
*/
function addContact(appWeixinId,callbacks){
callbacks = callbacks || {};
WeixinJSBridge.invoke("addContact", {
webtype: "1",
username: appWeixinId
}, function (resp) {
var success = !resp.err_msg || "add_contact:ok" == resp.err_msg || "add_contact:added" == resp.err_msg;
if(success) {
callbacks.success && callbacks.success(resp);
}else{
callbacks.fail && callbacks.fail(resp);
}
})
}
/**
* 调起微信Native的图片播放组件。
* 这里必须对参数进行强检测,如果参数不合法,直接会导致微信客户端crash
*
* @param {String} curSrc 当前播放的图片地址
* @param {Array} srcList 图片地址列表
*/
function imagePreview(curSrc,srcList) {
if(!curSrc || !srcList || srcList.length == 0) {
return;
}
WeixinJSBridge.invoke('imagePreview', {
'current' : curSrc,
'urls' : srcList
});
}
/**
* 显示网页右上角的按钮
*/
function showOptionMenu() {
WeixinJSBridge.call('showOptionMenu');
}
/**
* 隐藏网页右上角的按钮
*/
function hideOptionMenu() {
WeixinJSBridge.call('hideOptionMenu');
}
/**
* 显示底部工具栏
*/
function showToolbar() {
WeixinJSBridge.call('showToolbar');
}
/**
* 隐藏底部工具栏
*/
function hideToolbar() {
WeixinJSBridge.call('hideToolbar');
}
/**
* 返回如下几种类型:
*
* network_type:wifi wifi网络
* network_type:edge 非wifi,包含3G/2G
* network_type:fail 网络断开连接
* network_type:wwan 2g或者3g
*
* 使用方法:
* WeixinApi.getNetworkType(function(networkType){
*
* });
*
* @param callback
*/
function getNetworkType(callback) {
if (callback && typeof callback == 'function') {
WeixinJSBridge.invoke('getNetworkType', {}, function (e) {
// 在这里拿到e.err_msg,这里面就包含了所有的网络类型
callback(e.err_msg);
});
}
}
/**
* 关闭当前微信公众平台页面
*/
function closeWindow() {
WeixinJSBridge.call("closeWindow");
}
/**
* 当页面加载完毕后执行,使用方法:
* WeixinApi.ready(function(Api){
* // 从这里只用Api即是WeixinApi
* });
* @param readyCallback
*/
function wxJsBridgeReady(readyCallback) {
if (readyCallback && typeof readyCallback == 'function') {
var Api = this;
var wxReadyFunc = function () {
readyCallback(Api);
};
if (typeof window.WeixinJSBridge == "undefined"){
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', wxReadyFunc, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', wxReadyFunc);
document.attachEvent('onWeixinJSBridgeReady', wxReadyFunc);
}
}else{
wxReadyFunc();
}
}
}
return {
version :"2.0",
ready :wxJsBridgeReady,
shareToTimeline :weixinShareTimeline,
shareToWeibo :weixinShareWeibo,
shareToFriend :weixinSendAppMessage,
generalShare :weixinGeneralShare,
addContact :addContact,
showOptionMenu :showOptionMenu,
hideOptionMenu :hideOptionMenu,
showToolbar :showToolbar,
hideToolbar :hideToolbar,
getNetworkType :getNetworkType,
imagePreview :imagePreview,
closeWindow :closeWindow
};
})();相关推荐
weixin-api.js
weixin-api.js
微信jsapi 调用分享接口(完整版)
1.测试环境 申请测试账号 地址: https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index 填写内容: ①:接口配置信息 url:配置http://+域名或者http://+外网ip也可以 token:自定义(任意) ...
ARM64麒麟V10系统下PyTorch离线安装全攻略(附资源下载)
本文详细介绍了在ARM64架构的银河麒麟V10操作系统上,如何通过离线方式成功安装PyTorch深度学习框架。文章提供了从系统环境准备、依赖梳理、离线资源获取与验证,到分步安装、避坑指南及安装后验证的完整流程,并附有资源下载建议,旨在帮助开发者在国产化环境中高效部署AI开发平台。
微信jsapi支付
//微信支付。payinfode zhex payReward: (payInfo)=> { WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId": payInfo.appId, //公众号名称,由商户传入 "timeStamp": payInfo.timeStamp, //时间戳,自1970年以来的秒数 ...
别再手动上传了!用宝塔面板的‘Let‘s Encrypt’免费SSL证书,3分钟自动续期
本文详细介绍了如何利用宝塔面板的‘Let‘s Encrypt’功能实现SSL证书的自动申请和续期,3分钟完成配置即可永久免费使用。通过对比不同SSL证书方案,突出Let's Encrypt的免费、自动续期和高安全性优势,特别适合个人博客和中小企业官网。
Android 集成Chrome 浏览器内核 Crosswalk
Crosswalk 内核的兴起与消亡 Android 4.4 版本之前,使用的是基于 androidWebKit 的 WebView 但实际上,由于 Android 的碎片化问题(大量存在不同的 Android 系统版本,并且各个厂商对内置应用进行定制化,有可能用的不是最新的浏览器内核)。这就导致 WebView 在真实环境中对 API 的支持根本无迹可寻,越发混乱。 随着混合开发的兴起,前端对 ...
【小程序】微信小程序常用api的使用,附案例(建议收藏)
学会使用 微信官方文档 · 小程序 wxapi.js 代码 界面 wxapi.js 代码截图 4.3 wx.uploadFile()上传文件 wxapi.js 案例截图 wxapi.js 代码截图 6- 网络请求 6.1 wx.request() 发起 HTTPS 网络请求 【微信小程序】小程序使用详细教程(建议收藏)
速腾聚创激光雷达复现FAST-LIO
记录复现FAST-LIO算法的过程和,代码梳理和理解。FAST-LIO的简化版、注释版。速腾激光雷达
【公众号/小程序】微信H5跳转小程序踩过的坑!!!
【公众号/小程序】H5跳转小程序踩过的坑!!!
三相逆变器拓扑结构的分析及应用场景
三相逆变器是电力电子领域中广泛应用的一种设备,用于将直流电转换为交流电。不同的拓扑结构在性能、成本、复杂度和应用领域上存在差异。小编将在本文中将进一步拓展对三相逆变器拓扑结构的分析,并探讨其适用的应用场景。
[华为]华为无线控制器AC6508简单配置实例
用户需求:3个地址段,分别是领导、员工、访客,访问控制策略是只允许访客上网,不允许访客访问内网。 vlan173为设备的管理地址和AP获取的地址,领导、员工、访客的vlan分别是vlan131/vlan132/vlan133 首先是许可的下载,使用华为的账号登陆http://app.huawei.com/isdp ,然后按照说明输入许可,下载许可,将许可导入到设备。 web界面访问后,直接按照配置向导配置就可以了。 1.基本配置里主要配置license、设备名称、设备时间 2.端口配置:连接上
一段分享到微信的代码
var WeixinApi = (function () { "use strict"; function weixinShareTimeline(data, callbacks) { callbacks = callbacks || {}; var shareTimeline = function (theData) {
NOAA气象数据下载攻略
各方搜寻气象数据下载途径,发现网上最多的就是从NOAA下载,但是中途有尝试过很多次都没有下载到,每次都是显示不可用,今天终于下载成功了,特此记录。 首先我是从这个网址进入的:National Centers for Environmental Information (NCEI) formerly known as National Climatic Data Center (NCDC) | NCEI offers access to the most significant archives of oc
关于微信中分享到朋友圈代码
最近在做微信的项目,遇到需要转发到朋友圈功能,有需要的朋友可以参考 首先看页面源代码: 发送红包 $(document).ready(function(){ $(function(){ $("#tips").click(function () { $('#tips').hide();
【从零开始入门unity游戏开发之——C#篇01】理论开篇,理解什么是编程
理论开篇,理解什么是编程
最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版
Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。
关于新版本微信分享的一些汇总
因为公司的项目主要是在微信上运行的,所以就要接触微信的分享接口等。 但是因为微信要处理那些类似于“分享后查看结果”的页面,就把接口给改了,发布了新版本的微信,针对这个问题。 新的微信sdk说明文档地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html 大概看了一下内容还是挺丰富的,但是:
汉书HE8,好用的汇编代码编写工具
汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大
uni-app x 鸿蒙原生工程接入支付宝/微信支付:har 依赖配置与 Payment Provider 注册实战指南
本文围绕 [docs/native/modules/harmony/pay.md](https://link.gitcode.com/i/20c4ffb772df9d9d61674dadbb1e3f17) 展开,系统讲解在 uni-app x 项目中,将支付宝支付(uni-payment-alipay)与微信支付(uni-payment-wxpay)集成到鸿蒙原生工程(HarmonyOS)的完整流
计算机控制技术及应用
《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。
Camera2Demo
在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作
WeixinApi安全最佳实践:防止微信网页被恶意分享的终极指南
WeixinApi是专门用于微信公众平台的Javascript API,提供了丰富的微信网页交互功能。在日常使用中,防止网页被恶意分享是保障内容安全的重要环节,本文将详细介绍如何利用WeixinApi实现这一目标。 ## 为什么需要防止恶意分享? 恶意分享可能导致多种安全风险,包括: - 未经授权的内容传播 - 钓鱼链接的扩散 - 品牌形象受损 - 用户信息泄露 通过合理配置WeixinAp
douyin-downloader 实操指南:3 个配置搬走无水印抖音视频、博主主页与合集
想存一条抖音视频,大多数人最后拿到的要么是压缩版,要么是贴着水印的残次品。**douyin-downloader 是一个无水印的抖音批量下载工具**:单条视频、图文、合集、原声,甚至整个博主主页,都能成批搬进本地文件夹,还自带重试、限速和去重。正文按"你这次想下载什么"的 3 个真实诉求来写,读完每一节,你就多会一类内容的搬运方式。 ## 单条视频下载配置:把一条抖音链接变成无水印本地文件 这
WeixinApi完全指南:如何在5分钟内实现微信网页分享功能
WeixinApi是专门用于微信公众平台的Javascript API,能够帮助开发者快速实现微信网页分享功能,提升用户体验和内容传播效率。通过简单的配置,即可在微信内置浏览器中实现分享到朋友圈、好友等功能。 ## 为什么选择WeixinApi实现微信分享? 微信作为国内最流行的社交平台之一,拥有庞大的用户群体。在微信环境中实现网页分享功能,能够极大地提高内容的传播范围和用户参与度。Weixi
WeixinApi与官方微信JS-SDK对比分析:哪个更适合你的项目?
微信公众平台开发中,选择合适的Javascript API工具对项目成功至关重要。WeixinApi作为非官方微信JS API解决方案,曾帮助众多开发者实现微信内置功能,而官方微信JS-SDK则提供了更稳定的开发体验。本文将从功能特性、使用难度、兼容性等维度深入对比两者差异,助你快速判断哪个更适合你的开发需求。 ## 一、核心功能对比:谁的能力更全面? ### WeixinApi的特色功能 W
WeixinApi源码深度解析:理解微信JS Bridge通信机制
WeixinApi是专门用于微信公众平台的Javascript API,它通过封装微信内置浏览器的JS Bridge接口,实现了网页与微信客户端之间的高效通信。本文将从源码角度深入剖析其核心通信机制,帮助开发者理解微信生态中网页与客户端交互的底层原理。 ## 微信JS Bridge通信基础 微信内置浏览器通过`WeixinJSBridge`对象提供了网页与客户端原生功能交互的桥梁。Weixin
WeixinApi未来展望:微信生态下的JavaScript API发展趋势
WeixinApi作为专门用于微信公众平台的JavaScript API,曾为开发者提供了丰富的功能支持,包括分享到朋友圈、好友,隐藏菜单入口,获取网络状态等核心能力。随着微信生态的不断演进,这款非官方API的未来发展既面临挑战,也孕育着新的机遇。本文将深入探讨WeixinApi在微信生态下的技术演进方向、潜在应用场景及开发者应对策略。 ## 一、从WeixinApi看微信JS接口的技术演进
macOS Unlocker V4 版本演进深度解析:从 4.0.0 到 4.2.9 的架构重构、安全修复与工具链变迁
macOS Unlocker V4 是一套用 Go 编写、面向 VMware Workstation/Player 的补丁工具,其 [CHANGELOG.md](https://link.gitcode.com/i/a7d878ded37477602f512014b9b8999e) 以英国 DD/MM/YY 日期格式记录了从 4.0.0 初始发布到 4.2.9 的全部技术演进。本文以该变更日志为骨
微信公众平台开发利器WeixinApi:一站式解决12个微信内置浏览器功能集成难题
WeixinApi是一款专门用于微信公众平台的Javascript API,为开发者提供了便捷的微信内置浏览器功能集成方案,轻松解决分享、界面控制、网络状态检测等12大开发难题。无论是新手还是有经验的开发者,都能通过这个强大的工具快速实现微信生态下的各种功能需求。 ## 为什么选择WeixinApi? 微信公众平台开发常常需要与微信内置浏览器的各种功能进行交互,而官方API的使用复杂度较高。W
1万+



被折叠的 条评论
为什么被折叠?



