| @@ -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(); | |||
| /** | |||
| * 返回会员卡相关接口方法的实现类对象,以方便调用其各个接口 | |||
| * | |||
| * @return WxMpMemberCardService | |||
| */ | |||
| WxMpMemberCardService getMemberCardService(); | |||
| /** | |||
| * 初始化http请求对象 | |||
| */ | |||
| @@ -42,6 +42,7 @@ public abstract class AbstractWxMpServiceImpl<H, P> implements WxMpService, Requ | |||
| private WxMpTemplateMsgService templateMsgService = new WxMpTemplateMsgServiceImpl(this); | |||
| private WxMpDeviceService deviceService = new WxMpDeviceServiceImpl(this); | |||
| private WxMpShakeService shakeService = new WxMpShakeServiceImpl(this); | |||
| private WxMpMemberCardService memberCardService = new WxMpMemberCardServiceImpl(this); | |||
| private int retrySleepMillis = 1000; | |||
| private int maxRetryTimes = 5; | |||
| @@ -406,6 +407,11 @@ public abstract class AbstractWxMpServiceImpl<H, P> implements WxMpService, Requ | |||
| return this.shakeService; | |||
| } | |||
| @Override | |||
| public WxMpMemberCardService getMemberCardService() { | |||
| return this.memberCardService; | |||
| } | |||
| @Override | |||
| public RequestHttp getRequestHttp() { | |||
| 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.WxDataCubeUserSummary; | |||
| 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.result.*; | |||
| import me.chanjar.weixin.mp.bean.template.WxMpTemplateIndustry; | |||
| @@ -49,6 +50,7 @@ public class WxMpGsonBuilder { | |||
| INSTANCE.registerTypeAdapter(WxMediaImgUploadResult.class, new WxMediaImgUploadResultGsonAdapter()); | |||
| INSTANCE.registerTypeAdapter(WxMpTemplateIndustry.class, new WxMpIndustryGsonAdapter()); | |||
| INSTANCE.registerTypeAdapter(WxMpUserBlacklistGetResult.class, new WxUserBlacklistGetResultGsonAdapter()); | |||
| INSTANCE.registerTypeAdapter(WxMpMemberCardUserInfoResult.class, new WxMpMemberCardUserInfoResultGsonAdapter()); | |||
| } | |||
| 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; | |||
| } | |||
| } | |||