@@ -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); | |||