修复媒体消息转换错误bug & 新增创建卡券二维码接口
This commit is contained in:
@@ -4,18 +4,21 @@ import java.io.InputStream;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.foxinmy.weixin4j.card.CardCoupon;
|
||||
import com.foxinmy.weixin4j.card.CardCoupons;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.ApiResult;
|
||||
import com.foxinmy.weixin4j.model.Button;
|
||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
||||
import com.foxinmy.weixin4j.model.card.CardCoupon;
|
||||
import com.foxinmy.weixin4j.model.card.CardCoupons;
|
||||
import com.foxinmy.weixin4j.model.card.CardQR;
|
||||
import com.foxinmy.weixin4j.model.media.MediaCounter;
|
||||
import com.foxinmy.weixin4j.model.media.MediaDownloadResult;
|
||||
import com.foxinmy.weixin4j.model.media.MediaItem;
|
||||
import com.foxinmy.weixin4j.model.media.MediaRecord;
|
||||
import com.foxinmy.weixin4j.model.media.MediaUploadResult;
|
||||
import com.foxinmy.weixin4j.model.paging.Pageable;
|
||||
import com.foxinmy.weixin4j.model.qr.QRParameter;
|
||||
import com.foxinmy.weixin4j.model.qr.QRResult;
|
||||
import com.foxinmy.weixin4j.mp.api.CardApi;
|
||||
import com.foxinmy.weixin4j.mp.api.CustomApi;
|
||||
import com.foxinmy.weixin4j.mp.api.DataApi;
|
||||
@@ -43,8 +46,6 @@ import com.foxinmy.weixin4j.mp.model.KfSession.KfSessionCounter;
|
||||
import com.foxinmy.weixin4j.mp.model.Menu;
|
||||
import com.foxinmy.weixin4j.mp.model.MenuMatchRule;
|
||||
import com.foxinmy.weixin4j.mp.model.MenuSetting;
|
||||
import com.foxinmy.weixin4j.mp.model.QRParameter;
|
||||
import com.foxinmy.weixin4j.mp.model.QRResult;
|
||||
import com.foxinmy.weixin4j.mp.model.SemQuery;
|
||||
import com.foxinmy.weixin4j.mp.model.SemResult;
|
||||
import com.foxinmy.weixin4j.mp.model.Tag;
|
||||
@@ -176,6 +177,7 @@ public class WeixinProxy {
|
||||
componentTokenManager), perTicketManager.getCacheStorager()));
|
||||
this.settings = new Weixin4jSettings<WeixinAccount>(new WeixinAccount(
|
||||
perTicketManager.getAuthAppId(), null));
|
||||
this.settings.setCacheStorager(perTicketManager.getCacheStorager());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1376,8 +1378,8 @@ public class WeixinProxy {
|
||||
* @param parameter
|
||||
* 二维码参数
|
||||
* @return 二维码结果对象
|
||||
* @throws WeixinException
|
||||
* @see com.foxinmy.weixin4j.mp.model.QRResult
|
||||
* @throws WeixinException
|
||||
* @see com.foxinmy.weixin4j.model.qr.QRResult
|
||||
* @see com.foxinmy.weixin4j.model.qr.QRParameter
|
||||
* @see com.foxinmy.weixin4j.mp.api.QrApi
|
||||
* @see <a href=
|
||||
@@ -1904,5 +1906,25 @@ public class WeixinProxy {
|
||||
throws WeixinException {
|
||||
return cardApi.setCardSelfConsumeCell(cardId, isOpen);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建卡券二维码: 开发者可调用该接口生成一张卡券二维码供用户扫码后添加卡券到卡包。
|
||||
*
|
||||
* @param expireSeconds
|
||||
* 指定二维码的有效时间,范围是60 ~ 1800秒。不填默认为365天有效
|
||||
* @param cardQRs
|
||||
* 二维码参数:二维码领取单张卡券/多张卡券
|
||||
* @return 二维码结果对象
|
||||
* @see com.foxinmy.weixin4j.model.qr.QRResult
|
||||
* @see com.foxinmy.weixin4j.model.qr.QRParameter
|
||||
* @see com.foxinmy.weixin4j.mp.api.CardApi
|
||||
* @see <a
|
||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025062&token=&lang=zh_CN">投放卡券</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public QRResult createCardQR(Integer expireSeconds, CardQR... cardQRs)
|
||||
throws WeixinException {
|
||||
return cardApi.createCardQR(expireSeconds, cardQRs);
|
||||
}
|
||||
|
||||
public final static String VERSION = "1.7.0";
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
package com.foxinmy.weixin4j.mp.api;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.foxinmy.weixin4j.card.CardCoupon;
|
||||
import com.foxinmy.weixin4j.card.CardCoupons;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.ApiResult;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.model.card.CardCoupon;
|
||||
import com.foxinmy.weixin4j.model.card.CardCoupons;
|
||||
import com.foxinmy.weixin4j.model.card.CardQR;
|
||||
import com.foxinmy.weixin4j.model.qr.QRParameter;
|
||||
import com.foxinmy.weixin4j.model.qr.QRResult;
|
||||
import com.foxinmy.weixin4j.token.TokenManager;
|
||||
import com.foxinmy.weixin4j.util.IOUtil;
|
||||
|
||||
/**
|
||||
* 卡券API
|
||||
@@ -111,4 +119,41 @@ public class CardApi extends MpApi {
|
||||
token.getAccessToken()), params.toJSONString());
|
||||
return response.getAsResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建卡券二维码: 开发者可调用该接口生成一张卡券二维码供用户扫码后添加卡券到卡包。
|
||||
*
|
||||
* @param expireSeconds
|
||||
* 指定二维码的有效时间,范围是60 ~ 1800秒。不填默认为365天有效
|
||||
* @param cardQRs
|
||||
* 二维码参数:二维码领取单张卡券/多张卡券
|
||||
* @return 二维码结果对象
|
||||
* @see com.foxinmy.weixin4j.model.qr.QRResult
|
||||
* @see com.foxinmy.weixin4j.model.qr.QRParameter
|
||||
* @see <a
|
||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025062&token=&lang=zh_CN">投放卡券</a>
|
||||
* @throws WeixinException
|
||||
*/
|
||||
public QRResult createCardQR(Integer expireSeconds, CardQR... cardQRs)
|
||||
throws WeixinException {
|
||||
QRParameter parameter = QRParameter.createCardCouponQR(expireSeconds,
|
||||
cardQRs);
|
||||
Token token = tokenManager.getCache();
|
||||
String qr_uri = getRequestUri("card_qr_ticket_uri");
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
String.format(qr_uri, token.getAccessToken()),
|
||||
JSON.toJSONString(parameter));
|
||||
QRResult result = response.getAsObject(new TypeReference<QRResult>() {
|
||||
});
|
||||
qr_uri = String.format(getRequestUri("qr_image_uri"),
|
||||
result.getTicket());
|
||||
response = weixinExecutor.get(qr_uri);
|
||||
result.setShowUrl(qr_uri);
|
||||
try {
|
||||
result.setContent(IOUtil.toByteArray(response.getBody()));
|
||||
} catch (IOException e) {
|
||||
throw new WeixinException(e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package com.foxinmy.weixin4j.mp.api;
|
||||
package com.foxinmy.weixin4j.mp.api;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||
import com.foxinmy.weixin4j.model.Token;
|
||||
import com.foxinmy.weixin4j.mp.model.QRParameter;
|
||||
import com.foxinmy.weixin4j.mp.model.QRResult;
|
||||
import com.foxinmy.weixin4j.model.qr.QRParameter;
|
||||
import com.foxinmy.weixin4j.model.qr.QRResult;
|
||||
import com.foxinmy.weixin4j.token.TokenManager;
|
||||
import com.foxinmy.weixin4j.util.IOUtil;
|
||||
|
||||
@@ -34,8 +35,8 @@ public class QrApi extends MpApi {
|
||||
* 二维码参数
|
||||
* @return 二维码结果对象
|
||||
* @throws WeixinException
|
||||
* @see com.foxinmy.weixin4j.mp.model.QRResult
|
||||
* @see com.foxinmy.weixin4j.mp.model.QRParameter
|
||||
* @see com.foxinmy.weixin4j.model.qr.QRResult
|
||||
* @see com.foxinmy.weixin4j.model.qr.QRParameter
|
||||
* @see <a
|
||||
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433542&token=&lang=zh_CN">生成二维码</a>
|
||||
*/
|
||||
@@ -44,12 +45,13 @@ public class QrApi extends MpApi {
|
||||
String qr_uri = getRequestUri("qr_ticket_uri");
|
||||
WeixinResponse response = weixinExecutor.post(
|
||||
String.format(qr_uri, token.getAccessToken()),
|
||||
parameter.getContent());
|
||||
JSON.toJSONString(parameter));
|
||||
QRResult result = response.getAsObject(new TypeReference<QRResult>() {
|
||||
});
|
||||
qr_uri = getRequestUri("qr_image_uri");
|
||||
response = weixinExecutor
|
||||
.get(String.format(qr_uri, result.getTicket()));
|
||||
qr_uri = String.format(getRequestUri("qr_image_uri"),
|
||||
result.getTicket());
|
||||
response = weixinExecutor.get(qr_uri);
|
||||
result.setShowUrl(qr_uri);
|
||||
try {
|
||||
result.setContent(IOUtil.toByteArray(response.getBody()));
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -186,6 +186,8 @@ card_create_uri={api_base_url}/card/create?access_token=%s
|
||||
card_paycell_uri={api_base_url}/card/paycell/set?access_token=%s
|
||||
# \u8bbe\u7f6e\u81ea\u52a9\u6838\u9500\u63a5\u53e3
|
||||
card_selfconsumecell_uri={api_base_url}/card/selfconsumecell/set?access_token=%s
|
||||
# \u521b\u5efa\u5361\u5238\u4e8c\u7ef4\u7801\u63a5\u53e3
|
||||
card_qr_ticket_uri={api_base_url}/card/qrcode/create?access_token=%s
|
||||
|
||||
# \u4f7f\u7528\u6388\u6743\u7801\u6362\u53d6\u516c\u4f17\u53f7\u7684\u63a5\u53e3\u8c03\u7528\u51ed\u636e\u548c\u6388\u6743\u4fe1\u606f
|
||||
component_exchange_authorizer_uri={api_cgi_url}/component/api_query_auth?component_access_token=%s
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
package com.foxinmy.weixin4j.mp.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.foxinmy.weixin4j.type.QRType;
|
||||
|
||||
/**
|
||||
* 二维码参数对象
|
||||
* <p>
|
||||
* 目前有2种类型的二维码,分别是临时二维码和永久二维码,前者有过期时间,最大为1800秒,但能够生成较多数量,后者无过期时间,数量较少(目前参数只支持1--
|
||||
* 100000)
|
||||
* </p>
|
||||
*
|
||||
* @className QRParameter
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2014年4月8日
|
||||
* @since JDK 1.6
|
||||
* @see #createPermanenceInt(int) 创建整型永久二维码
|
||||
* @see #createPermanenceStr(String) 创建字符串型永久二维码
|
||||
* @see #createTemporary(long) 创建整型默认30秒有效期临时二维码
|
||||
* @see #createTemporary(int, long) 创建整型有效期临时二维码
|
||||
*/
|
||||
public class QRParameter implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 6611187606558274253L;
|
||||
private static final int DEFAULT_TEMPORARY_EXPIRE_SECONDS = 30;
|
||||
|
||||
/**
|
||||
* 临时二维码的有效时间, 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒
|
||||
*/
|
||||
private int expireSeconds;
|
||||
/**
|
||||
* 二维码类型
|
||||
*
|
||||
* @see com.foxinmy.weixin4j.type.QRType
|
||||
*/
|
||||
private QRType qrType;
|
||||
/**
|
||||
* 场景值I 根据qrType参数而定
|
||||
*/
|
||||
private String sceneValue;
|
||||
|
||||
private QRParameter() {
|
||||
}
|
||||
|
||||
public int getExpireSeconds() {
|
||||
return expireSeconds;
|
||||
}
|
||||
|
||||
public QRType getQrType() {
|
||||
return qrType;
|
||||
}
|
||||
|
||||
public String getSceneValue() {
|
||||
return sceneValue;
|
||||
}
|
||||
|
||||
private String content;
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建临时二维码
|
||||
*
|
||||
* @param expireSeconds
|
||||
* 有效时间
|
||||
* @param sceneValue
|
||||
* 二维码的场景值 <font color="red">临时二维码最大值为无符号32位非0整型</font>
|
||||
* @return 二维码参数
|
||||
*/
|
||||
public static QRParameter createTemporary(int expireSeconds, long sceneValue) {
|
||||
QRParameter qr = new QRParameter();
|
||||
qr.qrType = QRType.QR_SCENE;
|
||||
qr.expireSeconds = expireSeconds;
|
||||
qr.sceneValue = Long.toString(sceneValue);
|
||||
qr.content = String.format(
|
||||
"{\"expire_seconds\": %s, \"action_name\": \"%s\", \"action_info\": {\"scene\": {\"scene_id\": %s}}}",
|
||||
expireSeconds, QRType.QR_SCENE.name(), sceneValue);
|
||||
return qr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建临时二维码(默认有效期为30秒)
|
||||
*
|
||||
* @param sceneValue
|
||||
* 二维码的场景值 <font color="red">临时二维码最大值为无符号32位非0整型</font>
|
||||
* @return 二维码参数
|
||||
*/
|
||||
public static QRParameter createTemporary(long sceneValue) {
|
||||
QRParameter qr = new QRParameter();
|
||||
qr.qrType = QRType.QR_SCENE;
|
||||
qr.expireSeconds = DEFAULT_TEMPORARY_EXPIRE_SECONDS;
|
||||
qr.sceneValue = Long.toString(sceneValue);
|
||||
qr.content = String.format(
|
||||
"{\"expire_seconds\": %s, \"action_name\": \"%s\", \"action_info\": {\"scene\": {\"scene_id\": %s}}}",
|
||||
DEFAULT_TEMPORARY_EXPIRE_SECONDS, QRType.QR_SCENE.name(), sceneValue);
|
||||
return qr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建永久二维码(场景值为int)
|
||||
*
|
||||
* @param sceneValue
|
||||
* 场景值 最大值为100000
|
||||
* @return 二维码参数
|
||||
*/
|
||||
public static QRParameter createPermanenceInt(int sceneValue) {
|
||||
QRParameter qr = new QRParameter();
|
||||
qr.qrType = QRType.QR_LIMIT_SCENE;
|
||||
qr.sceneValue = Integer.toString(sceneValue);
|
||||
qr.content = String.format("{\"action_name\": \"%s\", \"action_info\": {\"scene\": {\"scene_id\": %s}}}",
|
||||
QRType.QR_LIMIT_SCENE.name(), sceneValue);
|
||||
return qr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建永久二维码(场景值为string)
|
||||
*
|
||||
* @param sceneValue
|
||||
* 场景值
|
||||
* @return 二维码参数
|
||||
*/
|
||||
public static QRParameter createPermanenceStr(String sceneValue) {
|
||||
QRParameter qr = new QRParameter();
|
||||
qr.qrType = QRType.QR_LIMIT_STR_SCENE;
|
||||
qr.sceneValue = sceneValue;
|
||||
qr.content = String.format("{\"action_name\": \"%s\", \"action_info\": {\"scene\": {\"scene_str\": \"%s\"}}}",
|
||||
QRType.QR_LIMIT_STR_SCENE, sceneValue);
|
||||
return qr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "QRParameter [expireSeconds=" + expireSeconds + ", qrType=" + qrType + ", sceneValue=" + sceneValue
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package com.foxinmy.weixin4j.mp.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
/**
|
||||
* 二维码
|
||||
*
|
||||
* @className QRResult
|
||||
* @author jinyu(foxinmy@gmail.com)
|
||||
* @date 2015年7月29日
|
||||
* @since JDK 1.6
|
||||
* @see
|
||||
*/
|
||||
public class QRResult implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 7730781702153258151L;
|
||||
|
||||
private String ticket;
|
||||
private String url;
|
||||
@JSONField(name = "expire_seconds")
|
||||
private int expireSeconds;
|
||||
private byte[] content;
|
||||
|
||||
public String getTicket() {
|
||||
return ticket;
|
||||
}
|
||||
|
||||
public void setTicket(String ticket) {
|
||||
this.ticket = ticket;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public int getExpireSeconds() {
|
||||
return expireSeconds;
|
||||
}
|
||||
|
||||
public void setExpireSeconds(int expireSeconds) {
|
||||
this.expireSeconds = expireSeconds;
|
||||
}
|
||||
|
||||
public byte[] getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(byte[] content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "QRResult [ticket=" + ticket + ", url=" + url
|
||||
+ ", expireSeconds=" + expireSeconds + ", content=...]";
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,10 @@ import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.card.CardCoupon;
|
||||
import com.foxinmy.weixin4j.card.CardCoupons;
|
||||
import com.foxinmy.weixin4j.card.CouponBaseInfo;
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.model.card.CardCoupon;
|
||||
import com.foxinmy.weixin4j.model.card.CardCoupons;
|
||||
import com.foxinmy.weixin4j.model.card.CouponBaseInfo;
|
||||
import com.foxinmy.weixin4j.mp.api.CardApi;
|
||||
import com.foxinmy.weixin4j.type.card.CardCodeType;
|
||||
import com.foxinmy.weixin4j.type.card.CardColor;
|
||||
|
||||
@@ -40,7 +40,7 @@ public class MenuTest extends TokenTest {
|
||||
String domain = "http://wx.jdxg.doubimeizhi.com";
|
||||
buttons.add(new Button("立即下单", domain, ButtonType.view));
|
||||
|
||||
buttons.add(new Button("个人中心", domain + "/user", ButtonType.view));
|
||||
//buttons.add(new Button("个人中心", domain + "/user", ButtonType.view));
|
||||
|
||||
Button button = new Button("小哥介绍", domain, ButtonType.view);
|
||||
button.pushSub(new Button("小哥介绍", "http://x.eqxiu.com/s/89oy462U",
|
||||
@@ -52,7 +52,7 @@ public class MenuTest extends TokenTest {
|
||||
ButtonType.view));
|
||||
button.pushSub(new Button("服务流程", "FLOW", ButtonType.click));
|
||||
button.pushSub(new Button("在线客服", "KF", ButtonType.click));
|
||||
buttons.add(button);
|
||||
//buttons.add(button);
|
||||
|
||||
ApiResult result = menuApi.createMenu(buttons);
|
||||
Assert.assertEquals("0", result.getReturnCode());
|
||||
|
||||
@@ -7,9 +7,9 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||
import com.foxinmy.weixin4j.model.qr.QRParameter;
|
||||
import com.foxinmy.weixin4j.model.qr.QRResult;
|
||||
import com.foxinmy.weixin4j.mp.api.QrApi;
|
||||
import com.foxinmy.weixin4j.mp.model.QRParameter;
|
||||
import com.foxinmy.weixin4j.mp.model.QRResult;
|
||||
|
||||
/**
|
||||
* 二维码相关测试
|
||||
@@ -23,27 +23,27 @@ public class QRTest extends TokenTest {
|
||||
private QrApi qrApi;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
public void init() throws WeixinException {
|
||||
qrApi = new QrApi(tokenManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void temp_qr() throws WeixinException, IOException {
|
||||
QRResult result = qrApi.createQR(QRParameter
|
||||
.createTemporary(1200, 1200));
|
||||
QRResult result = qrApi.createQR(QRParameter.createTemporaryQR(1200,
|
||||
1200L));
|
||||
Assert.assertTrue(!result.getTicket().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forever_qr_int() throws WeixinException, IOException {
|
||||
QRResult result = qrApi.createQR(QRParameter.createPermanenceInt(2));
|
||||
QRResult result = qrApi.createQR(QRParameter.createPermanenceQR(2));
|
||||
Assert.assertTrue(!result.getTicket().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forever_qr_str() throws WeixinException, IOException {
|
||||
QRResult result = qrApi.createQR(QRParameter
|
||||
.createPermanenceStr("1200中文"));
|
||||
.createPermanenceQR("1200中文"));
|
||||
Assert.assertTrue(!result.getTicket().isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user