version upgrade to 1.7.4

This commit is contained in:
jinyu 2017-01-09 12:57:34 +08:00
parent e4a77e96df
commit 2777b05005
17 changed files with 132 additions and 201 deletions

View File

@ -775,3 +775,11 @@
* 2016-12-13 * 2016-12-13
+ version upgrade to 1.7.3 + version upgrade to 1.7.3
* 2017-01-09
+ 新增批量发红包接口
+ 新增摇一摇周边接口
+ version upgrade to 1.7.4

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.foxinmy</groupId> <groupId>com.foxinmy</groupId>
<artifactId>weixin4j</artifactId> <artifactId>weixin4j</artifactId>
<version>1.7.4-SNAPSHOT</version> <version>1.7.4</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>weixin4j</name> <name>weixin4j</name>
<url>https://github.com/foxinmy/weixin4j</url> <url>https://github.com/foxinmy/weixin4j</url>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.foxinmy</groupId> <groupId>com.foxinmy</groupId>
<artifactId>weixin4j</artifactId> <artifactId>weixin4j</artifactId>
<version>1.7.4-SNAPSHOT</version> <version>1.7.4</version>
</parent> </parent>
<artifactId>weixin4j-base</artifactId> <artifactId>weixin4j-base</artifactId>
<name>weixin4j-base</name> <name>weixin4j-base</name>

View File

