Browse Source

添加门店管理-创建门店的接口,单元测试仅测试格式,暂未通过测试

master
BinaryWang 8 years ago
parent
commit
b7e8f2129d
6 changed files with 526 additions and 40 deletions
  1. +18
    -11
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
  2. +2
    -3
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpStoreService.java
  3. +56
    -16
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java
  4. +67
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImpl.java
  5. +341
    -10
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpStoreBaseInfo.java
  6. +42
    -0
      weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImplTest.java

+ 18
- 11
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java View File

@@ -302,28 +302,28 @@ public interface WxMpService {
WxMpKefuService getKefuService();

/**
* 返回素材相关接口方法实现类,以方便调用个其各种接口
* 返回素材相关接口方法实现类对象,以方便调用个其各种接口
*
* @return WxMpMaterialService
*/
WxMpMaterialService getMaterialService();

/**
* 返回菜单相关接口方法实现类,以方便调用个其各种接口
* 返回菜单相关接口方法实现类对象,以方便调用个其各种接口
*
* @return WxMpMenuService
*/
WxMpMenuService getMenuService();

/**
* 返回用户相关接口方法实现类,以方便调用个其各种接口
* 返回用户相关接口方法实现类对象,以方便调用个其各种接口
*
* @return WxMpUserService
*/
WxMpUserService getUserService();

/**
* 返回用户分组相关接口方法实现类,以方便调用个其各种接口
* 返回用户分组相关接口方法实现类对象,以方便调用个其各种接口
*
* @return WxMpGroupService
*/
@@ -331,44 +331,51 @@ public interface WxMpService {
WxMpGroupService getGroupService();

/**
* 返回用户标签相关接口方法实现类,以方便调用个其各种接口
* 返回用户标签相关接口方法实现类对象,以方便调用个其各种接口
*
* @return WxMpUserTagService
*/
WxMpUserTagService getUserTagService();

/**
* 返回二维码相关接口方法实现类,以方便调用个其各种接口
* 返回二维码相关接口方法实现类对象,以方便调用个其各种接口
*
* @return WxMpQrcodeService
*/
WxMpQrcodeService getQrcodeService();

/**
* 返回卡券相关接口方法实现类,以方便调用个其各种接口
* 返回卡券相关接口方法实现类对象,以方便调用个其各种接口
*
* @return WxMpCardService
*/
WxMpCardService getCardService();

/**
* 返回微信支付相关接口方法实现类,以方便调用个其各种接口
* 返回微信支付相关接口方法实现类对象,以方便调用个其各种接口
*
* @return WxMpPayService
*/
WxMpPayService getPayService();

/**
* 返回数据分析统计相关接口方法实现类,以方便调用个其各种接口
* 返回数据分析统计相关接口方法实现类对象,以方便调用个其各种接口
*
* @return WxMpDataCubeService
*/
WxMpDataCubeService getDataCubeService();

/**
* 返回用户黑名单管理相关接口的方法实现类,以方便调用其各种借
* 返回用户黑名单管理相关接口方法的实现类对象,以方便调用其各种接
*
* @return WxMpUserBlackListService
* @return WxMpUserBlacklistService
*/
WxMpUserBlacklistService getBlackListService();

/**
* 返回门店管理相关接口方法的实现类对象,以方便调用其各种接口
*
* @return WxMpStoreService
*/
WxMpStoreService getStoreService();
}

+ 2
- 3
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpStoreService.java View File

@@ -1,6 +1,7 @@
package me.chanjar.weixin.mp.api;

import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.bean.WxMpStoreBaseInfo;

/**
* 门店管理的相关接口代码
@@ -19,8 +20,6 @@ public interface WxMpStoreService {
* 接口格式: http://api.weixin.qq.com/cgi-bin/poi/addpoi?access_token=TOKEN
* </pre>
*
* @param scene_id 参数。
* @param expire_seconds 过期秒数,默认60秒,最小60秒,最大1800秒
*/
void userUpdateRemark(String openid, String remark) throws WxErrorException;
void add(WxMpStoreBaseInfo request) throws WxErrorException;
}

+ 56
- 16
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java View File

@@ -1,9 +1,23 @@
package me.chanjar.weixin.mp.api.impl;

import java.io.IOException;

