Browse Source

Merge pull request #263 from mgcnrx11/feat_card_coupon

Feature card coupon
master
Daniel Qian 9 years ago
parent
commit
b5986cfd4f
12 changed files with 731 additions and 2 deletions
  1. +10
    -1
      weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java
  2. +102
    -0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java
  3. +15
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java
  4. +26
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java
  5. +79
    -1
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java
  6. +177
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java
  7. +72
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpCard.java
  8. +78
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlMessage.java
  9. +87
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCardResult.java
  10. +38
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpCardGsonAdapter.java
  11. +45
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpCardResultGsonAdapter.java
  12. +2
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java

+ 10
- 1
weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java View File

@@ -47,7 +47,7 @@ public class WxConsts {
/////////////////////// ///////////////////////
public static final String MASS_ST_SUCCESS = "send success"; public static final String MASS_ST_SUCCESS = "send success";
public static final String MASS_ST_FAIL = "send fail"; public static final String MASS_ST_FAIL = "send fail";
public static final String MASS_ST_涉嫌广告 = "err(10001)";
public static final String MASS_ST_涉嫌广告 = "err(10001)";
public static final String MASS_ST_涉嫌政治 = "err(20001)"; public static final String MASS_ST_涉嫌政治 = "err(20001)";
public static final String MASS_ST_涉嫌社会 = "err(20004)"; public static final String MASS_ST_涉嫌社会 = "err(20004)";
public static final String MASS_ST_涉嫌色情 = "err(20002)"; public static final String MASS_ST_涉嫌色情 = "err(20002)";
@@ -93,6 +93,15 @@ public class WxConsts {
public static final String EVT_LOCATION_SELECT = "location_select"; public static final String EVT_LOCATION_SELECT = "location_select";
public static final String EVT_TEMPLATESENDJOBFINISH = "TEMPLATESENDJOBFINISH"; public static final String EVT_TEMPLATESENDJOBFINISH = "TEMPLATESENDJOBFINISH";
public static final String EVT_ENTER_AGENT = "enter_agent"; public static final String EVT_ENTER_AGENT = "enter_agent";
public static final String EVT_CARD_PASS_CHECK = "card_pass_check";
public static final String EVT_CARD_NOT_PASS_CHECK = "card_not_pass_check";
public static final String EVT_USER_GET_CARD = "user_get_card";
public static final String EVT_USER_DEL_CARD = "user_del_card";
public static final String EVT_USER_CONSUME_CARD = "user_consume_card";
public static final String EVT_USER_PAY_FROM_PAY_CELL = "user_pay_from_pay_cell";
public static final String EVT_USER_VIEW_CARD = "user_view_card";
public static final String EVT_USER_ENTER_SESSION_FROM_CARD = "user_enter_session_from_card";
public static final String EVT_CARD_SKU_REMIND = "card_sku_remind"; // 库存报警


/////////////////////// ///////////////////////
// 上传多媒体文件的类型 // 上传多媒体文件的类型


+ 102
- 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java View File

@@ -0,0 +1,102 @@
package me.chanjar.weixin.common.bean;

import java.io.Serializable;

/**
* 卡券Api签名
*
* @author YuJian
* @version 15/11/8
*/
public class WxCardApiSignature implements Serializable {

private String appId;

private String cardId;

private String cardType;

private String locationId;

private String code;

private String openId;

private Long timestamp;

private String nonceStr;

private String signature;

public String getAppId() {
return appId;
}

public void setAppId(String appId) {
this.appId = appId;
}

public String getCardId() {
return cardId;
}

public void setCardId(String cardId) {
this.cardId = cardId;
}

public String getCardType() {
return cardType;
}

public void setCardType(String cardType) {
this.cardType = cardType;
}

public String getLocationId() {
return locationId;
}

public void setLocationId(String locationId) {
this.locationId = locationId;
}

public String getCode() {
return code;
}

public void setCode(String code) {
this.code = code;
}

public String getOpenId() {
return openId;
}

public void setOpenId(String openId) {
this.openId = openId;
}

public Long getTimestamp() {
return timestamp;
}

public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
}

public String getNonceStr() {
return nonceStr;
}

public void setNonceStr(String nonceStr) {
this.nonceStr = nonceStr;
}

public String getSignature() {
return signature;
}

public void setSignature(String signature) {
this.signature = signature;
}
}

+ 15
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java View File

@@ -50,6 +50,21 @@ public interface WxMpConfigStorage {
*/ */
public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds); public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds);


