1
0
mirror of synced 2025-12-15 19:47:58 +08:00

🆕 #3077【小程序】增加openApi管理的接口支持

This commit is contained in:
水依寒
2023-07-12 11:04:59 +08:00
committed by GitHub
parent 9bd7940195
commit 831aac31ba
10 changed files with 362 additions and 4 deletions

View File

@@ -0,0 +1,65 @@
package cn.binarywang.wx.miniapp.api;
import cn.binarywang.wx.miniapp.bean.openapi.WxMiniGetApiQuotaResult;
import cn.binarywang.wx.miniapp.bean.openapi.WxMiniGetRidInfoResult;
import me.chanjar.weixin.common.error.WxErrorException;
/**
* openApi管理
*
* @author shuiyihan12
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/openApi-mgnt/clearQuota.html">openApi管理 微信文档</a>
* @since 2023/7/7 17:07
*/
public interface WxMaOpenApiService {
/**
* 本接口用于清空公众号/小程序/第三方平台等接口的每日调用接口次数
* HTTP调用https://api.weixin.qq.com/cgi-bin/clear_quota?access_token=ACCESS_TOKEN
*
* @return 是否成功
* @throws WxErrorException the wx error exception
* @apiNote !!! 单小程序直接调用该方法 , 如多个appid调用此方法前请调用 {@link cn.binarywang.wx.miniapp.api.WxMaService#switchoverTo} 切换appid !!!
* @code wxMaService.getWxMaOpenApiService().clearQuota() //单个
* @code wxMaService.switchoverTo(" appid ").getWxMaOpenApiService().clearQuota() //多个
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/openApi-mgnt/clearQuota.html">注意事项参考微信文档</a>
*/
boolean clearQuota() throws WxErrorException;
/**
* 查询API调用额度
* HTTP调用https://api.weixin.qq.com/cgi-bin/openapi/quota/get?access_token=ACCESS_TOKEN
*
* @param cgiPath api的请求地址例如"/cgi-bin/message/custom/send";不要前缀“https://api.weixin.qq.com” ,也不要漏了"/",否则都会76003的报错
* @return 额度详情
* @throws WxErrorException 微信异常
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/openApi-mgnt/getApiQuota.html">注意事项参考微信文档</a>
*/
WxMiniGetApiQuotaResult getApiQuota(String cgiPath) throws WxErrorException;
/**
* 查询rid信息
* HTTP调用https://api.weixin.qq.com/cgi-bin/openapi/rid/get?access_token=ACCESS_TOKEN
*
* @param rid 调用接口报错返回的rid
* @return 该rid对应的请求详情
* @throws WxErrorException 微信异常
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/openApi-mgnt/getRidInfo.html">注意事项参考微信文档</a>
*/
WxMiniGetRidInfoResult getRidInfo(String rid) throws WxErrorException;
/**
* 使用AppSecret重置 API 调用次数
* HTTP调用https://api.weixin.qq.com/cgi-bin/clear_quota/v2
*
* @return 是否成功
* @throws WxErrorException 微信异常
* @apiNote !!! 单小程序直接调用该方法 , 如多个appid调用此方法前请调用 {@link cn.binarywang.wx.miniapp.api.WxMaService#switchoverTo} 切换appid!!!
* 参考示例
* @code wxMaService.getWxMaOpenApiService().clearQuotaByAppSecret() //单个
* @code wxMaService.switchoverTo(" appid ").getWxMaOpenApiService().clearQuotaByAppSecret() //多个
* @see <a href="https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/openApi-mgnt/clearQuotaByAppSecret.html">注意事项参考微信文档</a>
*/
boolean clearQuotaByAppSecret() throws WxErrorException;
}

View File

@@ -523,4 +523,10 @@ public interface WxMaService extends WxService {
* @return getWxMaShopPayService
*/
WxMaShopPayService getWxMaShopPayService();
/**
* 小程序openApi管理
* @return getWxMaOpenApiService
*/
WxMaOpenApiService getWxMaOpenApiService();
}

View File