import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.result.WxError;
@@ -12,22 +26,39 @@ import me.chanjar.weixin.common.session.StandardSessionManager;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.common.util.RandomUtils;
import me.chanjar.weixin.common.util.crypto.SHA1;
import me.chanjar.weixin.common.util.http.*;
import me.chanjar.weixin.mp.api.*;
import me.chanjar.weixin.mp.bean.*;
import me.chanjar.weixin.mp.bean.result.*;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder;
import me.chanjar.weixin.common.util.http.DefaultApacheHttpClientBuilder;
import me.chanjar.weixin.common.util.http.RequestExecutor;
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
import me.chanjar.weixin.common.util.http.URIUtil;
import me.chanjar.weixin.mp.api.WxMpCardService;
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpDataCubeService;
import me.chanjar.weixin.mp.api.WxMpGroupService;
import me.chanjar.weixin.mp.api.WxMpKefuService;
import me.chanjar.weixin.mp.api.WxMpMaterialService;
import me.chanjar.weixin.mp.api.WxMpMenuService;
import me.chanjar.weixin.mp.api.WxMpPayService;
import me.chanjar.weixin.mp.api.WxMpQrcodeService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpStoreService;
import me.chanjar.weixin.mp.api.WxMpUserBlacklistService;
import me.chanjar.weixin.mp.api.WxMpUserService;
import me.chanjar.weixin.mp.api.WxMpUserTagService;
import me.chanjar.weixin.mp.bean.WxMpIndustry;
import me.chanjar.weixin.mp.bean.WxMpMassGroupMessage;
import me.chanjar.weixin.mp.bean.WxMpMassNews;
import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage;
import me.chanjar.weixin.mp.bean.WxMpMassPreviewMessage;
import me.chanjar.weixin.mp.bean.WxMpMassVideo;
import me.chanjar.weixin.mp.bean.WxMpSemanticQuery;
import me.chanjar.weixin.mp.bean.WxMpTemplateMessage;
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult;
import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult;
import me.chanjar.weixin.mp.bean.result.WxMpUser;