public String getCardApiTicket();

public boolean isCardApiTicketExpired();

/**
* 强制将卡券api ticket过期掉
*/
public void expireCardApiTicket();

/**
* 应该是线程安全的
* @param cardApiTicket
*/
public void updateCardApiTicket(String cardApiTicket, int expiresInSeconds);

public String getAppId(); public String getAppId();


public String getSecret(); public String getSecret();


+ 26
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java View File

@@ -32,6 +32,9 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
protected volatile String jsapiTicket; protected volatile String jsapiTicket;
protected volatile long jsapiTicketExpiresTime; protected volatile long jsapiTicketExpiresTime;


protected volatile String cardApiTicket;
protected volatile long cardApiTicketExpiresTime;

/** /**
* 临时文件目录 * 临时文件目录
*/ */
@@ -90,6 +93,27 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
this.jsapiTicketExpiresTime = 0; this.jsapiTicketExpiresTime = 0;
} }


/**
* 卡券api_ticket
*/
public String getCardApiTicket() {
return cardApiTicket;
}

public boolean isCardApiTicketExpired() {
return System.currentTimeMillis() > this.cardApiTicketExpiresTime;
}

public synchronized void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) {
this.cardApiTicket = cardApiTicket;
// 预留200秒的时间
this.cardApiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l;
}

public void expireCardApiTicket() {
this.cardApiTicketExpiresTime = 0;
}

public String getAppId() { public String getAppId() {
return this.appId; return this.appId;
} }
@@ -192,6 +216,8 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage {
", http_proxy_password='" + http_proxy_password + '\'' + ", http_proxy_password='" + http_proxy_password + '\'' +
", jsapiTicket='" + jsapiTicket + '\'' + ", jsapiTicket='" + jsapiTicket + '\'' +
", jsapiTicketExpiresTime='" + jsapiTicketExpiresTime + '\'' + ", jsapiTicketExpiresTime='" + jsapiTicketExpiresTime + '\'' +
", cardApiTicket='" + cardApiTicket + '\'' +
", cardApiTicketExpiresTime='" + cardApiTicketExpiresTime + '\'' +
", tmpDirFile='" + tmpDirFile + '\'' + ", tmpDirFile='" + tmpDirFile + '\'' +
'}'; '}';
} }


+ 79
- 1
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java View File

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