@ -6,7 +6,8 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException; import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@ -56,28 +57,6 @@ public class CashApi extends MchApi {
* *
* @param redpacket * @param redpacket
* 红包信息 * 红包信息
* @param openId
* 接受收红包的用户的openid 必填
* @see #sendRedpacks(Redpacket, String...)
*/
public RedpacketSendResult sendRedpack(Redpacket redpacket, String openId)
throws WeixinException {
try {
return sendRedpacks(redpacket, openId).get(0).get();
} catch (InterruptedException e) {
throw new WeixinException("send redpack error", e);
} catch (ExecutionException e) {
throw new WeixinException("send redpack error", e);
}
}
/**
* 发放红包 企业向微信用户个人发现金红包
*
* @param redpacket
* 红包信息
* @param openIds
* 接受收红包的用户的openid 必填
* @return 发放结果 * @return 发放结果
* @see com.foxinmy.weixin4j.payment.mch.Redpacket * @see com.foxinmy.weixin4j.payment.mch.Redpacket
* @see com.foxinmy.weixin4j.payment.mch.RedpacketSendResult * @see com.foxinmy.weixin4j.payment.mch.RedpacketSendResult
@ -89,8 +68,8 @@ public class CashApi extends MchApi {
* 发放裂变红包接口</a> * 发放裂变红包接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public List<Future<RedpacketSendResult>> sendRedpacks(Redpacket redpacket, public RedpacketSendResult sendRedpack(Redpacket redpacket)
String... openIds) { throws WeixinException {
String appId = redpacket.getAppId(); String appId = redpacket.getAppId();
super.declareMerchant(redpacket); super.declareMerchant(redpacket);
final JSONObject obj = (JSONObject) JSON.toJSON(redpacket); final JSONObject obj = (JSONObject) JSON.toJSON(redpacket);
@ -100,26 +79,39 @@ public class CashApi extends MchApi {
obj.put("wxappid", obj.remove("appid")); obj.put("wxappid", obj.remove("appid"));
final String redpack_uri = redpacket.getTotalNum() > 1 ? getRequestUri("groupredpack_send_uri") final String redpack_uri = redpacket.getTotalNum() > 1 ? getRequestUri("groupredpack_send_uri")
: getRequestUri("redpack_send_uri"); : getRequestUri("redpack_send_uri");
int sendLength = openIds.length; obj.put("sign", weixinSignature.sign(obj));
String param = XmlStream.map2xml(obj);
WeixinResponse response = getWeixinSSLExecutor().post(redpack_uri,
param);
String text = response.getAsString()
.replaceFirst("<wxappid>", "<appid>")
.replaceFirst("</wxappid>", "</appid>");
return XmlStream.fromXML(text, RedpacketSendResult.class);
}
/**
* 批量发放红包 企业向微信用户个人发现金红包
*
* @param redpacket
* 多个红包信息
* @return 发放结果
* @see #sendRedpacks(Redpacket...)
* @throws WeixinException
*/
public List<Future<RedpacketSendResult>> sendRedpacks(
Redpacket... redpackets) {
ExecutorService sendExecutor = Executors.newFixedThreadPool(Math.max(1, ExecutorService sendExecutor = Executors.newFixedThreadPool(Math.max(1,
sendLength / 10)); // 十分之一? redpackets.length / 10)); // 十分之一?
CompletionService<RedpacketSendResult> completion = new ExecutorCompletionService<RedpacketSendResult>(
sendExecutor);
List<Future<RedpacketSendResult>> callSendList = new ArrayList<Future<RedpacketSendResult>>( List<Future<RedpacketSendResult>> callSendList = new ArrayList<Future<RedpacketSendResult>>(
sendLength); redpackets.length);
for (final String openId : openIds) { for (final Redpacket redpacket : redpackets) {
Future<RedpacketSendResult> futureSend = sendExecutor Future<RedpacketSendResult> futureSend = completion
.submit(new Callable<RedpacketSendResult>() { .submit(new Callable<RedpacketSendResult>() {
@Override @Override
public RedpacketSendResult call() throws Exception { public RedpacketSendResult call() throws Exception {
obj.put("re_openid", openId); return sendRedpack(redpacket);
obj.put("sign", weixinSignature.sign(obj));
String param = XmlStream.map2xml(obj);
WeixinResponse response = getWeixinSSLExecutor()
.post(redpack_uri, param);
String text = response.getAsString()
.replaceFirst("<wxappid>", "<appid>")
.replaceFirst("</wxappid>", "</appid>");
return XmlStream.fromXML(text,
RedpacketSendResult.class);
} }
}); });
callSendList.add(futureSend); callSendList.add(futureSend);

View File

@ -681,24 +681,6 @@ public class WeixinPayProxy {
* *
* @param redpacket * @param redpacket
* 红包信息 * 红包信息
* @param openId
* 接受收红包的用户的openid 必填
* @see com.foxinmy.weixin4j.api.CashApi
* @throws WeixinException
* @see #sendRedpacks(Redpacket, String...)
*/
public RedpacketSendResult sendRedpack(Redpacket redpacket, String openId)
throws WeixinException {
return cashApi.sendRedpack(redpacket, openId);
}
/**
* 发放红包 企业向微信用户个人发现金红包
*
* @param redpacket
* 红包信息
* @param openIds
* 接受收红包的用户的openid 必填
* @return 发放结果 * @return 发放结果
* @see com.foxinmy.weixin4j.api.CashApi * @see com.foxinmy.weixin4j.api.CashApi
* @see com.foxinmy.weixin4j.payment.mch.Redpacket * @see com.foxinmy.weixin4j.payment.mch.Redpacket
@ -711,9 +693,24 @@ public class WeixinPayProxy {
* 发放裂变红包接口</a> * 发放裂变红包接口</a>
* @throws WeixinException * @throws WeixinException
*/ */
public List<Future<RedpacketSendResult>> sendRedpacks(Redpacket redpacket, public RedpacketSendResult sendRedpack(Redpacket redpacket)
String... openIds) { throws WeixinException {
return cashApi.sendRedpacks(redpacket, openIds); return cashApi.sendRedpack(redpacket);
}
/**
* 批量发放红包 企业向微信用户个人发现金红包
*
* @param redpacket
* 多个红包信息
* @return 发放结果
* @see com.foxinmy.weixin4j.api.CashApi
* @see #sendRedpacks(Redpacket...)
* @throws WeixinException
*/
public List<Future<RedpacketSendResult>> sendRedpacks(
Redpacket... redpackets) {
return cashApi.sendRedpacks(redpackets);
} }
/** /**
@ -882,5 +879,5 @@ public class WeixinPayProxy {
return customsApi.queryCustomsOrder(idQuery, customsCity); return customsApi.queryCustomsOrder(idQuery, customsCity);
} }
public final static String VERSION = "1.7.3"; public final static String VERSION = "1.7.4";
} }

View File

@ -36,7 +36,7 @@ public class APPPayRequest extends AbstractPayRequest {
public PayRequest toRequestObject() { public PayRequest toRequestObject() {
PayRequest payRequest = new PayRequest(getPaymentAccount().getId(), PayRequest payRequest = new PayRequest(getPaymentAccount().getId(),
"Sign=WXPay"); "Sign=WXPay");
payRequest.setPartnerId(getPaymentAccount().getPartnerId()); payRequest.setPartnerId(getPaymentAccount().getMchId());
payRequest.setPrepayId(getPrePayId()); payRequest.setPrepayId(getPrePayId());
String sign = DigestUtil.MD5( String sign = DigestUtil.MD5(
String.format("%s&key=%s", String.format("%s&key=%s",
@ -55,7 +55,7 @@ public class APPPayRequest extends AbstractPayRequest {
content.append(String.format("<appid><![CDATA[%s]]></appid>", content.append(String.format("<appid><![CDATA[%s]]></appid>",
payRequest.getAppId())); payRequest.getAppId()));
content.append(String.format("<partnerid><![CDATA[%s]]></partnerid>", content.append(String.format("<partnerid><![CDATA[%s]]></partnerid>",
getPaymentAccount().getMchId())); getPaymentAccount().getPartnerId()));
content.append(String.format("<prepayid><![CDATA[%s]]></prepayid>", content.append(String.format("<prepayid><![CDATA[%s]]></prepayid>",
payRequest.getPrepayId())); payRequest.getPrepayId()));
content.append(String.format("<package><![CDATA[%s]]></package>", content.append(String.format("<package><![CDATA[%s]]></package>",

View File

@ -33,6 +33,12 @@ public class Redpacket extends MerchantResult {
@XmlElement(name = "mch_billno") @XmlElement(name = "mch_billno")
@JSONField(name = "mch_billno") @JSONField(name = "mch_billno")
private String outTradeNo; private String outTradeNo;
/**
* 接受收红包的用户的openid 必填
*/
@XmlElement(name = "re_openid")
@JSONField(name = "re_openid")
private String openId;
/** /**
* 红包发送者名称 必填 * 红包发送者名称 必填
*/ */
@ -113,6 +119,8 @@ public class Redpacket extends MerchantResult {
* *
* @param outTradeNo * @param outTradeNo
* 商户侧一天内不可重复的订单号 接口根据商户订单号支持重入 如出现超时可再调用 必填 * 商户侧一天内不可重复的订单号 接口根据商户订单号支持重入 如出现超时可再调用 必填
* @param openId
* 接受收红包的用户的openid 必填
* @param sendName * @param sendName
* 红包发送者名称 必填 * 红包发送者名称 必填
* @param totalAmount * @param totalAmount
@ -128,24 +136,48 @@ public class Redpacket extends MerchantResult {
* @param remark * @param remark
* 备注 必填 * 备注 必填
*/ */
public Redpacket(String outTradeNo, String sendName, double totalAmount, public Redpacket(String outTradeNo, String openId, String sendName,
int totalNum, String wishing, String clientIp, String actName, double totalAmount, int totalNum, String wishing, String clientIp,
String remark) { String actName, String remark) {
this.outTradeNo = outTradeNo; this.outTradeNo = outTradeNo;
this.openId = openId;
this.sendName = sendName; this.sendName = sendName;
this.totalAmount = DateUtil.formatYuan2Fen(totalAmount);
this.totalNum = totalNum; this.totalNum = totalNum;
this.wishing = wishing; this.wishing = wishing;
this.clientIp = clientIp; this.clientIp = clientIp;
this.actName = actName; this.actName = actName;
this.remark = remark; this.remark = remark;
this.totalAmount = DateUtil.formatYuan2Fen(totalAmount);
this.amtType = totalNum > 1 ? "ALL_RAND" : null; this.amtType = totalNum > 1 ? "ALL_RAND" : null;
} }
/**
* 批量发送时可能需要
*
* @param outTradeNo
* 订单号
* @param openId
* 用户ID
* @return 红包实体
*/
public Redpacket copy(String outTradeNo, String openId) {
Redpacket readpacket = new Redpacket(outTradeNo, openId, sendName,
totalAmount, totalNum, wishing, clientIp, actName, remark);
readpacket.setMsgAppId(msgAppId);
readpacket.setConsumeMchId(consumeMchId);
readpacket.setSceneType(sceneType);
readpacket.setRisk(risk);
return readpacket;
}
public String getOutTradeNo() { public String getOutTradeNo() {
return outTradeNo; return outTradeNo;
} }
public String getOpenId() {
return openId;
}
public String getSendName() { public String getSendName() {
return sendName; return sendName;
} }
@ -226,12 +258,12 @@ public class Redpacket extends MerchantResult {
@Override @Override
public String toString() { public String toString() {
return "Redpacket [outTradeNo=" + outTradeNo + ", sendName=" + sendName return "Redpacket [outTradeNo=" + outTradeNo + ", openId=" + openId
+ ", totalAmount=" + totalAmount + ", totalNum=" + totalNum + ", sendName=" + sendName + ", totalAmount=" + totalAmount
+ ", amtType=" + amtType + ", wishing=" + wishing + ", totalNum=" + totalNum + ", amtType=" + amtType
+ ", clientIp=" + clientIp + ", actName=" + actName + ", wishing=" + wishing + ", clientIp=" + clientIp
+ ", remark=" + remark + ", msgAppId=" + msgAppId + ", actName=" + actName + ", remark=" + remark + ", msgAppId="
+ ", consumeMchId=" + consumeMchId + ", sceneType=" + sceneType + msgAppId + ", consumeMchId=" + consumeMchId + ", sceneType="
+ ", risk=" + risk + ", " + super.toString() + "]"; + sceneType + ", risk=" + risk + ", " + super.toString() + "]";
} }
} }

View File

@ -1,112 +0,0 @@
package com.foxinmy.weixin4j.util;
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 接口调用错误获取
*
* @author fengyapeng
* @className WeixinErrorUtil2
* @date
* @see
* @since JDK 1.6
*/
public final class WeixinErrorUtil2 {
private static byte[] errorXmlByteArray;
private final static Map<String, String> errorCacheMap;
static {
errorCacheMap = new ConcurrentHashMap<String, String>();
try {
errorXmlByteArray = IOUtil.toByteArray(WeixinResponse.class.getResourceAsStream("error.xml"));
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
ContentHandler textHandler = new ErrorTextHandler(errorCacheMap);
xmlReader.setContentHandler(textHandler);
xmlReader.parse(new InputSource(new ByteArrayInputStream(errorXmlByteArray)));
} catch (IOException e) {
;
} catch (SAXException e) {
}
}
private static class ErrorTextHandler extends DefaultHandler {
private Map<String, String> errorCacheMap;
public ErrorTextHandler(Map<String, String> errorCacheMap) {
this.errorCacheMap = errorCacheMap;
}
private String code;
private String text;
private boolean codeElement;
private boolean textElement;
private int isPair = 0;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
codeElement = qName.equalsIgnoreCase("code");
textElement = qName.equalsIgnoreCase("text");
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String _text = new String(ch, start, length);
if (codeElement) {
isPair++;
code = _text;
codeElement = false;
}
if (textElement) {
isPair++;
text = _text;
textElement = false;
}
if (isPair == 2) {
// 配对成功
errorCacheMap.put(code, text);
isPair = 0;
code = null;
text = null;
}
}
}
public static String getText(String code) throws RuntimeException {
return errorCacheMap.get(code);
}
public static String getText(String code, String defaultMsg) throws RuntimeException {
String text = getText(code);
if (StringUtil.isNotBlank(text)) {
return text;
}
return defaultMsg;
}
public static void main(String[] args) {
System.out.println(getText("40001"));
System.out.println(getText("30002"));
System.out.println(getText("1234"));
}
}

View File

@ -26,10 +26,10 @@ public class CashTest extends PayTest {
@Test @Test
public void sendRedpacket() throws WeixinException { public void sendRedpacket() throws WeixinException {
Redpacket redpacket = new Redpacket("HB001", "无忧钱庄", 1d, 1, "红包测试", Redpacket redpacket = new Redpacket("HB001",
"oyFLst1bqtuTcxK-ojF8hOGtLQao", "无忧钱庄", 1d, 1, "红包测试",
"127.0.0.1", "快来领取红包吧!", "来就送钱"); "127.0.0.1", "快来领取红包吧!", "来就送钱");
RedpacketSendResult result = PAY.sendRedpack(redpacket, RedpacketSendResult result = PAY.sendRedpack(redpacket);
"oyFLst1bqtuTcxK-ojF8hOGtLQao");
Assert.assertEquals(Consts.SUCCESS, result.getReturnCode()); Assert.assertEquals(Consts.SUCCESS, result.getReturnCode());
Assert.assertEquals(Consts.SUCCESS, result.getResultCode()); Assert.assertEquals(Consts.SUCCESS, result.getResultCode());
System.err.println(result); System.err.println(result);

View File

@ -261,3 +261,9 @@
* 2016-12-13 * 2016-12-13
+ version upgrade to 1.7.3 + version upgrade to 1.7.3
* 2017-01-09
+ 新增批量发红包接口
+ version upgrade to 1.7.4

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.foxinmy</groupId> <groupId>com.foxinmy</groupId>
<artifactId>weixin4j</artifactId> <artifactId>weixin4j</artifactId>
<version>1.7.4-SNAPSHOT</version> <version>1.7.4</version>
</parent> </parent>
<artifactId>weixin4j-mp</artifactId> <artifactId>weixin4j-mp</artifactId>
<name>weixin4j-mp</name> <name>weixin4j-mp</name>

View File

@ -225,5 +225,5 @@ public class WeixinComponentProxy {
authAppId), component(componentId).getTokenManager()); authAppId), component(componentId).getTokenManager());
} }
public final static String VERSION = "1.7.3"; public final static String VERSION = "1.7.4";
} }

View File

@ -2063,5 +2063,5 @@ public class WeixinProxy {
return cardApi.createCardQR(expireSeconds, cardQRs); return cardApi.createCardQR(expireSeconds, cardQRs);
} }
public final static String VERSION = "1.7.3"; public final static String VERSION = "1.7.4";
} }

View File

@ -200,3 +200,11 @@
* 2016-12-13 * 2016-12-13
+ version upgrade to 1.7.3 + version upgrade to 1.7.3
* 2017-01-09
+ 新增批量发红包接口
+ 新增摇一摇周边接口
+ version upgrade to 1.7.4

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.foxinmy</groupId> <groupId>com.foxinmy</groupId>
<artifactId>weixin4j</artifactId> <artifactId>weixin4j</artifactId>
<version>1.7.4-SNAPSHOT</version> <version>1.7.4</version>
</parent> </parent>
<artifactId>weixin4j-qy</artifactId> <artifactId>weixin4j-qy</artifactId>
<name>weixin4j-qy</name> <name>weixin4j-qy</name>

View File

@ -1433,5 +1433,5 @@ public class WeixinProxy {
return chatApi.sendChatMessage(message); return chatApi.sendChatMessage(message);
} }
public final static String VERSION = "1.7.3"; public final static String VERSION = "1.7.4";
} }

View File

@ -285,5 +285,5 @@ public class WeixinSuiteProxy {
suite(suiteId).getTokenManager()); suite(suiteId).getTokenManager());
} }
public final static String VERSION = "1.7.3"; public final static String VERSION = "1.7.4";
} }