public class WxMpServiceImpl implements WxMpService {

@@ -65,6 +96,8 @@ public class WxMpServiceImpl implements WxMpService {

private WxMpPayService payService = new WxMpPayServiceImpl(this);

private WxMpStoreService storeService = new WxMpStoreServiceImpl(this);

private WxMpDataCubeService dataCubeService = new WxMpDataCubeServiceImpl(this);

private WxMpUserBlacklistService blackListService = new WxMpUserBlacklistServiceImpl(this);
@@ -442,6 +475,8 @@ public class WxMpServiceImpl implements WxMpService {
return this.execute(executor, uri, data);
}
if (error.getErrorCode() != 0) {
this.log.error("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}", uri, data,
error);
throw new WxErrorException(error);
}
return null;
@@ -560,4 +595,9 @@ public class WxMpServiceImpl implements WxMpService {
return this.blackListService;
}

@Override
public WxMpStoreService getStoreService() {
return this.storeService;
}

}

+ 67
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImpl.java View File

@@ -0,0 +1,67 @@
package me.chanjar.weixin.mp.api.impl;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map.Entry;

import org.joor.Reflect;

import com.google.common.collect.Lists;

import me.chanjar.weixin.common.annotation.Required;
import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.WxMpStoreService;
import me.chanjar.weixin.mp.bean.WxMpStoreBaseInfo;

/**
* Created by Binary Wang on 2016/9/26.
* @author binarywang (https://github.com/binarywang)
*
*/
public class WxMpStoreServiceImpl implements WxMpStoreService {

private WxMpService wxMpService;

public WxMpStoreServiceImpl(WxMpService wxMpService) {
this.wxMpService = wxMpService;
}

@Override
public void add(WxMpStoreBaseInfo request) throws WxErrorException {
checkParameters(request);

String url = "http://api.weixin.qq.com/cgi-bin/poi/addpoi";
// String data = "{\"business\":{\"base_info\":{\"business_name\":\"haha\",\"branch_name\":\"abc\",\"province\":\"aaa\",\"city\":\"aaa\",\"district\":\"aaa\",\"telephone\":\"122\",\"categories\":\"adsdas\",\"offset_type\":\"1\",\"longitude\":\"115.32375\",\"latitude\":\"25.097486\"}}}";
String response = this.wxMpService.post(url, request.toJson());
// String response = this.wxMpService.post(url, data);
WxError wxError = WxError.fromJson(response);
if (wxError.getErrorCode() != 0) {
throw new WxErrorException(wxError);
}
}

private void checkParameters(WxMpStoreBaseInfo request) {
List<String> nullFields = Lists.newArrayList();
for (Entry<String, Reflect> entry : Reflect.on(request).fields()
.entrySet()) {
Reflect reflect = entry.getValue();
try {
Field field = request.getClass().getDeclaredField(entry.getKey());
if (field.isAnnotationPresent(Required.class)
&& reflect.get() == null) {
nullFields.add(entry.getKey());
}
} catch (NoSuchFieldException | SecurityException e) {
e.printStackTrace();
}
}

if (!nullFields.isEmpty()) {
throw new IllegalArgumentException("必填字段[" + nullFields + "]必须提供值");
}

}

}

+ 341
- 10
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpStoreBaseInfo.java View File

@@ -1,9 +1,14 @@
package me.chanjar.weixin.mp.bean;

import java.math.BigDecimal;
import java.util.List;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.annotations.SerializedName;

import java.util.List;
import me.chanjar.weixin.common.annotation.Required;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;

/**
* 门店基础信息
@@ -11,6 +16,16 @@ import java.util.List;
* Created by Binary Wang on 2016-09-23.
*/
public class WxMpStoreBaseInfo {

public String toJson() {
JsonElement base_info = WxMpGsonBuilder.create().toJsonTree(this);
JsonObject jsonObject = new JsonObject();
jsonObject.add("base_info", base_info);
JsonObject business = new JsonObject();
business.add("business", jsonObject);
return business.toString();
}

public static class WxMpStorePhoto {
/**
* 照片url
@@ -31,6 +46,7 @@ public class WxMpStoreBaseInfo {
* 门店名称(仅为商户名,如:国美、麦当劳,不应包含地区、地址、分店名等信息,错误示例:北京国美)
* 不能为空,15个汉字或30个英文字符内
*/
@Required
@SerializedName("business_name")
private String businessName;

@@ -39,14 +55,16 @@ public class WxMpStoreBaseInfo {
* 分店名称(不应包含地区信息,不应与门店名有重复,错误示例:北京王府井店)
* 10个字以内
*/
@Required
@SerializedName("branch_name")
private String branch_name;
private String branchName;

/**
* province
* 门店所在的省份(直辖市填城市名,如:北京市)
* 10个字以内
*/
@Required
@SerializedName("province")
private String province;

@@ -55,6 +73,7 @@ public class WxMpStoreBaseInfo {
* 门店所在的城市
* 10个字以内
*/
@Required
@SerializedName("city")
private String city;

@@ -63,6 +82,7 @@ public class WxMpStoreBaseInfo {
* 门店所在地区
* 10个字以内
*/
@Required
@SerializedName("district")
private String district;

@@ -71,6 +91,7 @@ public class WxMpStoreBaseInfo {
* 门店所在的详细街道地址(不要填写省市信息)
* (东莞等没有“区”行政区划的城市,该字段可不必填写。其余城市必填。)
*/
@Required
@SerializedName("address")
private String address;

@@ -78,6 +99,7 @@ public class WxMpStoreBaseInfo {
* telephone
* 门店的电话(纯数字,区号、分机号均由“-”隔开)
*/
@Required
@SerializedName("telephone")
private String telephone;

@@ -85,29 +107,33 @@ public class WxMpStoreBaseInfo {
* categories
* 门店的类型(不同级分类用“,”隔开,如:美食,川菜,火锅。详细分类参见附件:微信门店类目表)
*/
@Required
@SerializedName("categories")
private String categories;
private String[] categories;

/**
* offset_type
* offsetType
* 坐标类型,1 为火星坐标(目前只能选1)
*/
@Required
@SerializedName("offset_type")
private String offset_type;
private Integer offsetType = 1;

/**
* longitude
* 门店所在地理位置的经度
*/
@Required
@SerializedName("longitude")
private String longitude;
private BigDecimal longitude;

/**
* latitude
* 门店所在地理位置的纬度(经纬度均为火星坐标,最好选用腾讯地图标记的坐标)
*/
@Required
@SerializedName("latitude")
private String latitude;
private BigDecimal latitude;

/**
* photo_list
@@ -115,7 +141,7 @@ public class WxMpStoreBaseInfo {
* 图片内容不允许与门店不相关,不允许为二维码、员工合照(或模特肖像)、营业执照、无门店正门的街景、地图截图、公交地铁站牌、菜单截图等
*/
@SerializedName("photo_list")
private List<WxMpStorePhoto> photo_list;
private List<WxMpStorePhoto> photos;

/**
* recommend
@@ -145,12 +171,317 @@ public class WxMpStoreBaseInfo {
* 营业时间,24 小时制表示,用“-”连接,如 8:00-20:00
*/
@SerializedName("open_time")
private String open_time;
private String openTime;

/**
* avg_price
* 人均价格,大于0 的整数
*/
@SerializedName("avg_price")
private Integer avg_price;
private Integer avgPrice;

public String getSid() {
return this.sid;
}

public void setSid(String sid) {
this.sid = sid;
}

public String getBusinessName() {
return this.businessName;
}

public void setBusinessName(String businessName) {
this.businessName = businessName;
}

public String getBranchName() {
return this.branchName;
}

public void setBranchName(String branchName) {
this.branchName = branchName;
}

public String getProvince() {
return this.province;
}

public void setProvince(String province) {
this.province = province;
}

public String getCity() {
return this.city;
}

public void setCity(String city) {
this.city = city;
}

public String getDistrict() {
return this.district;
}

public void setDistrict(String district) {
this.district = district;
}

public String getAddress() {
return this.address;
}

public void setAddress(String address) {
this.address = address;
}

public String getTelephone() {
return this.telephone;
}

public void setTelephone(String telephone) {
this.telephone = telephone;
}

public String[] getCategories() {
return this.categories;
}

public void setCategories(String[] categories) {
this.categories = categories;
}

public Integer getOffsetType() {
return this.offsetType;
}

public void setOffsetType(Integer offsetType) {
this.offsetType = offsetType;
}

public BigDecimal getLongitude() {
return this.longitude;
}

public void setLongitude(BigDecimal longitude) {
this.longitude = longitude;
}

public BigDecimal getLatitude() {
return this.latitude;
}

public void setLatitude(BigDecimal latitude) {
this.latitude = latitude;
}

public List<WxMpStorePhoto> getPhotos() {
return this.photos;
}

public void setPhotos(List<WxMpStorePhoto> photos) {
this.photos = photos;
}

public String getRecommend() {
return this.recommend;
}

public void setRecommend(String recommend) {
this.recommend = recommend;
}

public String getSpecial() {
return this.special;
}

public void setSpecial(String special) {
this.special = special;
}

public String getIntroduction() {
return this.introduction;
}

public void setIntroduction(String introduction) {
this.introduction = introduction;
}

public String getOpenTime() {
return this.openTime;
}

public void setOpenTime(String openTime) {
this.openTime = openTime;
}

public Integer getAvgPrice() {
return this.avgPrice;
}

public void setAvgPrice(Integer avgPrice) {
this.avgPrice = avgPrice;
}

public static WxMpStoreBaseInfoBuilder builder() {
return new WxMpStoreBaseInfoBuilder();
}

public static class WxMpStoreBaseInfoBuilder {
private String sid;
private String businessName;
private String branchName;
private String province;
private String city;
private String district;
private String address;
private String telephone;
private String[] categories;
private Integer offsetType;
private BigDecimal longitude;
private BigDecimal latitude;
private List<WxMpStorePhoto> photos;
private String recommend;
private String special;
private String introduction;
private String openTime;
private Integer avgPrice;

public WxMpStoreBaseInfoBuilder sid(String sid) {
this.sid = sid;
return this;
}

public WxMpStoreBaseInfoBuilder businessName(String businessName) {
this.businessName = businessName;
return this;
}

public WxMpStoreBaseInfoBuilder branchName(String branchName) {
this.branchName = branchName;
return this;
}

public WxMpStoreBaseInfoBuilder province(String province) {
this.province = province;
return this;
}

public WxMpStoreBaseInfoBuilder city(String city) {
this.city = city;
return this;
}

public WxMpStoreBaseInfoBuilder district(String district) {
this.district = district;
return this;
}

public WxMpStoreBaseInfoBuilder address(String address) {
this.address = address;
return this;
}

public WxMpStoreBaseInfoBuilder telephone(String telephone) {
this.telephone = telephone;
return this;
}

public WxMpStoreBaseInfoBuilder categories(String[] categories) {
this.categories = categories;
return this;
}

public WxMpStoreBaseInfoBuilder offsetType(Integer offsetType) {
this.offsetType = offsetType;
return this;
}

public WxMpStoreBaseInfoBuilder longitude(BigDecimal longitude) {
this.longitude = longitude;
return this;
}

public WxMpStoreBaseInfoBuilder latitude(BigDecimal latitude) {
this.latitude = latitude;
return this;
}

public WxMpStoreBaseInfoBuilder photos(List<WxMpStorePhoto> photos) {
this.photos = photos;
return this;
}

public WxMpStoreBaseInfoBuilder recommend(String recommend) {
this.recommend = recommend;
return this;
}

public WxMpStoreBaseInfoBuilder special(String special) {
this.special = special;
return this;
}

public WxMpStoreBaseInfoBuilder introduction(String introduction) {
this.introduction = introduction;
return this;
}

public WxMpStoreBaseInfoBuilder openTime(String openTime) {
this.openTime = openTime;
return this;
}

public WxMpStoreBaseInfoBuilder avgPrice(Integer avgPrice) {
this.avgPrice = avgPrice;
return this;
}

public WxMpStoreBaseInfoBuilder from(WxMpStoreBaseInfo origin) {
this.sid(origin.sid);
this.businessName(origin.businessName);
this.branchName(origin.branchName);
this.province(origin.province);
this.city(origin.city);
this.district(origin.district);
this.address(origin.address);
this.telephone(origin.telephone);
this.categories(origin.categories);
this.offsetType(origin.offsetType);
this.longitude(origin.longitude);
this.latitude(origin.latitude);
this.photos(origin.photos);
this.recommend(origin.recommend);
this.special(origin.special);
this.introduction(origin.introduction);
this.openTime(origin.openTime);
this.avgPrice(origin.avgPrice);
return this;
}

public WxMpStoreBaseInfo build() {
WxMpStoreBaseInfo m = new WxMpStoreBaseInfo();
m.sid = this.sid;
m.businessName = this.businessName;
m.branchName = this.branchName;
m.province = this.province;
m.city = this.city;
m.district = this.district;
m.address = this.address;
m.telephone = this.telephone;
m.categories = this.categories;
m.offsetType = this.offsetType;
m.longitude = this.longitude;
m.latitude = this.latitude;
m.photos = this.photos;
m.recommend = this.recommend;
m.special = this.special;
m.introduction = this.introduction;
m.openTime = this.openTime;
m.avgPrice = this.avgPrice;
return m;
}
}

}

+ 42
- 0
weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImplTest.java View File

@@ -0,0 +1,42 @@
/**
* Copyright(c) 2011-2016 by UCredit Inc.
* All Rights Reserved
*/
package me.chanjar.weixin.mp.api.impl;

import java.math.BigDecimal;

import org.testng.annotations.Guice;
import org.testng.annotations.Test;

import com.google.inject.Inject;

import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.ApiTestModule;
import me.chanjar.weixin.mp.bean.WxMpStoreBaseInfo;

/**
* @author 王彬 (Binary Wang)
*
*/
@Test
@Guice(modules = ApiTestModule.class)
public class WxMpStoreServiceImplTest {
@Inject
private WxMpServiceImpl wxMpService;

/**
* Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpStoreServiceImpl#add(me.chanjar.weixin.mp.bean.WxMpStoreBaseInfo)}.
* @throws WxErrorException
*/
public void testAdd() throws WxErrorException {
this.wxMpService.getStoreService()
.add(WxMpStoreBaseInfo.builder().businessName("haha").branchName("abc")
.province("aaa").district("aaa").telephone("122").address("abc")
.categories(new String[] { "美食,川菜,火锅" })
.longitude(new BigDecimal("115.32375"))
.latitude(new BigDecimal("25.097486")).city("aaa").offsetType(1)
.build());
}

}

Loading…
Cancel
Save