import me.chanjar.weixin.common.bean.WxCardApiSignature;
import me.chanjar.weixin.common.bean.WxMenu; import me.chanjar.weixin.common.bean.WxMenu;
import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
@@ -770,7 +771,7 @@ public interface WxMpService {
* @return * @return
*/ */
public boolean checkJSSDKCallbackDataSignature(Map<String, String> kvm, String signature); public boolean checkJSSDKCallbackDataSignature(Map<String, String> kvm, String signature);
/** /**
* 发送微信红包给个人用户 * 发送微信红包给个人用户
* @param parameters * @param parameters
@@ -778,4 +779,81 @@ public interface WxMpService {
* @throws WxErrorException * @throws WxErrorException
*/ */
public WxRedpackResult sendRedpack(Map<String, String> parameters) throws WxErrorException; public WxRedpackResult sendRedpack(Map<String, String> parameters) throws WxErrorException;

/**
* 获得卡券api_ticket,不强制刷新卡券api_ticket
* @see #getCardApiTicket(boolean)
* @return 卡券api_ticket
* @throws WxErrorException
*/
public String getCardApiTicket() throws WxErrorException;

/**
* <pre>
* 获得卡券api_ticket
* 获得时会检查卡券apiToken是否过期,如果过期了,那么就刷新一下,否则就什么都不干
*
* 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD.954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94.9F.E6.88.90.E7.AE.97.E6.B3.95
* </pre>
* @param forceRefresh 强制刷新
* @return 卡券api_ticket
* @throws WxErrorException
*/
public String getCardApiTicket(boolean forceRefresh) throws WxErrorException;

/**
* <pre>
* 创建调用卡券api时所需要的签名
*
* 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD
* .954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94
* .9F.E6.88.90.E7.AE.97.E6.B3.95
* </pre>
*
* @param optionalSignParam 参与签名的参数数组。
* 可以为下列字段:app_id, card_id, card_type, code, openid, location_id
* @return 卡券Api签名对象
*/
public WxCardApiSignature createCardApiSignature(String... optionalSignParam) throws
WxErrorException;

/**
* 卡券Code解码
* @param encryptCode 加密Code,通过JSSDK的chooseCard接口获得
* @return 解密后的Code
* @throws WxErrorException
*/
public String decryptCardCode(String encryptCode) throws WxErrorException;

/**
* 卡券Code查询
* @param cardId 卡券ID代表一类卡券
* @param code 单张卡券的唯一标准
* @param checkConsume 是否校验code核销状态,填入true和false时的code异常状态返回数据不同
* @return WxMpCardResult对象
* @throws WxErrorException
*/
public WxMpCardResult queryCardCode(String cardId, String code, boolean checkConsume)
throws WxErrorException;
/**
* 卡券Code核销。核销失败会抛出异常
* @param code 单张卡券的唯一标准
* @return
* @throws WxErrorException
*/
public void consumeCardCode(String code) throws WxErrorException;

/**
* 卡券Mark接口。
* 开发者在帮助消费者核销卡券之前,必须帮助先将此code(卡券串码)与一个openid绑定(即mark住),
* 才能进一步调用核销接口,否则报错。
* @param code 卡券的code码
* @param cardId 卡券的ID
* @param openId 用券用户的openid
* @param isMark 是否要mark(占用)这个code,填写true或者false,表示占用或解除占用
* @throws WxErrorException
*/
public void markCardCode(String code, String cardId, String openId, boolean isMark) throws
WxErrorException;
} }

+ 177
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java View File

@@ -5,6 +5,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.StringReader; import java.io.StringReader;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -14,8 +15,10 @@ import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.UUID; import java.util.UUID;


import com.google.gson.JsonPrimitive;
import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.bean.WxCardApiSignature;
import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.WxMenu; import me.chanjar.weixin.common.bean.WxMenu;
import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.bean.result.WxError;
@@ -43,6 +46,7 @@ import me.chanjar.weixin.mp.bean.WxMpMaterialArticleUpdate;
import me.chanjar.weixin.mp.bean.WxMpMaterialNews; import me.chanjar.weixin.mp.bean.WxMpMaterialNews;
import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; import me.chanjar.weixin.mp.bean.WxMpSemanticQuery;
import me.chanjar.weixin.mp.bean.WxMpTemplateMessage; import me.chanjar.weixin.mp.bean.WxMpTemplateMessage;
import me.chanjar.weixin.mp.bean.result.WxMpCardResult;
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult;
import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult; import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult;
import me.chanjar.weixin.mp.bean.result.WxMpMaterialCountResult; import me.chanjar.weixin.mp.bean.result.WxMpMaterialCountResult;
@@ -112,6 +116,11 @@ public class WxMpServiceImpl implements WxMpService {
*/ */
protected final Object globalJsapiTicketRefreshLock = new Object(); protected final Object globalJsapiTicketRefreshLock = new Object();


/**
* 全局的是否正在刷新卡券api_ticket的锁
*/
protected final Object globalCardApiTicketRefreshLock = new Object();

protected WxMpConfigStorage wxMpConfigStorage; protected WxMpConfigStorage wxMpConfigStorage;


protected CloseableHttpClient httpClient; protected CloseableHttpClient httpClient;
@@ -1006,4 +1015,172 @@ public class WxMpServiceImpl implements WxMpService {
throw new WxErrorException(error); throw new WxErrorException(error);
} }
} }