@@ -85,6 +85,7 @@ public abstract class BaseWxMaServiceImpl<H, P> implements WxMaService, RequestH
private final WxMaProductOrderService productOrderService = new WxMaProductOrderServiceImpl(this);
private final WxMaShopCouponService wxMaShopCouponService = new WxMaShopCouponServiceImpl(this);
private final WxMaShopPayService wxMaShopPayService = new WxMaShopPayServiceImpl(this);
private final WxMaOpenApiService wxMaOpenApiService = new WxMaOpenApiServiceImpl(this);
private Map<String, WxMaConfig> configMap;
private int retrySleepMillis = 1000;
private int maxRetryTimes = 5;
@@ -634,4 +635,9 @@ public abstract class BaseWxMaServiceImpl<H, P> implements WxMaService, RequestH
public WxMaShopPayService getWxMaShopPayService() {
return this.wxMaShopPayService;
}
@Override
public WxMaOpenApiService getWxMaOpenApiService() {
return this.wxMaOpenApiService;
}
}

View File

@@ -0,0 +1,81 @@
package cn.binarywang.wx.miniapp.api.impl;
import cn.binarywang.wx.miniapp.api.WxMaOpenApiService;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.openapi.WxMiniGetApiQuotaResult;
import cn.binarywang.wx.miniapp.bean.openapi.WxMiniGetRidInfoResult;
import cn.binarywang.wx.miniapp.constant.WxMaApiUrlConstants;
import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder;
import com.google.gson.JsonObject;
import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.json.GsonParser;
import static me.chanjar.weixin.common.api.WxConsts.ERR_CODE;
/**
* @author shuiyihan12
* @since 2023/7/7 17:08
*/
@RequiredArgsConstructor
public class WxMaOpenApiServiceImpl implements WxMaOpenApiService {
private final WxMaService wxMaService;
private static final String QUOTA = "quota";
private static final String REQUEST = "request";
@Override
public boolean clearQuota() throws WxErrorException {
JsonObject params = new JsonObject();
params.addProperty("appid", this.wxMaService.getWxMaConfig().getAppid());
String responseContent = this.wxMaService.post(WxMaApiUrlConstants.OpenApi.CLEAR_QUOTA, params.toString());
parseErrorResponse(responseContent);
return true;
}
@Override
public WxMiniGetApiQuotaResult getApiQuota(String cgiPath) throws WxErrorException {
JsonObject params = new JsonObject();
params.addProperty("cgi_path", cgiPath);
String responseContent = this.wxMaService.post(WxMaApiUrlConstants.OpenApi.GET_API_QUOTA, params.toString());
parseErrorResponse(responseContent);
JsonObject response = GsonParser.parse(responseContent);
if (response.has(QUOTA)) {
return WxMaGsonBuilder.create().fromJson(response.getAsJsonObject(QUOTA), WxMiniGetApiQuotaResult.class);
}
return null;
}
@Override
public WxMiniGetRidInfoResult getRidInfo(String rid) throws WxErrorException {
JsonObject params = new JsonObject();
params.addProperty("rid", rid);
String responseContent = this.wxMaService.post(WxMaApiUrlConstants.OpenApi.GET_RID_INFO, params.toString());
parseErrorResponse(responseContent);
JsonObject response = GsonParser.parse(responseContent);
if (response.has(REQUEST)) {
return WxMaGsonBuilder.create().fromJson(response.getAsJsonObject(QUOTA), WxMiniGetRidInfoResult.class);
}
return null;
}
@Override
public boolean clearQuotaByAppSecret() throws WxErrorException {
String url = String.format(WxMaApiUrlConstants.OpenApi.CLEAR_QUOTA_BY_APP_SECRET, this.wxMaService.getWxMaConfig().getAppid(), this.wxMaService.getWxMaConfig().getSecret());
String responseContent = this.wxMaService.post(url, "");
parseErrorResponse(responseContent);
return true;
}
private void parseErrorResponse(String response) throws WxErrorException {
JsonObject jsonObject = GsonParser.parse(response);
if (jsonObject.get(ERR_CODE).getAsInt() != 0) {
throw new WxErrorException(WxError.fromJson(response, WxType.MiniApp));
}
}
}

