| @@ -5,6 +5,7 @@ import com.google.gson.JsonArray; | |||
| import me.chanjar.weixin.common.error.WxErrorException; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| /** | |||
| * 云开发相关接口. | |||
| @@ -32,6 +33,8 @@ public interface WxMaCloudService { | |||
| String DATABASE_DELETE_URL = "https://api.weixin.qq.com/tcb/databasedelete"; | |||
| String DATABASE_ADD_URL = "https://api.weixin.qq.com/tcb/databaseadd"; | |||
| String invokeCloudFunction(String name, String body) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 触发云函数。注意:HTTP API 途径触发云函数不包含用户信息。 | |||
| @@ -50,6 +53,12 @@ public interface WxMaCloudService { | |||
| */ | |||
| String invokeCloudFunction(String env, String name, String body) throws WxErrorException; | |||
| List<String> add(String collection, List list) throws WxErrorException; | |||
| String add(String collection, Object obj) throws WxErrorException; | |||
| JsonArray databaseAdd(String query) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 数据库插入记录 | |||
| @@ -65,6 +74,10 @@ public interface WxMaCloudService { | |||
| */ | |||
| JsonArray databaseAdd(String env, String query) throws WxErrorException; | |||
| Integer delete(String collection, String whereJson) throws WxErrorException; | |||
| int databaseDelete(String query) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 数据库删除记录 | |||
| @@ -80,6 +93,10 @@ public interface WxMaCloudService { | |||
| */ | |||
| int databaseDelete(String env, String query) throws WxErrorException; | |||
| WxCloudDatabaseUpdateResult update(String collection, String whereJson, String updateJson) throws WxErrorException; | |||
| WxCloudDatabaseUpdateResult databaseUpdate(String query) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 数据库更新记录 | |||
| @@ -95,6 +112,29 @@ public interface WxMaCloudService { | |||
| */ | |||
| WxCloudDatabaseUpdateResult databaseUpdate(String env, String query) throws WxErrorException; | |||
| /** | |||
| * db.collection('geo') | |||
| * .where({ | |||
| * price: _.gt(10) | |||
| * }) | |||
| * .orderBy('_id', 'asc') | |||
| * .orderBy('price', 'desc') | |||
| * .skip(1) | |||
| * .limit(10) | |||
| * .get() | |||
| * @param collection | |||
| * @param whereJson | |||
| * @param orderBy | |||
| * @param skip | |||
| * @param limit | |||
| * @return | |||
| * @throws WxErrorException | |||
| */ | |||
| WxCloudDatabaseQueryResult query(String collection, String whereJson, Map<String, String> orderBy, | |||
| Integer skip, Integer limit) throws WxErrorException; | |||
| WxCloudDatabaseQueryResult databaseQuery(String query) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 数据库查询记录 | |||
| @@ -110,6 +150,8 @@ public interface WxMaCloudService { | |||
| */ | |||
| WxCloudDatabaseQueryResult databaseQuery(String env, String query) throws WxErrorException; | |||
| JsonArray databaseAggregate(String query) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 数据库聚合记录 | |||
| @@ -125,6 +167,10 @@ public interface WxMaCloudService { | |||
| */ | |||
| JsonArray databaseAggregate(String env, String query) throws WxErrorException; | |||
| Long count(String collection, String whereJson) throws WxErrorException; | |||
| Long databaseCount(String query) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 统计集合记录数或统计查询语句对应的结果记录数 | |||
| @@ -140,6 +186,9 @@ public interface WxMaCloudService { | |||
| */ | |||
| Long databaseCount(String env, String query) throws WxErrorException; | |||
| void updateIndex(String collectionName, List<WxCloudDatabaseCreateIndexRequest> createIndexes, | |||
| List<String> dropIndexNames) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 变更数据库索引 | |||
| @@ -157,11 +206,15 @@ public interface WxMaCloudService { | |||
| void updateIndex(String env, String collectionName, List<WxCloudDatabaseCreateIndexRequest> createIndexes, | |||
| List<String> dropIndexNames) throws WxErrorException; | |||
| Long databaseMigrateImport(String collectionName, String filePath, int fileType, | |||
| boolean stopOnError, int conflictMode) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 数据库导入 | |||
| * | |||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseMigrateImport.html | |||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseMigrateImport | |||
| * .html | |||
| * 请求地址: POST https://api.weixin.qq.com/tcb/databasemigrateimport?access_token=ACCESS_TOKEN | |||
| * </pre> | |||
| * | |||
| @@ -177,11 +230,14 @@ public interface WxMaCloudService { | |||
| Long databaseMigrateImport(String env, String collectionName, String filePath, int fileType, boolean stopOnError, | |||
| int conflictMode) throws WxErrorException; | |||
| Long databaseMigrateExport(String filePath, int fileType, String query) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 数据库导出 | |||
| * | |||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseMigrateExport.html | |||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseMigrateExport | |||
| * .html | |||
| * 请求地址: POST https://api.weixin.qq.com/tcb/databasemigrateexport?access_token=ACCESS_TOKEN | |||
| * </pre> | |||
| * | |||
| @@ -194,11 +250,14 @@ public interface WxMaCloudService { | |||
| */ | |||
| Long databaseMigrateExport(String env, String filePath, int fileType, String query) throws WxErrorException; | |||
| WxCloudCloudDatabaseMigrateQueryInfoResult databaseMigrateQueryInfo(Long jobId) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 数据库迁移状态查询 | |||
| * | |||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseMigrateQueryInfo.html | |||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database | |||
| * /databaseMigrateQueryInfo.html | |||
| * 请求地址:POST https://api.weixin.qq.com/tcb/databasemigratequeryinfo?access_token=ACCESS_TOKEN | |||
| * </pre> | |||
| * | |||
| @@ -209,6 +268,8 @@ public interface WxMaCloudService { | |||
| */ | |||
| WxCloudCloudDatabaseMigrateQueryInfoResult databaseMigrateQueryInfo(String env, Long jobId) throws WxErrorException; | |||
| WxCloudUploadFileResult uploadFile(String path) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 获取文件上传链接 | |||
| @@ -225,6 +286,8 @@ public interface WxMaCloudService { | |||
| */ | |||
| WxCloudUploadFileResult uploadFile(String env, String path) throws WxErrorException; | |||
| WxCloudBatchDownloadFileResult batchDownloadFile(String[] fileIds, long[] maxAges) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 获取文件下载链接 | |||
| @@ -242,6 +305,8 @@ public interface WxMaCloudService { | |||
| */ | |||
| WxCloudBatchDownloadFileResult batchDownloadFile(String env, String[] fileIds, long[] maxAges) throws WxErrorException; | |||
| WxCloudBatchDeleteFileResult batchDeleteFile(String[] fileIds) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 删除文件 | |||
| @@ -272,11 +337,14 @@ public interface WxMaCloudService { | |||
| */ | |||
| WxCloudGetQcloudTokenResult getQcloudToken(long lifeSpan) throws WxErrorException; | |||
| void databaseCollectionAdd(String collectionName) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 新增集合 | |||
| * | |||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCollectionAdd.html | |||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCollectionAdd | |||
| * .html | |||
| * 请求地址:POST https://api.weixin.qq.com/tcb/databasecollectionadd?access_token=ACCESS_TOKEN | |||
| * </pre> | |||
| * | |||
| @@ -286,11 +354,14 @@ public interface WxMaCloudService { | |||
| */ | |||
| void databaseCollectionAdd(String env, String collectionName) throws WxErrorException; | |||
| void databaseCollectionDelete(String collectionName) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 删除集合 | |||
| * | |||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCollectionDelete.html | |||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database | |||
| * /databaseCollectionDelete.html | |||
| * 请求地址:POST https://api.weixin.qq.com/tcb/databasecollectionadd?access_token=ACCESS_TOKEN | |||
| * </pre> | |||
| * | |||
| @@ -300,17 +371,20 @@ public interface WxMaCloudService { | |||
| */ | |||
| void databaseCollectionDelete(String env, String collectionName) throws WxErrorException; | |||
| WxCloudDatabaseCollectionGetResult databaseCollectionGet(Long limit, Long offset) throws WxErrorException; | |||
| /** | |||
| * <pre> | |||
| * 获取特定云环境下集合信息 | |||
| * | |||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCollectionGet.html | |||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCollectionGet | |||
| * .html | |||
| * 请求地址:POST https://api.weixin.qq.com/tcb/databasecollectionget?access_token=ACCESS_TOKEN | |||
| * </pre> | |||
| * | |||
| * @param env 云环境ID | |||
| * @param limit 获取数量限制,默认值:10 | |||
| * @param offset 偏移量,默认值:0 | |||
| * @param env 云环境ID | |||
| * @param limit 获取数量限制,默认值:10 | |||
| * @param offset 偏移量,默认值:0 | |||
| * @return . | |||
| * @throws WxErrorException . | |||
| */ | |||
| @@ -3,20 +3,24 @@ package cn.binarywang.wx.miniapp.api.impl; | |||
| import cn.binarywang.wx.miniapp.api.WxMaCloudService; | |||
| import cn.binarywang.wx.miniapp.api.WxMaService; | |||
| import cn.binarywang.wx.miniapp.bean.cloud.*; | |||
| import cn.binarywang.wx.miniapp.constant.WxMaConstants; | |||
| import cn.binarywang.wx.miniapp.util.JoinerUtils; | |||
| import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | |||
| import com.google.common.collect.ImmutableMap; | |||
| import com.google.common.collect.Lists; | |||
| import com.google.gson.JsonArray; | |||
| import com.google.gson.JsonElement; | |||
| import com.google.gson.JsonObject; | |||
| import com.google.gson.JsonParser; | |||
| import lombok.RequiredArgsConstructor; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import me.chanjar.weixin.common.error.WxError; | |||
| import me.chanjar.weixin.common.error.WxErrorException; | |||
| import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import java.io.Serializable; | |||
| import java.util.HashMap; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| import java.util.*; | |||
| /** | |||
| * 云开发相关接口实现类. | |||
| @@ -30,48 +34,225 @@ public class WxMaCloudServiceImpl implements WxMaCloudService { | |||
| private static final JsonParser JSON_PARSER = new JsonParser(); | |||
| private final WxMaService wxMaService; | |||
| @Override | |||
| public String invokeCloudFunction(String name, String body) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| return invokeCloudFunction(cloudEnv, name, body); | |||
| } | |||
| @Override | |||
| public String invokeCloudFunction(String env, String name, String body) throws WxErrorException { | |||
| final String response = this.wxMaService.post(String.format(INVOKE_CLOUD_FUNCTION_URL, env, name), body); | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| final String response = this.wxMaService.post(String.format(INVOKE_CLOUD_FUNCTION_URL, cloudEnv, name), body); | |||
| return JSON_PARSER.parse(response).getAsJsonObject().get("resp_data").getAsString(); | |||
| } | |||
| @Override | |||
| public List<String> add(String collection, List list) throws WxErrorException { | |||
| String jsonData = WxMaGsonBuilder.create().toJson(list); | |||
| String query = JoinerUtils.blankJoiner.join( | |||
| "db.collection('", collection, "')", | |||
| ".add({data: ", jsonData, "})"); | |||
| JsonObject params = new JsonObject(); | |||
| params.addProperty("env", this.wxMaService.getWxMaConfig().getCloudEnv()); | |||
| params.addProperty("query", query); | |||
| String responseContent = wxMaService.post(DATABASE_ADD_URL, params.toString()); | |||
| JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); | |||
| JsonObject jsonObject = tmpJsonElement.getAsJsonObject(); | |||
| if (jsonObject.get(WxMaConstants.ERRCODE).getAsInt() != 0) { | |||
| throw new WxErrorException(WxError.fromJson(responseContent)); | |||
| } | |||
| JsonArray idArray = jsonObject.getAsJsonArray("id_list"); | |||
| List<String> idList = new ArrayList<>(); | |||
| Iterator<JsonElement> idIterator = idArray.iterator(); | |||
| while (idIterator.hasNext()) { | |||
| JsonElement id = idIterator.next(); | |||
| idList.add(id.getAsString()); | |||
| } | |||
| return idList; | |||
| } | |||
| @Override | |||
| public String add(String collection, Object obj) throws WxErrorException { | |||
| String jsonData = WxMaGsonBuilder.create().toJson(obj); | |||
| String query = JoinerUtils.blankJoiner.join( | |||
| "db.collection('", collection, "')", | |||
| ".add({data: ", jsonData, "})"); | |||
| JsonObject params = new JsonObject(); | |||
| params.addProperty("env", this.wxMaService.getWxMaConfig().getCloudEnv()); | |||
| params.addProperty("query", query); | |||
| String responseContent = wxMaService.post(DATABASE_ADD_URL, params.toString()); | |||
| JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); | |||
| JsonObject jsonObject = tmpJsonElement.getAsJsonObject(); | |||
| if (jsonObject.get(WxMaConstants.ERRCODE).getAsInt() != 0) { | |||
| throw new WxErrorException(WxError.fromJson(responseContent)); | |||
| } | |||
| JsonArray idArray = jsonObject.getAsJsonArray("id_list"); | |||
| return idArray.getAsString(); | |||
| } | |||
| @Override | |||
| public JsonArray databaseAdd(String query) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| return databaseAdd(cloudEnv, query); | |||
| } | |||
| @Override | |||
| public JsonArray databaseAdd(String env, String query) throws WxErrorException { | |||
| String response = this.wxMaService.post(DATABASE_ADD_URL, ImmutableMap.of("env", env, "query", query)); | |||
| return JSON_PARSER.parse(response).getAsJsonObject().get("id_list").getAsJsonArray(); | |||
| } | |||
| @Override | |||
| public Integer delete(String collection, String whereJson) throws WxErrorException { | |||
| String query = JoinerUtils.blankJoiner.join( | |||
| "db.collection('", collection, "')", | |||
| ".where(", whereJson, ").remove()"); | |||
| JsonObject params = new JsonObject(); | |||
| params.addProperty("env", this.wxMaService.getWxMaConfig().getCloudEnv()); | |||
| params.addProperty("query", query); | |||
| String responseContent = wxMaService.post(DATABASE_DELETE_URL, params.toString()); | |||
| JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent); | |||
| JsonObject jsonObject = tmpJsonElement.getAsJsonObject(); | |||
| if (jsonObject.get(WxMaConstants.ERRCODE).getAsInt() != 0) { | |||
| throw new WxErrorException(WxError.fromJson(responseContent)); | |||
| } | |||
| Integer deletedNum = jsonObject.get("deleted").getAsInt(); | |||
| return deletedNum; | |||
| } | |||
| @Override | |||
| public int databaseDelete(String query) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| return databaseDelete(cloudEnv, query); | |||
| } | |||
| @Override | |||
| public int databaseDelete(String env, String query) throws WxErrorException { | |||
| String response = this.wxMaService.post(DATABASE_DELETE_URL, ImmutableMap.of("env", env, "query", query)); | |||
| return JSON_PARSER.parse(response).getAsJsonObject().get("deleted").getAsInt(); | |||
| } | |||
| @Override | |||
| public WxCloudDatabaseUpdateResult update(String collection, String whereJson, String updateJson) throws WxErrorException { | |||
| String query = JoinerUtils.blankJoiner.join( | |||
| "db.collection('", collection, "')", | |||
| ".where(", whereJson, ").update({data:", updateJson, " })"); | |||
| JsonObject params = new JsonObject(); | |||
| params.addProperty("env", this.wxMaService.getWxMaConfig().getCloudEnv()); | |||
| params.addProperty("query", query); | |||
| String responseContent = wxMaService.post(DATABASE_UPDATE_URL, params.toString()); | |||
| return WxGsonBuilder.create().fromJson(responseContent, WxCloudDatabaseUpdateResult.class); | |||
| } | |||
| @Override | |||
| public WxCloudDatabaseUpdateResult databaseUpdate(String query) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| return databaseUpdate(cloudEnv, query); | |||
| } | |||
| @Override | |||
| public WxCloudDatabaseUpdateResult databaseUpdate(String env, String query) throws WxErrorException { | |||
| String response = this.wxMaService.post(DATABASE_UPDATE_URL, ImmutableMap.of("env", env, "query", query)); | |||
| return WxGsonBuilder.create().fromJson(response, WxCloudDatabaseUpdateResult.class); | |||
| } | |||
| @Override | |||
| public WxCloudDatabaseQueryResult query(String collection, String whereJson, Map<String, String> orderBy, | |||
| Integer skip, Integer limit) throws WxErrorException { | |||
| if (StringUtils.isBlank(whereJson)) { | |||
| whereJson = "{}"; | |||
| } | |||
| StringBuilder orderBySb = new StringBuilder(); | |||
| if (null != orderBy && !orderBy.isEmpty()) { | |||
| orderBy.entrySet().forEach( | |||
| e -> orderBySb.append(".orderBy('").append(e.getKey()).append("', '").append(e.getValue()).append("')") | |||
| ); | |||
| } | |||
| if (null == limit) { | |||
| limit = 100; | |||
| } | |||
| if (null == skip) { | |||
| skip = 0; | |||
| } | |||
| String query = JoinerUtils.blankJoiner.join( | |||
| "db.collection('", collection, "')", | |||
| ".where(", whereJson, ")", orderBySb.toString(), ".skip(", skip, ").limit(", limit, ").get()"); | |||
| JsonObject params = new JsonObject(); | |||
| params.addProperty("env", this.wxMaService.getWxMaConfig().getCloudEnv()); | |||
| params.addProperty("query", query); | |||
| String responseContent = wxMaService.post(DATABASE_QUERY_URL, params.toString()); | |||
| return WxGsonBuilder.create().fromJson(responseContent, WxCloudDatabaseQueryResult.class); | |||
| } | |||
| @Override | |||
| public WxCloudDatabaseQueryResult databaseQuery(String query) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| return databaseQuery(cloudEnv, query); | |||
| } | |||
| @Override | |||
| public WxCloudDatabaseQueryResult databaseQuery(String env, String query) throws WxErrorException { | |||
| String response = this.wxMaService.post(DATABASE_QUERY_URL, ImmutableMap.of("env", env, "query", query)); | |||
| return WxGsonBuilder.create().fromJson(response, WxCloudDatabaseQueryResult.class); | |||
| } | |||
| @Override | |||
| public JsonArray databaseAggregate(String query) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| return databaseAggregate(cloudEnv, query); | |||
| } | |||
| @Override | |||
| public JsonArray databaseAggregate(String env, String query) throws WxErrorException { | |||
| String response = this.wxMaService.post(DATABASE_AGGREGATE_URL, ImmutableMap.of("env", env, "query", query)); | |||
| return JSON_PARSER.parse(response).getAsJsonObject().get("data").getAsJsonArray(); | |||
| } | |||
| @Override | |||
| public Long count(String collection, String whereJson) throws WxErrorException { | |||
| String query = JoinerUtils.blankJoiner.join( | |||
| "db.collection('", collection, "')", | |||
| ".where(", whereJson, ").count()"); | |||
| JsonObject params = new JsonObject(); | |||
| params.addProperty("env", this.wxMaService.getWxMaConfig().getCloudEnv()); | |||
| params.addProperty("query", query); | |||
| String responseContent = wxMaService.post(DATABASE_COUNT_URL, params.toString()); | |||
| return JSON_PARSER.parse(responseContent).getAsJsonObject().get("count").getAsLong(); | |||
| } | |||
| @Override | |||
| public Long databaseCount(String query) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| return databaseCount(cloudEnv, query); | |||
| } | |||
| @Override | |||
| public Long databaseCount(String env, String query) throws WxErrorException { | |||
| String response = this.wxMaService.post(DATABASE_COUNT_URL, ImmutableMap.of("env", env, "query", query)); | |||
| return JSON_PARSER.parse(response).getAsJsonObject().get("count").getAsLong(); | |||
| } | |||
| @Override | |||
| public void updateIndex(String collectionName, List<WxCloudDatabaseCreateIndexRequest> createIndexes, | |||
| List<String> dropIndexNames) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| updateIndex(cloudEnv, collectionName, createIndexes, dropIndexNames); | |||
| } | |||
| @Override | |||
| public void updateIndex(String env, String collectionName, List<WxCloudDatabaseCreateIndexRequest> createIndexes, | |||
| List<String> dropIndexNames) throws WxErrorException { | |||
| @@ -86,6 +267,13 @@ public class WxMaCloudServiceImpl implements WxMaCloudService { | |||
| "collection_name", collectionName, "create_indexes", createIndexes, "drop_indexes", dropIndexes)); | |||
| } | |||
| @Override | |||
| public Long databaseMigrateImport(String collectionName, String filePath, int fileType, | |||
| boolean stopOnError, int conflictMode) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| return databaseMigrateImport(cloudEnv, collectionName, filePath, fileType, stopOnError, conflictMode); | |||
| } | |||
| @Override | |||
| public Long databaseMigrateImport(String env, String collectionName, String filePath, int fileType, | |||
| boolean stopOnError, int conflictMode) throws WxErrorException { | |||
| @@ -101,6 +289,12 @@ public class WxMaCloudServiceImpl implements WxMaCloudService { | |||
| return JSON_PARSER.parse(response).getAsJsonObject().get("job_id").getAsLong(); | |||
| } | |||
| @Override | |||
| public Long databaseMigrateExport(String filePath, int fileType, String query) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| return databaseMigrateExport(cloudEnv, filePath, fileType, query); | |||
| } | |||
| @Override | |||
| public Long databaseMigrateExport(String env, String filePath, int fileType, String query) throws WxErrorException { | |||
| JsonObject params = new JsonObject(); | |||
| @@ -113,18 +307,37 @@ public class WxMaCloudServiceImpl implements WxMaCloudService { | |||
| return JSON_PARSER.parse(response).getAsJsonObject().get("job_id").getAsLong(); | |||
| } | |||
| @Override | |||
| public WxCloudCloudDatabaseMigrateQueryInfoResult databaseMigrateQueryInfo(Long jobId) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| return databaseMigrateQueryInfo(cloudEnv, jobId); | |||
| } | |||
| @Override | |||
| public WxCloudCloudDatabaseMigrateQueryInfoResult databaseMigrateQueryInfo(String env, Long jobId) throws WxErrorException { | |||
| String response = this.wxMaService.post(DATABASE_MIGRATE_QUERY_INFO_URL, ImmutableMap.of("env", env, "job_id", jobId)); | |||
| String response = this.wxMaService.post(DATABASE_MIGRATE_QUERY_INFO_URL, ImmutableMap.of("env", env, "job_id", | |||
| jobId)); | |||
| return WxGsonBuilder.create().fromJson(response, WxCloudCloudDatabaseMigrateQueryInfoResult.class); | |||
| } | |||
| @Override | |||
| public WxCloudUploadFileResult uploadFile(String path) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| return uploadFile(cloudEnv, path); | |||
| } | |||
| @Override | |||
| public WxCloudUploadFileResult uploadFile(String env, String path) throws WxErrorException { | |||
| String response = this.wxMaService.post(UPLOAD_FILE_URL, ImmutableMap.of("env", env, "path", path)); | |||
| return WxGsonBuilder.create().fromJson(response, WxCloudUploadFileResult.class); | |||
| } | |||
| @Override | |||
| public WxCloudBatchDownloadFileResult batchDownloadFile(String[] fileIds, long[] maxAges) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| return batchDownloadFile(cloudEnv, fileIds, maxAges); | |||
| } | |||
| @Override | |||
| public WxCloudBatchDownloadFileResult batchDownloadFile(String env, String[] fileIds, long[] maxAges) throws WxErrorException { | |||
| List<Map<String, Serializable>> fileList = Lists.newArrayList(); | |||
| @@ -137,6 +350,12 @@ public class WxMaCloudServiceImpl implements WxMaCloudService { | |||
| return WxGsonBuilder.create().fromJson(response, WxCloudBatchDownloadFileResult.class); | |||
| } | |||
| @Override | |||
| public WxCloudBatchDeleteFileResult batchDeleteFile(String[] fileIds) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| return batchDeleteFile(cloudEnv, fileIds); | |||
| } | |||
| @Override | |||
| public WxCloudBatchDeleteFileResult batchDeleteFile(String env, String[] fileIds) throws WxErrorException { | |||
| String response = this.wxMaService.post(BATCH_DELETE_FILE_URL, ImmutableMap.of("env", env, "fileid_list", fileIds)); | |||
| @@ -149,14 +368,33 @@ public class WxMaCloudServiceImpl implements WxMaCloudService { | |||
| return WxGsonBuilder.create().fromJson(response, WxCloudGetQcloudTokenResult.class); | |||
| } | |||
| @Override | |||
| public void databaseCollectionAdd(String collectionName) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| databaseCollectionAdd(cloudEnv, collectionName); | |||
| } | |||
| @Override | |||
| public void databaseCollectionAdd(String env, String collectionName) throws WxErrorException { | |||
| this.wxMaService.post(DATABASE_COLLECTION_ADD_URL, ImmutableMap.of("env", env, "collection_name", collectionName)); | |||
| } | |||
| @Override | |||
| public void databaseCollectionDelete(String collectionName) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| databaseCollectionDelete(cloudEnv, collectionName); | |||
| } | |||
| @Override | |||
| public void databaseCollectionDelete(String env, String collectionName) throws WxErrorException { | |||
| this.wxMaService.post(DATABASE_COLLECTION_DELETE_URL, ImmutableMap.of("env", env, "collection_name", collectionName)); | |||
| this.wxMaService.post(DATABASE_COLLECTION_DELETE_URL, ImmutableMap.of("env", env, "collection_name", | |||
| collectionName)); | |||
| } | |||
| @Override | |||
| public WxCloudDatabaseCollectionGetResult databaseCollectionGet(Long limit, Long offset) throws WxErrorException { | |||
| String cloudEnv = this.wxMaService.getWxMaConfig().getCloudEnv(); | |||
| return databaseCollectionGet(cloudEnv, limit, offset); | |||
| } | |||
| @Override | |||
| @@ -174,5 +412,4 @@ public class WxMaCloudServiceImpl implements WxMaCloudService { | |||
| String response = this.wxMaService.post(DATABASE_COLLECTION_GET_URL, params); | |||
| return WxGsonBuilder.create().fromJson(response, WxCloudDatabaseCollectionGetResult.class); | |||
| } | |||
| } | |||
| @@ -87,6 +87,10 @@ public interface WxMaConfig { | |||
| String getAesKey(); | |||
| String getOriginalId(); | |||
| String getCloudEnv(); | |||
| String getMsgDataFormat(); | |||
| long getExpiresTime(); | |||
| @@ -1,51 +1,53 @@ | |||
| package cn.binarywang.wx.miniapp.config.impl; | |||
| import java.io.File; | |||
| import java.util.concurrent.locks.Lock; | |||
| import java.util.concurrent.locks.ReentrantLock; | |||
| import cn.binarywang.wx.miniapp.config.WxMaConfig; | |||
| import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | |||
| import me.chanjar.weixin.common.bean.WxAccessToken; | |||
| import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | |||
| import java.io.File; | |||
| import java.util.concurrent.locks.Lock; | |||
| import java.util.concurrent.locks.ReentrantLock; | |||
| /** | |||
| * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化 | |||
| * | |||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
| */ | |||
| public class WxMaDefaultConfigImpl implements WxMaConfig { | |||
| private volatile String msgDataFormat; | |||
| protected volatile String appid; | |||
| private volatile String secret; | |||
| protected volatile String token; | |||
| /** | |||
| * 小程序原始ID | |||
| */ | |||
| protected volatile String originalId; | |||
| protected Lock accessTokenLock = new ReentrantLock(); | |||
| /** | |||
| * 临时文件目录. | |||
| */ | |||
| protected volatile File tmpDirFile; | |||
| private volatile String msgDataFormat; | |||
| private volatile String secret; | |||
| private volatile String accessToken; | |||
| private volatile String aesKey; | |||
| private volatile long expiresTime; | |||
| /** | |||
| * 云环境ID | |||
| */ | |||
| private volatile String cloudEnv; | |||
| private volatile String httpProxyHost; | |||
| private volatile int httpProxyPort; | |||
| private volatile String httpProxyUsername; | |||
| private volatile String httpProxyPassword; | |||
| private volatile String jsapiTicket; | |||
| private volatile long jsapiTicketExpiresTime; | |||
| /** | |||
| * 微信卡券的ticket单独缓存. | |||
| */ | |||
| private volatile String cardApiTicket; | |||
| private volatile long cardApiTicketExpiresTime; | |||
| protected Lock accessTokenLock = new ReentrantLock(); | |||
| private Lock jsapiTicketLock = new ReentrantLock(); | |||
| private Lock cardApiTicketLock = new ReentrantLock(); | |||
| /** | |||
| * 临时文件目录. | |||
| */ | |||
| protected volatile File tmpDirFile; | |||
| private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; | |||
| /** | |||
| @@ -190,6 +192,24 @@ public class WxMaDefaultConfigImpl implements WxMaConfig { | |||
| this.aesKey = aesKey; | |||
| } | |||
| @Override | |||
| public String getOriginalId() { | |||
| return originalId; | |||
| } | |||
| public void setOriginalId(String originalId) { | |||
| this.originalId = originalId; | |||
| } | |||
| @Override | |||
| public String getCloudEnv() { | |||
| return this.cloudEnv; | |||
| } | |||
| public void setCloudEnv(String cloudEnv) { | |||
| this.cloudEnv = cloudEnv; | |||
| } | |||
| @Override | |||
| public String getMsgDataFormat() { | |||
| return this.msgDataFormat; | |||
| @@ -0,0 +1,253 @@ | |||
| /** | |||
| * Copyright (c) 2019,sunnybs. | |||
| * All Rights Reserved. | |||
| * <p> | |||
| * Project Name:yigou | |||
| */ | |||
| package cn.binarywang.wx.miniapp.util; | |||
| import com.google.common.base.Joiner; | |||
| /** | |||
| * ClassName: JoinerUtils <br/> | |||
| * Description: 字符串连接器 <br/> | |||
| * Date: 2019年10月18日 下午1:42:59 <br/> | |||
| * | |||
| * @author <a href="https://gitee.com/esunego_hunan/weixin-java-tools">wsp</a> | |||
| */ | |||
| public class JoinerUtils { | |||
| private static final String NULL = "null"; | |||
| /** | |||
| * <p> | |||
| * 空白连接器,忽略null | |||
| * </p> | |||
| * | |||
| * <pre> | |||
| * JoinerUtils.blankJoiner.join("a", "b", "c"); | |||
| * <b>result : </b>abc | |||
| * | |||
| * JoinerUtils.blankJoiner.join("a", null, "c"); | |||
| * <b>result : </b>ac | |||
| * </pre> | |||
| */ | |||
| public static final Joiner blankJoiner = Joiner.on("").skipNulls(); | |||
| /** | |||
| * <p> | |||
| * 空白连接器 | |||
| * </p> | |||
| * | |||
| * <pre> | |||
| * JoinerUtils.blankJoinerWithNull.join("a", "b", "c"); | |||
| * <b>result : </b>abc | |||
| * | |||
| * JoinerUtils.blankJoinerWithNull.join("a", null, "c"); | |||
| * <b>result : </b>anullc | |||
| * </pre> | |||
| */ | |||
| public static final Joiner blankJoinerWithNull = Joiner.on("").useForNull(NULL); | |||
| /** | |||
| * <p> | |||
| * 空格连接器,忽略null | |||
| * </p> | |||
| * | |||
| * <pre> | |||
| * JoinerUtils.spaceJoiner.join("a", "b", "c"); | |||
| * <b>result : </b>a b c | |||
| * | |||
| * JoinerUtils.spaceJoiner.join("a", null, "c"); | |||
| * <b>result : </b>a c | |||
| * </pre> | |||
| */ | |||
| public static final Joiner spaceJoiner = Joiner.on(" ").skipNulls(); | |||
| /** | |||
| * <p> | |||
| * 空格连接器 | |||
| * </p> | |||
| * | |||
| * <pre> | |||
| * JoinerUtils.spaceJoinerWithNull.join("a", "b", "c"); | |||
| * <b>result : </b>a b c | |||
| * | |||
| * JoinerUtils.spaceJoinerWithNull.join("a", null, "c"); | |||
| * <b>result : </b>a null c | |||
| * </pre> | |||
| */ | |||
| public static final Joiner spaceJoinerWithNull = Joiner.on(" ").useForNull(NULL); | |||
| /** | |||
| * <p> | |||
| * 逗号分隔符连接器,忽略null | |||
| * </p> | |||
| * | |||
| * <pre> | |||
| * JoinerUtils.commaJoiner.join("a", "b", "c"); | |||
| * <b>result : </b>a,b,c | |||
| * | |||
| * JoinerUtils.commaJoiner.join("a", null, "c"); | |||
| * <b>result : </b>a,c | |||
| * </pre> | |||
| */ | |||
| public static final Joiner commaJoiner = Joiner.on(",").skipNulls(); | |||
| /** | |||
| * <p> | |||
| * 逗号分隔符连接器 | |||
| * </p> | |||
| * | |||
| * <pre> | |||
| * JoinerUtils.commaJoinerWithNull.join("a", "b", "c"); | |||
| * <b>result : </b>a,b,c | |||
| * | |||
| * JoinerUtils.commaJoinerWithNull.join("a", null, "c"); | |||
| * <b>result : </b>a,null,c | |||
| * </pre> | |||
| */ | |||
| public static final Joiner commaJoinerWithNull = Joiner.on(",").useForNull(NULL); | |||
| /** | |||
| * <p> | |||
| * 等号分隔符连接器,忽略null | |||
| * </p> | |||
| * | |||
| * <pre> | |||
| * JoinerUtils.equalJoiner.join("a", "b", "c"); | |||
| * <b>result : </b>a=b=c | |||
| * | |||
| * JoinerUtils.equalJoiner.join("a", null, "c"); | |||
| * <b>result : </b>a=c | |||
| * </pre> | |||
| */ | |||
| public static final Joiner equalJoiner = Joiner.on("=").skipNulls(); | |||
| /** | |||
| * <p> | |||
| * 等号分隔符连接器 | |||
| * </p> | |||
| * | |||
| * <pre> | |||
| * JoinerUtils.equalJoinerWithNull.join("a", "b", "c"); | |||
| * <b>result : </b>a=b=c | |||
| * | |||
| * JoinerUtils.equalJoinerWithNull.join("a", null, "c"); | |||
| * <b>result : </b>a=null=c | |||
| * </pre> | |||
| */ | |||
| public static final Joiner equalJoinerWithNull = Joiner.on("=").useForNull(NULL); | |||
| /** | |||
| * <p> | |||
| * 竖线分隔符连接器,忽略null | |||
| * </p> | |||
| * | |||
| * <pre> | |||
| * JoinerUtils.vLineJoiner.join("a", "b", "c"); | |||
| * <b>result : </b>a|b|c | |||
| * | |||
| * JoinerUtils.vLineJoiner.join("a", null, "c"); | |||
| * <b>result : </b>a|c | |||
| * </pre> | |||
| */ | |||
| public static final Joiner vLineJoiner = Joiner.on("|").skipNulls(); | |||
| /** | |||
| * <p> | |||
| * 竖线分隔符连接器 | |||
| * </p> | |||
| * | |||
| * <pre> | |||
| * JoinerUtils.vLineJoinerWithNull.join("a", "b", "c"); | |||
| * <b>result : </b>a|b|c | |||
| * | |||
| * JoinerUtils.vLineJoinerWithNull.join("a", null, "c"); | |||
| * <b>result : </b>a|null|c | |||
| * </pre> | |||
| */ | |||
| public static final Joiner vLineJoinerWithNull = Joiner.on("|").useForNull(NULL); | |||
| /** | |||
| * <p> | |||
| * 中横线分隔符连接器,忽略null | |||
| * </p> | |||
| * | |||
| * <pre> | |||
| * JoinerUtils.hLineJoiner.join("a", "b", "c"); | |||
| * <b>result : </b>a-b-c | |||
| * | |||
| * JoinerUtils.hLineJoiner.join("a", null, "c"); | |||
| * <b>result : </b>a-c | |||
| * </pre> | |||
| */ | |||
| public static final Joiner hLineJoiner = Joiner.on("-").skipNulls(); | |||
| /** | |||
| * <p> | |||
| * 中横线分隔符连接器 | |||
| * </p> | |||
| * | |||
| * <pre> | |||
| * JoinerUtils.hLineJoinerWithNull.join("a", "b", "c"); | |||
| * <b>result : </b>a-b-c | |||
| * | |||
| * JoinerUtils.hLineJoinerWithNull.join("a", null, "c"); | |||
| * <b>result : </b>a-null-c | |||
| * </pre> | |||
| */ | |||
| public static final Joiner hLineJoinerWithNull = Joiner.on("-").useForNull(NULL); | |||
| /** | |||
| * <p> | |||
| * 下划线分隔符连接器,忽略null | |||
| * </p> | |||
| * | |||
| * <pre> | |||
| * JoinerUtils.underlineJoiner.join("a", "b", "c"); | |||
| * <b>result : </b>a_b_c | |||
| * | |||
| * JoinerUtils.underlineJoiner.join("a", null, "c"); | |||
| * <b>result : </b>a_c | |||
| * </pre> | |||
| */ | |||
| public static final Joiner underlineJoiner = Joiner.on("_").skipNulls(); | |||
| /** | |||
| * <p> | |||
| * 下划线分隔符连接器 | |||
| * </p> | |||
| * | |||
| * <pre> | |||
| * JoinerUtils.underlineJoinerWithNull.join("a", "b", "c"); | |||
| * <b>result : </b>a_b_c | |||
| * | |||
| * JoinerUtils.underlineJoinerWithNull.join("a", null, "c"); | |||
| * <b>result : </b>a_null_c | |||
| * </pre> | |||
| */ | |||
| public static final Joiner underlineJoinerWithNull = Joiner.on("_").useForNull(NULL); | |||
| /** | |||
| * <p> | |||
| * 斜线分隔符连接器,忽略null | |||
| * </p> | |||
| * | |||
| * <pre> | |||
| * JoinerUtils.pathJoiner.join("a", "b", "c"); | |||
| * <b>result : </b>a/b/c | |||
| * | |||
| * JoinerUtils.pathJoiner.join("a", null, "c"); | |||
| * <b>result : </b>a/c | |||
| * </pre> | |||
| */ | |||
| public static final Joiner pathJoiner = Joiner.on("/").skipNulls(); | |||
| /** | |||
| * <p> | |||
| * 斜线分隔符连接器 | |||
| * </p> | |||
| * | |||
| * <pre> | |||
| * JoinerUtils.pathJoinerWithNull.join("a", "b", "c"); | |||
| * <b>result : </b>a/b/c | |||
| * | |||
| * JoinerUtils.pathJoinerWithNull.join("a", null, "c"); | |||
| * <b>result : </b>a/null/c | |||
| * </pre> | |||
| */ | |||
| public static final Joiner pathJoinerWithNull = Joiner.on("/").useForNull(NULL); | |||
| } | |||
| @@ -3,13 +3,19 @@ package cn.binarywang.wx.miniapp.api.impl; | |||
| import cn.binarywang.wx.miniapp.api.WxMaService; | |||
| import cn.binarywang.wx.miniapp.bean.cloud.*; | |||
| import cn.binarywang.wx.miniapp.test.ApiTestModule; | |||
| import com.google.common.collect.ImmutableSortedMap; | |||
| import com.google.common.collect.Lists; | |||
| import com.google.common.collect.Ordering; | |||
| import com.google.gson.JsonArray; | |||
| import com.google.inject.Inject; | |||
| import me.chanjar.weixin.common.error.WxErrorException; | |||
| import org.testng.annotations.BeforeTest; | |||
| import org.testng.annotations.Guice; | |||
| import org.testng.annotations.Test; | |||
| import java.math.BigDecimal; | |||
| import java.util.*; | |||
| import static org.assertj.core.api.Assertions.assertThat; | |||
| /** | |||
| @@ -20,18 +26,89 @@ import static org.assertj.core.api.Assertions.assertThat; | |||
| */ | |||
| @Guice(modules = ApiTestModule.class) | |||
| public class WxMaCloudServiceImplTest { | |||
| private static final String COLLECTION = "geo"; | |||
| @Inject | |||
| private WxMaService wxMaService; | |||
| @BeforeTest | |||
| public void before() { | |||
| /** | |||
| * 用以解决:javax.net.ssl.SSLHandshakeException: PKIX path building failed | |||
| * 参考:https://www.cnblogs.com/cloudapps/p/5022544.html | |||
| */ | |||
| String mpCert = ClassLoader.getSystemResource("wx-mp-jssecacerts").getPath(); | |||
| String maCert = ClassLoader.getSystemResource("wx-ma-jssecacerts").getPath(); | |||
| System.setProperty("javax.net.ssl.trustStore", mpCert + "," + maCert); | |||
| String property = System.getProperty("javax.net.ssl.trustStore"); | |||
| System.out.println("javax.net.ssl.trustStore=" + property); | |||
| } | |||
| @Test | |||
| public void testInvokeCloudFunction() throws WxErrorException { | |||
| final String result = this.wxMaService.getCloudService().invokeCloudFunction("rcn", "login", "{}"); | |||
| final String result = this.wxMaService.getCloudService().invokeCloudFunction("login", "{}"); | |||
| assertThat(result).isNotNull(); | |||
| } | |||
| @Test | |||
| public void testAddList() throws WxErrorException { | |||
| List<Map> stuList = new ArrayList<>(); | |||
| Map<String, Object> product1 = new HashMap<>(); | |||
| product1.put("description", "item1"); | |||
| product1.put("price", BigDecimal.valueOf(1.2)); | |||
| product1.put("due", new Date()); | |||
| /** | |||
| * 等价于new db.Geo.Point(113, 23) | |||
| * 参见:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-sdk-api/database/geo/Geo.Point.html | |||
| */ | |||
| Map<String, Object> point = new HashMap<>(); | |||
| point.put("type", "Point"); | |||
| point.put("coordinates", new Integer[]{113, 23}); | |||
| Map<String, Object> product2 = new HashMap<>(); | |||
| product2.put("tags", new String[]{"cloud", "database"}); | |||
| product2.put("location", point); | |||
| product2.put("done", false); | |||
| stuList.add(product1); | |||
| stuList.add(product2); | |||
| List<String> idList = this.wxMaService.getCloudService().add(COLLECTION, stuList); | |||
| System.out.println(idList.size()); | |||
| assertThat(idList).isNotEmpty(); | |||
| } | |||
| @Test | |||
| public void testAddObject() throws WxErrorException { | |||
| /** | |||
| * 等价于new db.Geo.Point(113, 23) | |||
| * 参见:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-sdk-api/database/geo/Geo.Point.html | |||
| */ | |||
| Map<String, Object> point = new HashMap<>(); | |||
| point.put("type", "Point"); | |||
| point.put("coordinates", new Integer[]{113, 23}); | |||
| Map<String, Object> product = new HashMap<>(); | |||
| product.put("description", "item1"); | |||
| product.put("price", BigDecimal.valueOf(1.2)); | |||
| product.put("due", new Date()); | |||
| product.put("tags", new String[]{"cloud", "database"}); | |||
| product.put("location", point); | |||
| product.put("done", false); | |||
| String id = this.wxMaService.getCloudService().add(COLLECTION, product); | |||
| System.out.println(id); | |||
| assertThat(id).isNotBlank(); | |||
| } | |||
| @Test | |||
| public void testDatabaseAdd() throws WxErrorException { | |||
| JsonArray array = this.wxMaService.getCloudService().databaseAdd("rcn", "db.collection(\"geo\").add({\n" + | |||
| JsonArray array = this.wxMaService.getCloudService().databaseAdd("db.collection(\"geo\").add({\n" + | |||
| " data: [{\n" + | |||
| " description: \"item1\",\n" + | |||
| " due:\n" + | |||
| @@ -63,16 +140,59 @@ public class WxMaCloudServiceImplTest { | |||
| assertThat(array).isNotEmpty(); | |||
| } | |||
| @Test | |||
| public void testDelete() throws WxErrorException { | |||
| StringBuilder whereParamSb = new StringBuilder(); | |||
| whereParamSb.append("{") | |||
| // 等于 | |||
| .append("_id: _.eq('79a2c43f5e7e9e8e001a120e494d51b8'),") | |||
| // in | |||
| .append("age: _.in([0, 1, 2, 3]),") | |||
| // 小于 | |||
| .append("due: _.lt('Mar 29, 2020 8:47:07 AM'),") | |||
| // 存在属性 | |||
| .append("price: _.exists(true)") | |||
| .append("}"); | |||
| final int result = this.wxMaService.getCloudService().delete( | |||
| COLLECTION, whereParamSb.toString()); | |||
| assertThat(result).isEqualTo(0); | |||
| } | |||
| @Test | |||
| public void testDatabaseDelete() throws WxErrorException { | |||
| final int result = this.wxMaService.getCloudService().databaseDelete("rcn", | |||
| final int result = this.wxMaService.getCloudService().databaseDelete( | |||
| "db.collection(\"geo\").doc(\"056120a7-c89e-4616-95bf-dfc9a11daa3b\").remove()"); | |||
| assertThat(result).isEqualTo(0); | |||
| } | |||
| @Test | |||
| public void testUpdate() throws WxErrorException { | |||
| StringBuilder whereParamSb = new StringBuilder(); | |||
| whereParamSb.append("{") | |||
| // in | |||
| .append("age: _.in([0, 1, 2, 3]),") | |||
| // 小于 | |||
| .append("due: _.lt('Mar 29, 2020 8:47:07 AM'),") | |||
| // 存在属性 | |||
| .append("price: _.exists(true)") | |||
| .append("}"); | |||
| StringBuilder updateSb = new StringBuilder(); | |||
| updateSb.append("{age: _.inc(1)}"); | |||
| final WxCloudDatabaseUpdateResult result = this.wxMaService.getCloudService().update(COLLECTION, | |||
| whereParamSb.toString(), updateSb.toString()); | |||
| assertThat(result).isNotNull(); | |||
| assertThat(result.getMatched()).isGreaterThan(0); | |||
| assertThat(result.getId()).isEmpty(); | |||
| assertThat(result.getModified()).isGreaterThan(0); | |||
| } | |||
| @Test | |||
| public void testDatabaseUpdate() throws WxErrorException { | |||
| final WxCloudDatabaseUpdateResult result = this.wxMaService.getCloudService().databaseUpdate("rcn", | |||
| final WxCloudDatabaseUpdateResult result = this.wxMaService.getCloudService().databaseUpdate( | |||
| "db.collection(\"geo\").where({description:\"item1\"}).update({data:{age: _.inc(1)}})"); | |||
| assertThat(result).isNotNull(); | |||
| assertThat(result.getMatched()).isGreaterThan(0); | |||
| @@ -80,9 +200,43 @@ public class WxMaCloudServiceImplTest { | |||
| assertThat(result.getModified()).isGreaterThan(0); | |||
| } | |||
| @Test | |||
| public void testQuery() throws WxErrorException { | |||
| StringBuilder whereParamSb = new StringBuilder(); | |||
| whereParamSb.append("{") | |||
| // in | |||
| .append("age: _.in([0, 1, 2, 3]),") | |||
| // 小于 | |||
| .append("due: _.lt('Mar 29, 2020 8:47:07 AM'),") | |||
| // 存在属性 | |||
| .append("price: _.exists(true)") | |||
| .append("}"); | |||
| // // Hutool创建有序map,返回LinkedHashMap | |||
| // Map<String, Integer> map2 = MapUtil.newHashMap(true); | |||
| // map2.put("_id", "asc"); | |||
| // map2.put("price", "desc"); | |||
| // 有序map | |||
| ImmutableSortedMap<String, String> orderBy = new ImmutableSortedMap | |||
| .Builder<String, String>(Ordering.natural()) | |||
| .put("_id", "asc") | |||
| .put("price", "desc") | |||
| .build(); | |||
| final WxCloudDatabaseQueryResult result = this.wxMaService.getCloudService().query(COLLECTION, | |||
| whereParamSb.toString(), orderBy, 20, 20); | |||
| assertThat(result).isNotNull(); | |||
| assertThat(result.getPager()).isNotNull(); | |||
| assertThat(result.getPager().getLimit()).isEqualTo(10); | |||
| assertThat(result.getPager().getOffset()).isEqualTo(1); | |||
| assertThat(result.getPager().getTotal()).isGreaterThan(0); | |||
| assertThat(result.getData().length).isGreaterThan(0); | |||
| } | |||
| @Test | |||
| public void testDatabaseQuery() throws WxErrorException { | |||
| final WxCloudDatabaseQueryResult result = this.wxMaService.getCloudService().databaseQuery("rcn", | |||
| final WxCloudDatabaseQueryResult result = this.wxMaService.getCloudService().databaseQuery( | |||
| "db.collection(\"geo\").where({done:false}).limit(10).skip(1).get()"); | |||
| assertThat(result).isNotNull(); | |||
| assertThat(result.getPager()).isNotNull(); | |||
| @@ -94,21 +248,36 @@ public class WxMaCloudServiceImplTest { | |||
| @Test | |||
| public void testDatabaseAggregate() throws WxErrorException { | |||
| final JsonArray result = this.wxMaService.getCloudService().databaseAggregate("rcn", | |||
| final JsonArray result = this.wxMaService.getCloudService().databaseAggregate( | |||
| "db.collection(\"geo\").aggregate().match({tags:\"cloud\"}).limit(10).end()"); | |||
| assertThat(result).isNotNull(); | |||
| } | |||
| @Test | |||
| public void testCount() throws WxErrorException { | |||
| StringBuilder whereParamSb = new StringBuilder(); | |||
| whereParamSb.append("{") | |||
| // in | |||
| .append("age: _.in([0, 1, 2, 3]),") | |||
| // 小于 | |||
| .append("due: _.lt('Mar 29, 2020 8:47:07 AM'),") | |||
| // 存在属性 | |||
| .append("price: _.exists(true)") | |||
| .append("}"); | |||
| final Long result = this.wxMaService.getCloudService().count(COLLECTION, whereParamSb.toString()); | |||
| assertThat(result).isGreaterThan(0); | |||
| } | |||
| @Test | |||
| public void testDatabaseCount() throws WxErrorException { | |||
| final Long result = this.wxMaService.getCloudService().databaseCount("rcn", | |||
| final Long result = this.wxMaService.getCloudService().databaseCount( | |||
| "db.collection(\"geo\").where({done:false}).count()"); | |||
| assertThat(result).isGreaterThan(0); | |||
| } | |||
| @Test | |||
| public void testUpdateIndex() throws WxErrorException { | |||
| this.wxMaService.getCloudService().updateIndex("rcn", "geo", | |||
| this.wxMaService.getCloudService().updateIndex(COLLECTION, | |||
| Lists.newArrayList(new WxCloudDatabaseCreateIndexRequest() | |||
| .setName("drop_index") | |||
| .setUnique(true) | |||
| @@ -119,15 +288,16 @@ public class WxMaCloudServiceImplTest { | |||
| @Test | |||
| public void testDatabaseMigrateImport() throws WxErrorException { | |||
| final Long result = this.wxMaService.getCloudService().databaseMigrateImport("rcn", "geo", "test.json", | |||
| final Long result = this.wxMaService.getCloudService().databaseMigrateImport(COLLECTION, "test.json", | |||
| 1, true, 1); | |||
| assertThat(result).isGreaterThan(0); | |||
| } | |||
| @Test | |||
| public void testDatabaseMigrateExport() throws WxErrorException { | |||
| final Long result = this.wxMaService.getCloudService().databaseMigrateExport("rcn", "test.json", 1, | |||
| "const Point = db.Geo.Point;db.collection('geo').where({age: _.gt(1)}).limit(10).skip(1).orderBy('age','asc').orderBy('name', 'desc')" + | |||
| final Long result = this.wxMaService.getCloudService().databaseMigrateExport("test.json", 1, | |||
| "const Point = db.Geo.Point;db.collection('geo').where({age: _.gt(1)}).limit(10).skip(1).orderBy('age','asc')" + | |||
| ".orderBy('name', 'desc')" + | |||
| ".field({ name: true }).get()"); | |||
| assertThat(result).isGreaterThan(0); | |||
| } | |||
| @@ -135,14 +305,15 @@ public class WxMaCloudServiceImplTest { | |||
| @Test | |||
| public void testDatabaseMigrateQueryInfo() throws WxErrorException { | |||
| final WxCloudCloudDatabaseMigrateQueryInfoResult result = this.wxMaService.getCloudService() | |||
| .databaseMigrateQueryInfo("rcn", 476629L); | |||
| .databaseMigrateQueryInfo(476629L); | |||
| assertThat(result).isNotNull(); | |||
| System.out.println(result.getFileUrl()); | |||
| } | |||
| @Test | |||
| public void testUploadFile() throws WxErrorException { | |||
| final WxCloudUploadFileResult result = this.wxMaService.getCloudService().uploadFile("rcn", "E:\\MyDocs\\Desktop\\test.json"); | |||
| final WxCloudUploadFileResult result = this.wxMaService.getCloudService().uploadFile("E:\\MyDocs\\Desktop" + | |||
| "\\test.json"); | |||
| assertThat(result).isNotNull(); | |||
| assertThat(result.getAuthorization()).isNotNull(); | |||
| @@ -155,8 +326,9 @@ public class WxMaCloudServiceImplTest { | |||
| @Test | |||
| public void testBatchDownloadFile() throws WxErrorException { | |||
| final WxCloudBatchDownloadFileResult result = this.wxMaService.getCloudService().batchDownloadFile("rcn", | |||
| new String[]{"cloud://rcn.7263-rcn-1258788140/Snipaste_2019-11-13_00-21-27.png", "cloud://rcn.7263-rcn-1258788140/avatar.jpg"}, | |||
| final WxCloudBatchDownloadFileResult result = this.wxMaService.getCloudService().batchDownloadFile( | |||
| new String[]{"cloud://rcn.7263-rcn-1258788140/Snipaste_2019-11-13_00-21-27.png", "cloud://rcn" + | |||
| ".7263-rcn-1258788140/avatar.jpg"}, | |||
| new long[]{7200, 6800}); | |||
| assertThat(result).isNotNull(); | |||
| @@ -171,7 +343,7 @@ public class WxMaCloudServiceImplTest { | |||
| @Test | |||
| public void testBatchDeleteFile() throws WxErrorException { | |||
| final WxCloudBatchDeleteFileResult result = this.wxMaService.getCloudService().batchDeleteFile("rcn", | |||
| final WxCloudBatchDeleteFileResult result = this.wxMaService.getCloudService().batchDeleteFile( | |||
| new String[]{"cloud://rcn.7263-rcn-1258788140/test.json"}); | |||
| assertThat(result).isNotNull(); | |||
| @@ -195,18 +367,19 @@ public class WxMaCloudServiceImplTest { | |||
| @Test | |||
| public void testDatabaseCollectionAdd() throws WxErrorException { | |||
| this.wxMaService.getCloudService().databaseCollectionAdd("rcn","test_add_collection"); | |||
| this.wxMaService.getCloudService().databaseCollectionAdd("test_add_collection"); | |||
| } | |||
| @Test | |||
| public void testDatabaseCollectionDelete() throws WxErrorException { | |||
| this.wxMaService.getCloudService().databaseCollectionAdd("rcn","test_delete_collection"); | |||
| this.wxMaService.getCloudService().databaseCollectionDelete("rcn","test_delete_collection"); | |||
| this.wxMaService.getCloudService().databaseCollectionAdd("test_delete_collection"); | |||
| this.wxMaService.getCloudService().databaseCollectionDelete("test_delete_collection"); | |||
| } | |||
| @Test | |||
| public void testDatabaseCollectionGet() throws WxErrorException { | |||
| final WxCloudDatabaseCollectionGetResult result = this.wxMaService.getCloudService().databaseCollectionGet("rcn", null, null); | |||
| final WxCloudDatabaseCollectionGetResult result = this.wxMaService.getCloudService().databaseCollectionGet( | |||
| null, null); | |||
| assertThat(result).isNotNull(); | |||
| assertThat(result.getPager()).isNotNull(); | |||
| @@ -4,6 +4,7 @@ | |||
| <secret>secret</secret> | |||
| <token>Token</token> | |||
| <aesKey>EncodingAESKey</aesKey> | |||
| <cloudEnv>云环境</cloudEnv> | |||
| <accessToken>可以不填写</accessToken> | |||
| <expiresTime>可以不填写</expiresTime> | |||
| <openid>某个用户的openId</openid> | |||
| @@ -46,7 +46,6 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage { | |||
| private Map<String, Token> cardApiTickets = new ConcurrentHashMap<>(); | |||
| @Override | |||
| public boolean isComponentAccessTokenExpired() { | |||
| return System.currentTimeMillis() > componentExpiresTime; | |||
| @@ -79,7 +78,8 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage { | |||
| } | |||
| @Override | |||
| public void setWxOpenInfo(String componentAppId, String componentAppSecret, String componentToken, String componentAesKey) { | |||
| public void setWxOpenInfo(String componentAppId, String componentAppSecret, String componentToken, | |||
| String componentAesKey) { | |||
| setComponentAppId(componentAppId); | |||
| setComponentAppSecret(componentAppSecret); | |||
| setComponentToken(componentToken); | |||
| @@ -146,7 +146,8 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage { | |||
| @Override | |||
| public void updateAuthorizerAccessToken(String appId, WxOpenAuthorizerAccessToken authorizerAccessToken) { | |||
| updateAuthorizerAccessToken(appId, authorizerAccessToken.getAuthorizerAccessToken(), authorizerAccessToken.getExpiresIn()); | |||
| updateAuthorizerAccessToken(appId, authorizerAccessToken.getAuthorizerAccessToken(), | |||
| authorizerAccessToken.getExpiresIn()); | |||
| } | |||
| @Override | |||
| @@ -202,6 +203,14 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage { | |||
| private static class WxOpenInnerConfigStorage implements WxMpConfigStorage, WxMaConfig { | |||
| private WxOpenConfigStorage wxOpenConfigStorage; | |||
| private String appId; | |||
| /** | |||
| * 小程序原始ID | |||
| */ | |||
| private volatile String originalId; | |||
| /** | |||
| * 云环境ID | |||
| */ | |||
| private volatile String cloudEnv; | |||
| private Lock accessTokenLock = new ReentrantLock(); | |||
| private Lock jsapiTicketLock = new ReentrantLock(); | |||
| private Lock cardApiTicketLock = new ReentrantLock(); | |||
| @@ -325,6 +334,24 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage { | |||
| return this.appId; | |||
| } | |||
| @Override | |||
| public String getOriginalId() { | |||
| return originalId; | |||
| } | |||
| public void setOriginalId(String originalId) { | |||
| this.originalId = originalId; | |||
| } | |||
| @Override | |||
| public String getCloudEnv() { | |||
| return this.cloudEnv; | |||
| } | |||
| public void setCloudEnv(String cloudEnv) { | |||
| this.cloudEnv = cloudEnv; | |||
| } | |||
| @Override | |||
| public void expireAccessToken() { | |||
| wxOpenConfigStorage.expireAuthorizerAccessToken(appId); | |||