/**
* 获得卡券api_ticket,不强制刷新卡券api_ticket
*
* @return 卡券api_ticket
* @throws WxErrorException
* @see #getCardApiTicket(boolean)
*/
@Override
public String getCardApiTicket() throws WxErrorException {
return getCardApiTicket(false);
}

/**
* <pre>
* 获得卡券api_ticket
* 获得时会检查卡券apiToken是否过期,如果过期了,那么就刷新一下,否则就什么都不干
*
* 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD
* .954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94
* .9F.E6.88.90.E7.AE.97.E6.B3.95
* </pre>
*
* @param forceRefresh 强制刷新
* @return 卡券api_ticket
* @throws WxErrorException
*/
@Override
public String getCardApiTicket(boolean forceRefresh) throws WxErrorException {
if (forceRefresh) {
wxMpConfigStorage.expireCardApiTicket();
}
if (wxMpConfigStorage.isCardApiTicketExpired()) {
synchronized (globalCardApiTicketRefreshLock) {
if (wxMpConfigStorage.isCardApiTicketExpired()) {
String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=wx_card";
String responseContent = execute(new JoddGetRequestExecutor(), url, null);
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
String cardApiTicket = tmpJsonObject.get("ticket").getAsString();
int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
wxMpConfigStorage.updateCardApiTicket(cardApiTicket, expiresInSeconds);
}
}
}
return wxMpConfigStorage.getCardApiTicket();
}

/**
* <pre>
* 创建调用卡券api时所需要的签名
*
* 详情请见:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E9.99.84.E5.BD
* .954-.E5.8D.A1.E5.88.B8.E6.89.A9.E5.B1.95.E5.AD.97.E6.AE.B5.E5.8F.8A.E7.AD.BE.E5.90.8D.E7.94
* .9F.E6.88.90.E7.AE.97.E6.B3.95
* </pre>
*
* @param optionalSignParam 参与签名的参数数组。
* 可以为下列字段:app_id, card_id, card_type, code, openid, location_id
* @return 卡券Api签名对象
*/
@Override
public WxCardApiSignature createCardApiSignature(String... optionalSignParam) throws
WxErrorException {
long timestamp = System.currentTimeMillis() / 1000;
String nonceStr = RandomUtils.getRandomStr();
String cardApiTicket = getCardApiTicket(false);

String[] signParam = Arrays.copyOf(optionalSignParam, optionalSignParam.length + 3);
signParam[optionalSignParam.length] = String.valueOf(timestamp);
signParam[optionalSignParam.length + 1] = nonceStr;
signParam[optionalSignParam.length + 2] = cardApiTicket;
try {
String signature = SHA1.gen(signParam);
WxCardApiSignature cardApiSignature = new WxCardApiSignature();
cardApiSignature.setTimestamp(timestamp);
cardApiSignature.setNonceStr(nonceStr);
cardApiSignature.setSignature(signature);
return cardApiSignature;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}

/**
* 卡券Code解码
*
* @param encryptCode 加密Code,通过JSSDK的chooseCard接口获得
* @return 解密后的Code
* @throws WxErrorException
*/
@Override
public String decryptCardCode(String encryptCode) throws WxErrorException {
String url = "https://api.weixin.qq.com/card/code/decrypt";
JsonObject param = new JsonObject();
param.addProperty("encrypt_code", encryptCode);
String responseContent = post(url, param.toString());
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
JsonPrimitive jsonPrimitive = tmpJsonObject.getAsJsonPrimitive("code");
return jsonPrimitive.getAsString();
}

/**
* 卡券Code查询
*
* @param cardId 卡券ID代表一类卡券
* @param code 单张卡券的唯一标准
* @param checkConsume 是否校验code核销状态,填入true和false时的code异常状态返回数据不同
* @return WxMpCardResult对象
* @throws WxErrorException
*/
@Override
public WxMpCardResult queryCardCode(String cardId, String code, boolean checkConsume) throws WxErrorException {
String url = "https://api.weixin.qq.com/card/code/get";
JsonObject param = new JsonObject();
param.addProperty("card_id", cardId);
param.addProperty("code", code);
param.addProperty("check_consume", checkConsume);
String responseContent = post(url, param.toString());
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
return WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement,
new TypeToken<WxMpCardResult>() {
}.getType());
}