View File

@@ -0,0 +1,28 @@
package cn.binarywang.wx.miniapp.bean.openapi;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
/**
* 查询API调用额度 返回数据
*
* @author shuiyihan12
* @since 2023/7/10 16:52
*/
@Data
public class WxMiniGetApiQuotaResult {
/**
* 当天该账号可调用该接口的次数
*/
@SerializedName("daily_limit")
private Integer dailyLimit;
/**
* 当天已经调用的次数
*/
private Integer used;
/**
* 当天剩余调用次数
*/
private Integer remain;
}

View File

@@ -0,0 +1,44 @@
package cn.binarywang.wx.miniapp.bean.openapi;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
/**
* 查询rid信息 返回数据
* @author shuiyihan12
* @since 2023/7/10 16:53
*/
@Data
public class WxMiniGetRidInfoResult {
/**
* 发起请求的时间戳
*/
@SerializedName("invoke_time")
private Integer invokeTime;
/**
* 请求毫秒级耗时
*/
@SerializedName("cost_in_ms")
private Integer costInMs;
/**
* 请求的URL参数
*/
@SerializedName("request_url")
private String requestUrl;
/**
* post请求的请求参数
*/
@SerializedName("request_body")
private String requestBody;
/**
* 接口请求返回参数
*/
@SerializedName("response_body")
private String responseBody;
/**
* 接口请求的客户端ip
*/
@SerializedName("client_ip")
private String clientIp;
}

View File

@@ -10,6 +10,30 @@ import lombok.experimental.UtilityClass;
*/
@UtilityClass
public class WxMaApiUrlConstants {
/**
* openApi管理
*/
public interface OpenApi {
/**
* 重置API调用次数
*/
String CLEAR_QUOTA = "https://api.weixin.qq.com/cgi-bin/clear_quota";
/**
* 查询API调用额度
*/
String GET_API_QUOTA = "https://api.weixin.qq.com/cgi-bin/openapi/quota/get";
/**
* 查询rid信息
*/
String GET_RID_INFO = "https://api.weixin.qq.com/cgi-bin/openapi/rid/get";
/**
* 使用AppSecret重置 API 调用次数
*/
String CLEAR_QUOTA_BY_APP_SECRET = "https://api.weixin.qq.com/cgi-bin/clear_quota/v2?appid=%s&appsecret=%s";
}
public interface Analysis {
String GET_DAILY_SUMMARY_TREND_URL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailysummarytrend";
String GET_DAILY_VISIT_TREND_URL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailyvisittrend";

View File

@@ -0,0 +1,48 @@
package cn.binarywang.wx.miniapp.api.impl;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.openapi.WxMiniGetApiQuotaResult;
import cn.binarywang.wx.miniapp.test.ApiTestModule;
import com.google.gson.Gson;
import com.google.inject.Inject;
import me.chanjar.weixin.common.error.WxErrorException;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import static org.testng.Assert.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;
/**
* openApi管理测试
*
* @author shuiyihan12
* @since 2023/7/7 17:08
*/
@Test
@Guice(modules = ApiTestModule.class)
public class WxMaOpenApiServiceImplTest {
@Inject
private WxMaService wxMaService;
@Test
public void clearQuota() throws WxErrorException {
final boolean result = wxMaService.getWxMaOpenApiService().clearQuota();
assertTrue(result);
}
@Test
public void getApiQuota() throws WxErrorException {
String cgiPath = "/cgi-bin/openapi/quota/get";
final WxMiniGetApiQuotaResult apiQuota = wxMaService.getWxMaOpenApiService().getApiQuota(cgiPath);
assertNotNull(apiQuota);
System.out.println(new Gson().toJson(apiQuota));
}
@Test
public void clearQuotaByAppSecret() throws WxErrorException {
final boolean result = wxMaService.getWxMaOpenApiService().clearQuotaByAppSecret();
assertTrue(result);
}
}