@@ -0,0 +1,38 @@ | |||||
package me.chanjar.weixin.mp.api; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardActivatedMessage; | |||||
import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUserInfoResult; | |||||
/** | |||||
* 会员卡相关接口 | |||||
* | |||||
* @author YuJian(mgcnrx11@gmail.com) | |||||
* @version 2017/7/8 | |||||
*/ | |||||
public interface WxMpMemberCardService { | |||||
/** | |||||
* 得到WxMpService | |||||
*/ | |||||
WxMpService getWxMpService(); | |||||
/** | |||||
* 会员卡激活接口 | |||||
* | |||||
* @param activatedMessage 激活所需参数 | |||||
* @return 调用返回的JSON字符串。 | |||||
* @throws WxErrorException 接口调用失败抛出的异常 | |||||
*/ | |||||
String activateMemberCard(WxMpMemberCardActivatedMessage activatedMessage) throws WxErrorException; | |||||
/** | |||||
* 拉取会员信息接口 | |||||
* | |||||
* @param cardId 会员卡的CardId,微信分配 | |||||
* @param code 领取会员的会员卡Code | |||||
* @return 会员信息的结果对象 | |||||
* @throws WxErrorException 接口调用失败抛出的异常 | |||||
*/ | |||||
WxMpMemberCardUserInfoResult getUserInfo(String cardId, String code) throws WxErrorException; | |||||
} |
@@ -434,6 +434,13 @@ public interface WxMpService { | |||||
*/ | */ | ||||
WxMpShakeService getShakeService(); | WxMpShakeService getShakeService(); | ||||
/** | |||||
* 返回会员卡相关接口方法的实现类对象,以方便调用其各个接口 | |||||
* | |||||
* @return WxMpMemberCardService | |||||
*/ | |||||
WxMpMemberCardService getMemberCardService(); | |||||
/** | /** | ||||
* 初始化http请求对象 | * 初始化http请求对象 | ||||
*/ | */ | ||||
@@ -42,6 +42,7 @@ public abstract class AbstractWxMpServiceImpl<H, P> implements WxMpService, Requ | |||||
private WxMpTemplateMsgService templateMsgService = new WxMpTemplateMsgServiceImpl(this); | private WxMpTemplateMsgService templateMsgService = new WxMpTemplateMsgServiceImpl(this); | ||||
private WxMpDeviceService deviceService = new WxMpDeviceServiceImpl(this); | private WxMpDeviceService deviceService = new WxMpDeviceServiceImpl(this); | ||||
private WxMpShakeService shakeService = new WxMpShakeServiceImpl(this); | private WxMpShakeService shakeService = new WxMpShakeServiceImpl(this); | ||||
private WxMpMemberCardService memberCardService = new WxMpMemberCardServiceImpl(this); | |||||
private int retrySleepMillis = 1000; | private int retrySleepMillis = 1000; | ||||
private int maxRetryTimes = 5; | private int maxRetryTimes = 5; | ||||
@@ -406,6 +407,11 @@ public abstract class AbstractWxMpServiceImpl<H, P> implements WxMpService, Requ | |||||
return this.shakeService; | return this.shakeService; | ||||
} | } | ||||
@Override | |||||
public WxMpMemberCardService getMemberCardService() { | |||||
return this.memberCardService; | |||||
} | |||||
@Override | @Override | ||||
public RequestHttp getRequestHttp() { | public RequestHttp getRequestHttp() { | ||||
return this; | return this; | ||||
@@ -0,0 +1,78 @@ | |||||
package me.chanjar.weixin.mp.api.impl; | |||||
import com.google.gson.Gson; | |||||
import com.google.gson.JsonElement; | |||||
import com.google.gson.JsonObject; | |||||
import com.google.gson.JsonParser; | |||||
import com.google.gson.reflect.TypeToken; | |||||
import me.chanjar.weixin.common.exception.WxErrorException; | |||||
import me.chanjar.weixin.mp.api.WxMpMemberCardService; | |||||
import me.chanjar.weixin.mp.api.WxMpService; | |||||
import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardActivatedMessage; | |||||
import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUserInfoResult; | |||||
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | |||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
/** | |||||
* 会员卡相关接口的实现类 | |||||
* | |||||
* @author YuJian(mgcnrx11@gmail.com) | |||||
* @version 2017/7/8 | |||||
*/ | |||||
public class WxMpMemberCardServiceImpl implements WxMpMemberCardService { | |||||
private final Logger log = LoggerFactory.getLogger(WxMpMemberCardServiceImpl.class); | |||||
private static final String MEMBER_CARD_ACTIVATE = "https://api.weixin.qq.com/card/membercard/activate"; | |||||
private static final String MEMBER_CARD_USER_INFO_GET = "https://api.weixin.qq.com/card/membercard/userinfo/get"; | |||||
private WxMpService wxMpService; | |||||
private static final Gson GSON = new Gson(); | |||||
WxMpMemberCardServiceImpl(WxMpService wxMpService) { | |||||
this.wxMpService = wxMpService; | |||||
} | |||||
/** | |||||
* 得到WxMpService | |||||
*/ | |||||
@Override | |||||
public WxMpService getWxMpService() { | |||||
return this.wxMpService; | |||||
} | |||||
/** | |||||
* 会员卡激活接口 | |||||
* | |||||
* @param activatedMessage 激活所需参数 | |||||
* @return 调用返回的JSON字符串。 | |||||
* @throws WxErrorException 接口调用失败抛出的异常 | |||||
*/ | |||||
@Override | |||||
public String activateMemberCard(WxMpMemberCardActivatedMessage activatedMessage) throws WxErrorException { | |||||
return this.wxMpService.post(MEMBER_CARD_ACTIVATE, GSON.toJson(activatedMessage)); | |||||
} | |||||
/** | |||||
* 拉取会员信息接口 | |||||
* | |||||
* @param cardId 会员卡的CardId,微信分配 | |||||
* @param code 领取会员的会员卡Code | |||||
* @return 会员信息的结果对象 | |||||
* @throws WxErrorException 接口调用失败抛出的异常 | |||||
*/ | |||||
@Override | |||||
public WxMpMemberCardUserInfoResult getUserInfo(String cardId, String code) throws WxErrorException { | |||||
JsonObject jsonObject = new JsonObject(); | |||||
jsonObject.addProperty("card_id", cardId); | |||||
jsonObject.addProperty("code",code); | |||||
String responseContent = this.getWxMpService().post(MEMBER_CARD_USER_INFO_GET, jsonObject.toString()); | |||||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | |||||
return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement, | |||||
new TypeToken<WxMpMemberCardUserInfoResult>() { | |||||
}.getType()); | |||||
} | |||||
} |
@@ -0,0 +1,27 @@ | |||||
package me.chanjar.weixin.mp.bean.membercard; | |||||
/** | |||||
* Created by YuJian on 2017/7/11. | |||||
*/ | |||||
public class MemberCardUserInfo { | |||||
private NameValues[] commonFieldList; | |||||
private NameValues[] customFieldList; | |||||
public NameValues[] getCommonFieldList() { | |||||
return commonFieldList; | |||||
} | |||||
public void setCommonFieldList(NameValues[] commonFieldList) { | |||||
this.commonFieldList = commonFieldList; | |||||
} | |||||
public NameValues[] getCustomFieldList() { | |||||
return customFieldList; | |||||
} | |||||
public void setCustomFieldList(NameValues[] customFieldList) { | |||||
this.customFieldList = customFieldList; | |||||
} | |||||
} |
@@ -0,0 +1,36 @@ | |||||
package me.chanjar.weixin.mp.bean.membercard; | |||||
/** | |||||
* Created by YuJian on 2017/7/11. | |||||
*/ | |||||
public class NameValues { | |||||
private String name; | |||||
private String value; | |||||
private String[] valueList; | |||||
public String getName() { | |||||
return name; | |||||
} | |||||
public void setName(String name) { | |||||
this.name = name; | |||||
} | |||||
public String getValue() { | |||||
return value; | |||||
} | |||||
public void setValue(String value) { | |||||
this.value = value; | |||||
} | |||||
public String[] getValueList() { | |||||
return valueList; | |||||
} | |||||
public void setValueList(String[] valueList) { | |||||
this.valueList = valueList; | |||||
} | |||||
} |
@@ -0,0 +1,144 @@ | |||||
package me.chanjar.weixin.mp.bean.membercard; | |||||
import com.google.gson.annotations.SerializedName; | |||||
/** | |||||
* 会员卡激活接口的参数 | |||||
* | |||||
* @author YuJian(mgcnrx11@hotmail.com) | |||||
* @version 2017/7/8 | |||||
*/ | |||||
public class WxMpMemberCardActivatedMessage { | |||||
// 会员卡编号,由开发者填入,作为序列号显示在用户的卡包里。可与Code码保持等值。 | |||||
@SerializedName("membership_number") | |||||
private String membershipNumber; | |||||
// 领取会员卡用户获得的code | |||||
private String code; | |||||
// 卡券ID,自定义code卡券必填 | |||||
@SerializedName("card_id") | |||||
private String cardId; | |||||
// 商家自定义会员卡背景图,须先调用上传图片接口将背景图上传至CDN,否则报错。卡面设计请遵循微信会员卡自定义背景设计规范 | |||||
@SerializedName("background_pic_url") | |||||
private String backgroundPicUrl; | |||||
// 激活后的有效起始时间。若不填写默认以创建时的 data_info 为准。Unix时间戳格式。 | |||||
@SerializedName("activate_begin_time") | |||||
private Integer activateBeginTime; | |||||
// 激活后的有效截至时间。若不填写默认以创建时的 data_info 为准。Unix时间戳格式。 | |||||
@SerializedName("activate_end_time") | |||||
private Integer activateEndTime; | |||||
// 初始积分,不填为0。 | |||||
@SerializedName("init_bonus") | |||||
private Integer initBonus; | |||||
// 积分同步说明。 | |||||
@SerializedName("init_bonus_record") | |||||
private String initBonusRecord; | |||||
// 初始余额,不填为0。 | |||||
@SerializedName("init_balance") | |||||
private Integer initBalance; | |||||
// 创建时字段custom_field1定义类型的初始值,限制为4个汉字,12字节。 | |||||
@SerializedName("init_custom_field_value1") | |||||
private String initCustomFieldValue1; | |||||
// 创建时字段custom_field2定义类型的初始值,限制为4个汉字,12字节。 | |||||
@SerializedName("init_custom_field_value2") | |||||
private String initCustomFieldValue2; | |||||
// 创建时字段custom_field3定义类型的初始值,限制为4个汉字,12字节。 | |||||
@SerializedName("init_custom_field_value3") | |||||
private String initCustomFieldValue3; | |||||
public String getMembershipNumber() { | |||||
return membershipNumber; | |||||
} | |||||
public void setMembershipNumber(String membershipNumber) { | |||||
this.membershipNumber = membershipNumber; | |||||
} | |||||
public String getCode() { | |||||
return code; | |||||
} | |||||
public void setCode(String code) { | |||||
this.code = code; | |||||
} | |||||
public String getCardId() { | |||||
return cardId; | |||||
} | |||||
public void setCardId(String cardId) { | |||||
this.cardId = cardId; | |||||
} | |||||
public String getBackgroundPicUrl() { | |||||
return backgroundPicUrl; | |||||
} | |||||
public void setBackgroundPicUrl(String backgroundPicUrl) { | |||||
this.backgroundPicUrl = backgroundPicUrl; | |||||
} | |||||
public Integer getActivateBeginTime() { | |||||
return activateBeginTime; | |||||
} | |||||
public void setActivateBeginTime(Integer activateBeginTime) { | |||||
this.activateBeginTime = activateBeginTime; | |||||
} | |||||
public Integer getActivateEndTime() { | |||||
return activateEndTime; | |||||
} | |||||
public void setActivateEndTime(Integer activateEndTime) { | |||||
this.activateEndTime = activateEndTime; | |||||
} | |||||
public Integer getInitBonus() { | |||||
return initBonus; | |||||
} | |||||
public void setInitBonus(Integer initBonus) { | |||||
this.initBonus = initBonus; | |||||
} | |||||
public String getInitBonusRecord() { | |||||
return initBonusRecord; | |||||
} | |||||
public void setInitBonusRecord(String initBonusRecord) { | |||||
this.initBonusRecord = initBonusRecord; | |||||
} | |||||
public Integer getInitBalance() { | |||||
return initBalance; | |||||
} | |||||
public void setInitBalance(Integer initBalance) { | |||||
this.initBalance = initBalance; | |||||
} | |||||
public String getInitCustomFieldValue1() { | |||||
return initCustomFieldValue1; | |||||
} | |||||
public void setInitCustomFieldValue1(String initCustomFieldValue1) { | |||||
this.initCustomFieldValue1 = initCustomFieldValue1; | |||||
} | |||||
public String getInitCustomFieldValue2() { | |||||
return initCustomFieldValue2; | |||||
} | |||||
public void setInitCustomFieldValue2(String initCustomFieldValue2) { | |||||
this.initCustomFieldValue2 = initCustomFieldValue2; | |||||
} | |||||
public String getInitCustomFieldValue3() { | |||||
return initCustomFieldValue3; | |||||
} | |||||
public void setInitCustomFieldValue3(String initCustomFieldValue3) { | |||||
this.initCustomFieldValue3 = initCustomFieldValue3; | |||||
} | |||||
} |
@@ -0,0 +1,137 @@ | |||||
package me.chanjar.weixin.mp.bean.membercard; | |||||
import java.io.Serializable; | |||||
/** | |||||
* 拉取会员信息返回的结果 | |||||
* | |||||
* 字段格式参考https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025283 6.2.1小节的步骤5 | |||||
* | |||||
* @author YuJian | |||||
* @version 2017/7/9 | |||||
*/ | |||||
public class WxMpMemberCardUserInfoResult implements Serializable { | |||||
private static final long serialVersionUID = 9084777967442098311L; | |||||
private String errorCode; | |||||
private String errorMsg; | |||||
private String openId; | |||||
private String nickname; | |||||
private String membershipNumber; | |||||
private Integer bonus; | |||||
private String sex; | |||||
private MemberCardUserInfo userInfo; | |||||
private String userCardStatus; | |||||
private Boolean hasActive; | |||||
public static long getSerialVersionUID() { | |||||
return serialVersionUID; | |||||
} | |||||
public String getErrorCode() { | |||||
return errorCode; | |||||
} | |||||
public void setErrorCode(String errorCode) { | |||||
this.errorCode = errorCode; | |||||
} | |||||
public String getErrorMsg() { | |||||
return errorMsg; | |||||
} | |||||
public void setErrorMsg(String errorMsg) { | |||||
this.errorMsg = errorMsg; | |||||
} | |||||
public String getOpenId() { | |||||
return openId; | |||||
} | |||||
public void setOpenId(String openId) { | |||||
this.openId = openId; | |||||
} | |||||
public String getNickname() { | |||||
return nickname; | |||||
} | |||||
public void setNickname(String nickname) { | |||||
this.nickname = nickname; | |||||
} | |||||
public String getMembershipNumber() { | |||||
return membershipNumber; | |||||
} | |||||
public void setMembershipNumber(String membershipNumber) { | |||||
this.membershipNumber = membershipNumber; | |||||
} | |||||
public Integer getBonus() { | |||||
return bonus; | |||||
} | |||||
public void setBonus(Integer bonus) { | |||||
this.bonus = bonus; | |||||
} | |||||
public String getSex() { | |||||
return sex; | |||||
} | |||||
public void setSex(String sex) { | |||||
this.sex = sex; | |||||
} | |||||
public MemberCardUserInfo getUserInfo() { | |||||
return userInfo; | |||||
} | |||||
public void setUserInfo(MemberCardUserInfo userInfo) { | |||||
this.userInfo = userInfo; | |||||
} | |||||
public String getUserCardStatus() { | |||||
return userCardStatus; | |||||
} | |||||
public void setUserCardStatus(String userCardStatus) { | |||||
this.userCardStatus = userCardStatus; | |||||
} | |||||
public Boolean getHasActive() { | |||||
return hasActive; | |||||
} | |||||
public void setHasActive(Boolean hasActive) { | |||||
this.hasActive = hasActive; | |||||
} | |||||
@Override | |||||
public String toString() { | |||||
return "WxMpMemberCardUserInfoResult{" + | |||||
"errorCode='" + errorCode + '\'' + | |||||
", errorMsg='" + errorMsg + '\'' + | |||||
", openId='" + openId + '\'' + | |||||
", nickname='" + nickname + '\'' + | |||||
", membershipNumber='" + membershipNumber + '\'' + | |||||
", bonus=" + bonus + | |||||
", sex='" + sex + '\'' + | |||||
", userInfo=" + userInfo + | |||||
", userCardStatus='" + userCardStatus + '\'' + | |||||
", hasActive=" + hasActive + | |||||
'}'; | |||||
} | |||||
} | |||||
@@ -6,6 +6,7 @@ import me.chanjar.weixin.mp.bean.*; | |||||
import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserCumulate; | import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserCumulate; | ||||
import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserSummary; | import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserSummary; | ||||
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; | import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; | ||||
import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUserInfoResult; | |||||
import me.chanjar.weixin.mp.bean.material.*; | import me.chanjar.weixin.mp.bean.material.*; | ||||
import me.chanjar.weixin.mp.bean.result.*; | import me.chanjar.weixin.mp.bean.result.*; | ||||
import me.chanjar.weixin.mp.bean.template.WxMpTemplateIndustry; | import me.chanjar.weixin.mp.bean.template.WxMpTemplateIndustry; | ||||
@@ -49,6 +50,7 @@ public class WxMpGsonBuilder { | |||||
INSTANCE.registerTypeAdapter(WxMediaImgUploadResult.class, new WxMediaImgUploadResultGsonAdapter()); | INSTANCE.registerTypeAdapter(WxMediaImgUploadResult.class, new WxMediaImgUploadResultGsonAdapter()); | ||||
INSTANCE.registerTypeAdapter(WxMpTemplateIndustry.class, new WxMpIndustryGsonAdapter()); | INSTANCE.registerTypeAdapter(WxMpTemplateIndustry.class, new WxMpIndustryGsonAdapter()); | ||||
INSTANCE.registerTypeAdapter(WxMpUserBlacklistGetResult.class, new WxUserBlacklistGetResultGsonAdapter()); | INSTANCE.registerTypeAdapter(WxMpUserBlacklistGetResult.class, new WxUserBlacklistGetResultGsonAdapter()); | ||||
INSTANCE.registerTypeAdapter(WxMpMemberCardUserInfoResult.class, new WxMpMemberCardUserInfoResultGsonAdapter()); | |||||
} | } | ||||
public static Gson create() { | public static Gson create() { | ||||
@@ -0,0 +1,72 @@ | |||||
package me.chanjar.weixin.mp.util.json; | |||||
import com.google.gson.*; | |||||
import me.chanjar.weixin.common.util.json.GsonHelper; | |||||
import me.chanjar.weixin.mp.bean.membercard.MemberCardUserInfo; | |||||
import me.chanjar.weixin.mp.bean.membercard.NameValues; | |||||
import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUserInfoResult; | |||||
import java.lang.reflect.Type; | |||||
/** | |||||
* Created by YuJian on 2017/7/11. | |||||
* | |||||
* @author YuJian | |||||
* @version 2017/7/11 | |||||
*/ | |||||
public class WxMpMemberCardUserInfoResultGsonAdapter implements JsonDeserializer<WxMpMemberCardUserInfoResult> { | |||||
@Override | |||||
public WxMpMemberCardUserInfoResult deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { | |||||
WxMpMemberCardUserInfoResult result = new WxMpMemberCardUserInfoResult(); | |||||
JsonObject jsonObject = jsonElement.getAsJsonObject(); | |||||
result.setOpenId(GsonHelper.getString(jsonObject, "openid")); | |||||
result.setErrorCode(GsonHelper.getString(jsonObject, "errcode")); | |||||
result.setErrorMsg(GsonHelper.getString(jsonObject, "errmsg")); | |||||
result.setNickname(GsonHelper.getString(jsonObject, "nickname")); | |||||
result.setMembershipNumber(GsonHelper.getString(jsonObject, "membership_number")); | |||||
result.setBonus(GsonHelper.getInteger(jsonObject, "bonus")); | |||||
result.setSex(GsonHelper.getString(jsonObject, "sex")); | |||||
result.setUserCardStatus(GsonHelper.getString(jsonObject, "user_card_status")); | |||||
result.setHasActive(GsonHelper.getBoolean(jsonObject, "has_active")); | |||||
JsonObject userInfoJsonObject = jsonObject.getAsJsonObject("user_info"); | |||||
MemberCardUserInfo cardUserInfo = new MemberCardUserInfo(); | |||||
JsonArray commonFieldListObj = userInfoJsonObject.getAsJsonArray("common_field_list"); | |||||
NameValues[] commonFieldListValues = new NameValues[commonFieldListObj.size()]; | |||||
for (int i = 0; i < commonFieldListObj.size(); i++) { | |||||
JsonObject commonField = commonFieldListObj.get(i).getAsJsonObject(); | |||||
NameValues commonNameValues = new NameValues(); | |||||
commonNameValues.setName(GsonHelper.getString(commonField, "name")); | |||||
commonNameValues.setValue(GsonHelper.getString(commonField, "value")); | |||||
commonFieldListValues[i] = commonNameValues; | |||||
} | |||||
cardUserInfo.setCommonFieldList(commonFieldListValues); | |||||
JsonArray customFieldListObj = userInfoJsonObject.getAsJsonArray("custom_field_list"); | |||||
NameValues[] customFieldListValues = new NameValues[customFieldListObj.size()]; | |||||
for (int i = 0; i < customFieldListObj.size(); i++) { | |||||
JsonObject customField = customFieldListObj.get(i).getAsJsonObject(); | |||||
NameValues customNameValues = new NameValues(); | |||||
customNameValues.setName(GsonHelper.getString(customField, "name")); | |||||
customNameValues.setValue(GsonHelper.getString(customField, "value")); | |||||
JsonArray valueListArray = customField.getAsJsonArray("value_list"); | |||||
String[] valueList = new String[valueListArray.size()]; | |||||
for (int j = 0; j < valueListArray.size(); j++) { | |||||
JsonObject valueListObj = valueListArray.getAsJsonObject(); | |||||
valueList[i] = valueListObj.getAsString(); | |||||
} | |||||
customNameValues.setValueList(valueList); | |||||
customFieldListValues[i] = customNameValues; | |||||
} | |||||
cardUserInfo.setCustomFieldList(customFieldListValues); | |||||
result.setUserInfo(cardUserInfo); | |||||
return result; | |||||
} | |||||
} |