/**
* 卡券Code核销。核销失败会抛出异常
*
* @param code 单张卡券的唯一标准
* @throws WxErrorException
*/
@Override
public void consumeCardCode(String code) throws WxErrorException {
String url = "https://api.weixin.qq.com/card/code/consume";
JsonObject param = new JsonObject();
param.addProperty("code", code);
post(url, param.toString());
}

/**
* 卡券Mark接口。
* 开发者在帮助消费者核销卡券之前,必须帮助先将此code(卡券串码)与一个openid绑定(即mark住),
* 才能进一步调用核销接口,否则报错。
*
* @param code 卡券的code码
* @param cardId 卡券的ID
* @param openId 用券用户的openid
* @param isMark 是否要mark(占用)这个code,填写true或者false,表示占用或解除占用
* @throws WxErrorException
*/
@Override
public void markCardCode(String code, String cardId, String openId, boolean isMark) throws
WxErrorException {
String url = "https://api.weixin.qq.com/card/code/mark";
JsonObject param = new JsonObject();
param.addProperty("code", code);
param.addProperty("card_id", cardId);
param.addProperty("openid", openId);
param.addProperty("is_mark", isMark);
String responseContent = post(url, param.toString());
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
WxMpCardResult cardResult = WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement,
new TypeToken<WxMpCardResult>() { }.getType());
if (!cardResult.getErrorCode().equals("0")) {
log.warn("朋友的券mark失败:{}", cardResult.getErrorMsg());
}
}
} }

+ 72
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpCard.java View File

@@ -0,0 +1,72 @@
package me.chanjar.weixin.mp.bean;


/**
* 微信卡券
*
* @author YuJian
* @version 15/11/11
*/
public class WxMpCard {

private String cardId;

private Long beginTime;

private Long endTime;

private String userCardStatus;

private Boolean canConsume;

public String getCardId() {
return cardId;
}

public void setCardId(String cardId) {
this.cardId = cardId;
}

public Long getBeginTime() {
return beginTime;
}

public void setBeginTime(Long beginTime) {
this.beginTime = beginTime;
}

public Long getEndTime() {
return endTime;
}

public void setEndTime(Long endTime) {
this.endTime = endTime;
}

public String getUserCardStatus() {
return userCardStatus;
}

public void setUserCardStatus(String userCardStatus) {
this.userCardStatus = userCardStatus;
}

public Boolean getCanConsume() {
return canConsume;
}

public void setCanConsume(Boolean canConsume) {
this.canConsume = canConsume;
}

@Override
public String toString() {
return "WxMpCard{" +
"cardId='" + cardId + '\'' +
", beginTime=" + beginTime +
", endTime=" + endTime +
", userCardStatus='" + userCardStatus + '\'' +
", canConsume=" + canConsume +
'}';
}
}

+ 78
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpXmlMessage.java View File

@@ -150,6 +150,31 @@ public class WxMpXmlMessage implements Serializable {
@XStreamAlias("ErrorCount") @XStreamAlias("ErrorCount")
private Integer errorCount; private Integer errorCount;


///////////////////////////////////////
// 卡券相关事件推送
///////////////////////////////////////
@XStreamAlias("CardId")
@XStreamConverter(value=XStreamCDataConverter.class)
private String cardId;

@XStreamAlias("FriendUserName")
@XStreamConverter(value=XStreamCDataConverter.class)
private String friendUserName;

@XStreamAlias("IsGiveByFriend")
private Integer isGiveByFriend; // 是否为转赠,1代表是,0代表否

@XStreamAlias("UserCardCode")
@XStreamConverter(value=XStreamCDataConverter.class)
private String userCardCode;

@XStreamAlias("OldUserCardCode")
@XStreamConverter(value=XStreamCDataConverter.class)
private String oldUserCardCode;

@XStreamAlias("OuterId")
private Integer outerId;

@XStreamAlias("ScanCodeInfo") @XStreamAlias("ScanCodeInfo")
private ScanCodeInfo scanCodeInfo = new ScanCodeInfo(); private ScanCodeInfo scanCodeInfo = new ScanCodeInfo();


@@ -456,6 +481,54 @@ public class WxMpXmlMessage implements Serializable {
this.errorCount = errorCount; this.errorCount = errorCount;
} }


public String getCardId() {
return cardId;
}

public void setCardId(String cardId) {
this.cardId = cardId;
}

public String getFriendUserName() {
return friendUserName;
}

public void setFriendUserName(String friendUserName) {
this.friendUserName = friendUserName;
}

public Integer getIsGiveByFriend() {
return isGiveByFriend;
}

public void setIsGiveByFriend(Integer isGiveByFriend) {
this.isGiveByFriend = isGiveByFriend;
}

public String getUserCardCode() {
return userCardCode;
}

public void setUserCardCode(String userCardCode) {
this.userCardCode = userCardCode;
}

public String getOldUserCardCode() {
return oldUserCardCode;
}

public void setOldUserCardCode(String oldUserCardCode) {
this.oldUserCardCode = oldUserCardCode;
}

public Integer getOuterId() {
return outerId;
}

public void setOuterId(Integer outerId) {
this.outerId = outerId;
}

public WxMpXmlMessage.ScanCodeInfo getScanCodeInfo() { public WxMpXmlMessage.ScanCodeInfo getScanCodeInfo() {
return scanCodeInfo; return scanCodeInfo;
} }
@@ -652,6 +725,11 @@ public class WxMpXmlMessage implements Serializable {
", filterCount=" + filterCount + ", filterCount=" + filterCount +
", sentCount=" + sentCount + ", sentCount=" + sentCount +
", errorCount=" + errorCount + ", errorCount=" + errorCount +
", cardId='" + cardId + '\'' +
", isGiveByFriend=" + isGiveByFriend +
", userCardCode='" + userCardCode + '\'' +
", oldUserCardCode='" + oldUserCardCode + '\'' +
", outerId=" + outerId +
", scanCodeInfo=" + scanCodeInfo + ", scanCodeInfo=" + scanCodeInfo +
", sendPicsInfo=" + sendPicsInfo + ", sendPicsInfo=" + sendPicsInfo +
", sendLocationInfo=" + sendLocationInfo + ", sendLocationInfo=" + sendLocationInfo +


+ 87
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCardResult.java View File

@@ -0,0 +1,87 @@
package me.chanjar.weixin.mp.bean.result;

import me.chanjar.weixin.mp.bean.WxMpCard;

import java.io.Serializable;

/**
* 卡券查询Code,核销Code接口返回结果
*
* @author YuJian
* @version 15/11/11
*/
public class WxMpCardResult implements Serializable {

private String errorCode;

private String errorMsg;

private String openId;

private WxMpCard card;

private String userCardStatus;

private Boolean canConsume;

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 WxMpCard getCard() {
return card;
}

public void setCard(WxMpCard card) {
this.card = card;
}

@Override
public String toString() {
return "WxMpCardResult{" +
"errorCode='" + errorCode + '\'' +
", errorMsg='" + errorMsg + '\'' +
", openId='" + openId + '\'' +
", card=" + card +
", userCardStatus='" + userCardStatus + '\'' +
", canConsume=" + canConsume +
'}';
}

public String getUserCardStatus() {
return userCardStatus;
}

public void setUserCardStatus(String userCardStatus) {
this.userCardStatus = userCardStatus;
}

public Boolean getCanConsume() {
return canConsume;
}

public void setCanConsume(Boolean canConsume) {
this.canConsume = canConsume;
}

}

+ 38
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpCardGsonAdapter.java View File

@@ -0,0 +1,38 @@
package me.chanjar.weixin.mp.util.json;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
import me.chanjar.weixin.common.util.json.GsonHelper;
import me.chanjar.weixin.mp.bean.WxMpCard;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Type;
import java.util.List;

/**
* Created by YuJian on 15/11/11.
*
* @author YuJian
* @version 15/11/11
*/
public class WxMpCardGsonAdapter implements JsonDeserializer<WxMpCard> {

@Override
public WxMpCard deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext
jsonDeserializationContext) throws JsonParseException {
WxMpCard card = new WxMpCard();
JsonObject jsonObject = jsonElement.getAsJsonObject();

card.setCardId(GsonHelper.getString(jsonObject, "card_id"));
card.setBeginTime(GsonHelper.getLong(jsonObject, "begin_time"));
card.setEndTime(GsonHelper.getLong(jsonObject, "end_time"));

return card;
}

}

+ 45
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpCardResultGsonAdapter.java View File

@@ -0,0 +1,45 @@
package me.chanjar.weixin.mp.util.json;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.reflect.TypeToken;
import me.chanjar.weixin.common.util.json.GsonHelper;
import me.chanjar.weixin.mp.bean.WxMpCard;
import me.chanjar.weixin.mp.bean.result.WxMpCardResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Type;
import java.text.ParseException;
import java.util.List;

/**
* Created by YuJian on 15/11/11.
*
* @author YuJian
* @version 15/11/11
*/
public class WxMpCardResultGsonAdapter implements JsonDeserializer<WxMpCardResult> {
@Override
public WxMpCardResult deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
WxMpCardResult cardResult = new WxMpCardResult();
JsonObject jsonObject = jsonElement.getAsJsonObject();

cardResult.setOpenId(GsonHelper.getString(jsonObject, "openid"));
cardResult.setErrorCode(GsonHelper.getString(jsonObject, "errcode"));
cardResult.setErrorMsg(GsonHelper.getString(jsonObject, "errmsg"));
cardResult.setCanConsume(GsonHelper.getBoolean(jsonObject, "can_consume"));
cardResult.setUserCardStatus(GsonHelper.getString(jsonObject, "user_card_status"));

WxMpCard card = WxMpGsonBuilder.INSTANCE.create().fromJson(jsonObject.get("card"),
new TypeToken<WxMpCard>() {
}.getType());

cardResult.setCard(card);

return cardResult;
}
}

+ 2
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java View File

@@ -38,6 +38,8 @@ public class WxMpGsonBuilder {
INSTANCE.registerTypeAdapter(WxMpMaterialNewsBatchGetResult.WxMaterialNewsBatchGetNewsItem.class, new WxMpMaterialNewsBatchGetGsonItemAdapter()); INSTANCE.registerTypeAdapter(WxMpMaterialNewsBatchGetResult.WxMaterialNewsBatchGetNewsItem.class, new WxMpMaterialNewsBatchGetGsonItemAdapter());
INSTANCE.registerTypeAdapter(WxMpMaterialFileBatchGetResult.class, new WxMpMaterialFileBatchGetGsonAdapter()); INSTANCE.registerTypeAdapter(WxMpMaterialFileBatchGetResult.class, new WxMpMaterialFileBatchGetGsonAdapter());
INSTANCE.registerTypeAdapter(WxMpMaterialFileBatchGetResult.WxMaterialFileBatchGetNewsItem.class, new WxMpMaterialFileBatchGetGsonItemAdapter()); INSTANCE.registerTypeAdapter(WxMpMaterialFileBatchGetResult.WxMaterialFileBatchGetNewsItem.class, new WxMpMaterialFileBatchGetGsonItemAdapter());
INSTANCE.registerTypeAdapter(WxMpCardResult.class, new WxMpCardResultGsonAdapter());
INSTANCE.registerTypeAdapter(WxMpCard.class, new WxMpCardGsonAdapter());
} }


public static Gson create() { public static Gson create() {


Loading…
Cancel
Save