From 24c5076f0b419ca852c69feb1d62e8826c066b49 Mon Sep 17 00:00:00 2001 From: fengyapeng Date: Tue, 20 Dec 2016 10:34:52 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BC=9A=E5=91=98=E5=8D=A1?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=91=87=E4=B8=80=E6=91=87=E9=83=A8?= =?UTF-8?q?=E5=88=86=E8=AE=BE=E5=A4=87=E6=8E=A5=E5=8F=A3=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin4j/model/card/MemCardBonusRule.java | 118 ++++++ .../model/card/MemCardCustomField.java | 73 ++++ .../weixin4j/model/card/MemberCard.java | 384 ++++++++++++++++++ .../weixin4j/type/card/CardStatus.java | 36 ++ .../foxinmy/weixin4j/type/card/CardType.java | 7 +- .../weixin4j/type/card/FieldNameType.java | 42 ++ .../weixin4j/util/WeixinErrorUtil2.java | 112 +++++ .../weixin4j/mp/api/ShakeAroundApi.java | 275 +++++++++++++ .../foxinmy/weixin4j/mp/api/weixin.properties | 209 +++++----- .../weixin4j/mp/model/shakearound/Device.java | 158 +++++++ .../model/shakearound/DeviceAuditState.java | 84 ++++ .../mp/model/shakearound/ShakeUserInfo.java | 58 +++ .../foxinmy/weixin4j/mp/test/HelpTest.java | 35 ++ 13 files changed, 1491 insertions(+), 100 deletions(-) create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/MemCardBonusRule.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/MemCardCustomField.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/MemberCard.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/CardStatus.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/FieldNameType.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/WeixinErrorUtil2.java create mode 100644 weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/ShakeAroundApi.java create mode 100644 weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/shakearound/Device.java create mode 100644 weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/shakearound/DeviceAuditState.java create mode 100644 weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/shakearound/ShakeUserInfo.java create mode 100644 weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/HelpTest.java diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/MemCardBonusRule.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/MemCardBonusRule.java new file mode 100644 index 00000000..7e13b99a --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/MemCardBonusRule.java @@ -0,0 +1,118 @@ +package com.foxinmy.weixin4j.model.card; + +import com.alibaba.fastjson.annotation.JSONField; + +/** + * 会员卡积分规则 + * + * @auther: Feng Yapeng + * @since: 2016/12/15 11:43 + */ +public class MemCardBonusRule { + + /** + * 消费金额。以分为单位。 + */ + @JSONField(name = "cost_money_unit") + private int costMoneyUnit; + /** + * 对应增加的积分 + */ + @JSONField(name = "increase_bonus") + private int increaseBonus; + /** + * 用户单次可获取的积分上限。 + */ + @JSONField(name = "max_increase_bonus ") + private int maxIncreaseBonus; + /** + * 初始设置积分【可以理解为开卡积分】 + */ + @JSONField(name = "init_increase_bonus") + private int initIncreaseBonus; + /** + *每使用N 积分 + */ + @JSONField(name = "cost_bonus_unit") + private int costBonusUnit; + /** + * 抵扣多少分 + */ + @JSONField(name = "reduce_money") + private int reduceMoney; + /** + * 抵扣条件,满xx分(这里以分为单位)可用 + */ + @JSONField(name = "least_money_to_use_bonus") + private int leastMoneyToUseBonus; + /** + * + */ + @JSONField(name = "max_reduce_bonus") + private int maxReduceBonus; + + + public int getCostMoneyUnit() { + return costMoneyUnit; + } + + public void setCostMoneyUnit(int costMoneyUnit) { + this.costMoneyUnit = costMoneyUnit; + } + + public int getIncreaseBonus() { + return increaseBonus; + } + + public void setIncreaseBonus(int increaseBonus) { + this.increaseBonus = increaseBonus; + } + + public int getMaxIncreaseBonus() { + return maxIncreaseBonus; + } + + public void setMaxIncreaseBonus(int maxIncreaseBonus) { + this.maxIncreaseBonus = maxIncreaseBonus; + } + + public int getInitIncreaseBonus() { + return initIncreaseBonus; + } + + public void setInitIncreaseBonus(int initIncreaseBonus) { + this.initIncreaseBonus = initIncreaseBonus; + } + + public int getCostBonusUnit() { + return costBonusUnit; + } + + public void setCostBonusUnit(int costBonusUnit) { + this.costBonusUnit = costBonusUnit; + } + + public int getReduceMoney() { + return reduceMoney; + } + + public void setReduceMoney(int reduceMoney) { + this.reduceMoney = reduceMoney; + } + + public int getLeastMoneyToUseBonus() { + return leastMoneyToUseBonus; + } + + public void setLeastMoneyToUseBonus(int leastMoneyToUseBonus) { + this.leastMoneyToUseBonus = leastMoneyToUseBonus; + } + + public int getMaxReduceBonus() { + return maxReduceBonus; + } + + public void setMaxReduceBonus(int maxReduceBonus) { + this.maxReduceBonus = maxReduceBonus; + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/MemCardCustomField.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/MemCardCustomField.java new file mode 100644 index 00000000..0e8388e0 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/MemCardCustomField.java @@ -0,0 +1,73 @@ +package com.foxinmy.weixin4j.model.card; + +import com.alibaba.fastjson.annotation.JSONField; +import com.foxinmy.weixin4j.type.card.FieldNameType; + +/** + * 会员卡自定义类型 + * + * @auther: Feng Yapeng + * @since: 2016/12/15 10:49 + */ +public class MemCardCustomField { + + /** + *会员信息类目半自定义名称,当开发者变更这类类目信息的value值时,可以选择触发系统模板消息通知用户。 + */ + @JSONField(name = "name_type") + private FieldNameType nameType; + + /** + * 会员信息类目自定义名称,当开发者变更这类类目信息的value值时, 不会触发系统模板消息通知用户 + */ + private String name; + /** + * 点击类目跳转外链url + */ + private String url; + /** + * s + */ + private String tips; + + public MemCardCustomField(FieldNameType fieldNameType, String url) { + this.nameType = fieldNameType; + this.url = url; + } + + public MemCardCustomField(FieldNameType fieldNameType, String name, String url) { + this.nameType = fieldNameType; + this.name = name; + this.url = url; + } + + public MemCardCustomField(String name, String url, String tips) { + this.name = name; + this.url = url; + this.tips = tips; + } + + public FieldNameType getNameType() { + return nameType; + } + + public void setNameType(FieldNameType nameType) { + this.nameType = nameType; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/MemberCard.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/MemberCard.java new file mode 100644 index 00000000..2cb211fb --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/card/MemberCard.java @@ -0,0 +1,384 @@ +package com.foxinmy.weixin4j.model.card; + +import com.alibaba.fastjson.annotation.JSONField; +import com.foxinmy.weixin4j.type.card.CardType; +import com.foxinmy.weixin4j.type.card.FieldNameType; + +/** + * 会员卡 + * @auther: Feng Yapeng + * @since: 2016/12/15 10:09 + */ +public class MemberCard extends CardCoupon { + + /** + * 会员卡背景图 [商家自定义会员卡背景图,须先调用上传图片接口将背景图上传至CDN,否则报错, + * 卡面设计请遵循微信会员卡自定义背景设计规范 ,像素大小控制在1000像素*600像素以下] + */ + @JSONField(name = "background_pic_url") + private String backgroundPicUrl; + + /** + * 会员卡特权说明。 + */ + @JSONField(name = "prerogative") + private String prerogative; + /** + * 用户领取会员卡后系统自动将其激活,无需调用激活接口,详情见自动激活。 + */ + @JSONField(name = "auto_activate") + private boolean autoActivate; + /** + * 设置为true时会员卡支持一键开卡,不允许同时传入activate_url字段,否则设置wx_activate失效。 + */ + @JSONField(name = "wx_activate") + private boolean wxActivate; + /** + * 激活会员卡的url。 + */ + @JSONField(name = "activate_url") + private String activateUrl; + + /** + * 显示积分 【true:积分相关字段均为必填】 + */ + @JSONField(name = "supply_bonus") + private boolean supplyBonus; + /** + * 设置跳转外链查看积分详情。仅适用于积分无法通过激活接口同步的情况下使用该字段 + */ + @JSONField(name = "bonus_url") + private String bonusUrl; + /** + * 显示余额 + */ + @JSONField(name = "supply_balance") + private String supplyBalance; + /** + * 设置跳转外链查看余额详情。仅适用于余额无法通过激活接口同步的情况下使用该字段。 + */ + @JSONField(name = "balance_url") + private String balanceUrl; + + /** + * 自定义会员信息类目 + */ + @JSONField(name = "custom_field1") + private MemCardCustomField customField1; + /** + * 自定义会员信息类目 + */ + @JSONField(name = "custom_field2") + private MemCardCustomField customField2; + /** + * 自定义会员信息类目 + */ + @JSONField(name = "custom_field3") + private MemCardCustomField customField3; + + /** + * 积分规则说明 + */ + @JSONField(name = "bonus_rules") + private String bonusRules; + /** + * 储值说明。 + */ + @JSONField(name = "balance_rules") + private String balanceRules; + /** + * 积分清零规则 + */ + @JSONField(name = "bonus_cleared") + private String bonusCleared; + /** + * 自定义会员信息类目,会员卡激活后显示 + */ + @JSONField(name = "custom_cell1") + private MemCardCustomField customCell1; + + /** + * 折扣【该会员卡享受的折扣优惠,填10就是九折。】 + */ + private int discount; + + @JSONField(name = "bonus_rule") + private MemCardBonusRule bonusRule; + + + /** + * 卡券 + * + * @param couponBaseInfo 基础信息 + */ + protected MemberCard(CouponBaseInfo couponBaseInfo, Builder builder) { + super(couponBaseInfo); + this.activateUrl = builder.activateUrl; + this.backgroundPicUrl = builder.backgroundPicUrl; + this.prerogative = builder.prerogative; + this.autoActivate = builder.autoActivate; + this.wxActivate = builder.wxActivate; + this.activateUrl = builder.activateUrl; + this.supplyBonus = builder.supplyBonus; + this.bonusUrl = builder.bonusUrl; + this.supplyBalance = builder.supplyBalance; + this.balanceUrl = builder.balanceUrl; + this.customField1 = builder.customField1; + this.customField2 = builder.customField2; + this.customField3 = builder.customField3; + this.bonusRules = builder.bonusRules; + this.balanceRules = builder.balanceRules; + this.bonusCleared = builder.bonusCleared; + this.customCell1 = builder.customCell1; + this.discount = builder.discount; + this.bonusRule = builder.bonusRule; + } + + @Override + public CardType getCardType() { + return CardType.MEMBER_CARD; + } + + public String getBackgroundPicUrl() { + return backgroundPicUrl; + } + + public String getPrerogative() { + return prerogative; + } + + public boolean isAutoActivate() { + return autoActivate; + } + + public boolean isWxActivate() { + return wxActivate; + } + + public String getActivateUrl() { + return activateUrl; + } + + public boolean isSupplyBonus() { + return supplyBonus; + } + + public String getBonusUrl() { + return bonusUrl; + } + + public String getSupplyBalance() { + return supplyBalance; + } + + public String getBalanceUrl() { + return balanceUrl; + } + + public MemCardCustomField getCustomField1() { + return customField1; + } + + public MemCardCustomField getCustomField2() { + return customField2; + } + + public MemCardCustomField getCustomField3() { + return customField3; + } + + public String getBonusRules() { + return bonusRules; + } + + public String getBalanceRules() { + return balanceRules; + } + + public String getBonusCleared() { + return bonusCleared; + } + + public MemCardCustomField getCustomCell1() { + return customCell1; + } + + public int getDiscount() { + return discount; + } + + public MemCardBonusRule getBonusRule() { + return bonusRule; + } + + + public static final class Builder { + + /** + * 会员卡背景图 [商家自定义会员卡背景图,须先调用上传图片接口将背景图上传至CDN,否则报错, + * 卡面设计请遵循微信会员卡自定义背景设计规范 ,像素大小控制在1000像素*600像素以下] + */ + private String backgroundPicUrl; + + /** + * 会员卡特权说明。 + */ + private String prerogative; + /** + * 用户领取会员卡后系统自动将其激活,无需调用激活接口,详情见自动激活。 + */ + private boolean autoActivate; + /** + * 设置为true时会员卡支持一键开卡,不允许同时传入activate_url字段,否则设置wx_activate失效。 + */ + private boolean wxActivate; + /** + * 激活会员卡的url。 + */ + private String activateUrl; + + /** + * 显示积分 【true:积分相关字段均为必填】 + */ + private boolean supplyBonus; + /** + * 设置跳转外链查看积分详情。仅适用于积分无法通过激活接口同步的情况下使用该字段 + */ + private String bonusUrl; + /** + * 显示余额 + */ + private String supplyBalance; + /** + * 设置跳转外链查看余额详情。仅适用于余额无法通过激活接口同步的情况下使用该字段。 + */ + private String balanceUrl; + /** + * 自定义会员信息类目 + */ + private MemCardCustomField customField1; + /** + * 自定义会员信息类目 + */ + private MemCardCustomField customField2; + /** + * 自定义会员信息类目 + */ + private MemCardCustomField customField3; + /** + * 积分规则说明 + */ + private String bonusRules; + /** + * 储值说明。 + */ + private String balanceRules; + /** + * 积分清零规则 + */ + private String bonusCleared; + /** + * 自定义会员信息类目,会员卡激活后显示 + */ + private MemCardCustomField customCell1; + /** + * 折扣【该会员卡享受的折扣优惠,填10就是九折。】 + */ + private int discount; + /** + * 积分规则 + */ + private MemCardBonusRule bonusRule; + + + public Builder setBackgroundPicUrl(String backgroundPicUrl) { + this.backgroundPicUrl = backgroundPicUrl; + return this; + } + + public Builder setPrerogative(String prerogative) { + this.prerogative = prerogative; + return this; + } + + public Builder setAutoActivate(boolean autoActivate) { + this.autoActivate = autoActivate; + return this; + } + + public Builder setWxActivate(boolean wxActivate) { + this.wxActivate = wxActivate; + return this; + } + + public Builder setActivateUrl(String activateUrl) { + this.activateUrl = activateUrl; + return this; + } + + public Builder setSupplyBonus(boolean supplyBonus) { + this.supplyBonus = supplyBonus; + return this; + } + + public Builder setBonusUrl(String bonusUrl) { + this.bonusUrl = bonusUrl; + return this; + } + + public Builder setSupplyBalance(String supplyBalance) { + this.supplyBalance = supplyBalance; + return this; + } + + public Builder setBalanceUrl(String balanceUrl) { + this.balanceUrl = balanceUrl; + return this; + } + + public Builder setCustomField1(FieldNameType type, String name, String url) { + this.customField1 = new MemCardCustomField(type, name, url); + return this; + } + + public Builder setCustomField2(FieldNameType type, String name, String url) { + this.customField2 = new MemCardCustomField(type, name, url); + return this; + } + + public Builder setCustomField3(FieldNameType type, String name, String url) { + this.customField3 = new MemCardCustomField(type, name, url); + return this; + } + + public Builder setBonusRules(String bonusRules) { + this.bonusRules = bonusRules; + return this; + } + + public Builder setBalanceRules(String balanceRules) { + this.balanceRules = balanceRules; + return this; + } + + public Builder setBonusCleared(String bonusCleared) { + this.bonusCleared = bonusCleared; + return this; + } + + public Builder setCustomCell1(String name, String url, String tips) { + this.customCell1 = new MemCardCustomField(name, url, tips); + return this; + } + + public Builder setDiscount(int discount) { + this.discount = discount; + return this; + } + + public Builder setBonusRule(MemCardBonusRule bonusRule) { + this.bonusRule = bonusRule; + return this; + } + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/CardStatus.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/CardStatus.java new file mode 100644 index 00000000..1e48bdca --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/CardStatus.java @@ -0,0 +1,36 @@ +package com.foxinmy.weixin4j.type.card; + +/** + * 会员卡的状态 + * + * @auther: Feng Yapeng + * @since: 2016/12/19 11:39 + */ +public enum CardStatus { + + /** + * 待审核; + */ + CARD_STATUS_NOT_VERIFY, + + /** + * 审核失败 + */ + CARD_STATUS_VERIFY_FAIL, + + /** + * 通过审核 + */ + CARD_STATUS_VERIFY_OK, + + /** + * 卡券被商户删除 + */ + CARD_STATUS_DELETE, + + /** + * 在公众平台投放过的卡券 + */ + CARD_STATUS_DISPATCH; + +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/CardType.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/CardType.java index a32c2c11..f9354e7f 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/CardType.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/CardType.java @@ -29,5 +29,10 @@ public enum CardType { /** * 优惠券 */ - GENERAL_COUPON; + GENERAL_COUPON, + + /** + * 会员卡 + */ + MEMBER_CARD; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/FieldNameType.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/FieldNameType.java new file mode 100644 index 00000000..b1c11743 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/card/FieldNameType.java @@ -0,0 +1,42 @@ +package com.foxinmy.weixin4j.type.card; + +/** + * 会员信息类目半自定义名称 + * + * @auther: Feng Yapeng + * @since: 2016/12/15 10:37 + */ +public enum FieldNameType { + /** + * 等级 + */ + FIELD_NAME_TYPE_LEVEL, + /** + * 优惠券 + */ + FIELD_NAME_TYPE_COUPON, + /** + * 印花 + */ + FIELD_NAME_TYPE_STAMP, + /** + * 折扣 + */ + FIELD_NAME_TYPE_DISCOUNT, + /** + * 成就 + */ + FIELD_NAME_TYPE_ACHIEVEMEN, + /** + * 里程 + */ + FIELD_NAME_TYPE_MILEAGE, + /** + * 集点 + */ + FIELD_NAME_TYPE_SET_POINTS, + /** + * 次数 + */ + FIELD_NAME_TYPE_TIMS; +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/WeixinErrorUtil2.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/WeixinErrorUtil2.java new file mode 100644 index 00000000..3f0634ba --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/WeixinErrorUtil2.java @@ -0,0 +1,112 @@ +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 errorCacheMap; + + static { + errorCacheMap = new ConcurrentHashMap(); + 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 errorCacheMap; + + public ErrorTextHandler(Map 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")); + } +} diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/ShakeAroundApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/ShakeAroundApi.java new file mode 100644 index 00000000..284ad1fe --- /dev/null +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/ShakeAroundApi.java @@ -0,0 +1,275 @@ +package com.foxinmy.weixin4j.mp.api; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +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.paging.Pageable; +import com.foxinmy.weixin4j.model.paging.Pagedata; +import com.foxinmy.weixin4j.mp.model.shakearound.Device; +import com.foxinmy.weixin4j.mp.model.shakearound.DeviceAuditState; +import com.foxinmy.weixin4j.mp.model.shakearound.ShakeUserInfo; +import com.foxinmy.weixin4j.token.TokenManager; +import com.sun.javafx.binding.StringFormatter; + +import java.util.ArrayList; +import java.util.List; + +/** + * 摇一摇周边 + * + * @author fengyapeng + * @auther: Feng Yapeng feng27156@gmail.com + * @since: 2016 /10/12 21:13 + * @since 2016 -10-13 10:49:39 + */ +public class ShakeAroundApi extends MpApi { + + + private final TokenManager tokenManager; + + + /** + * Instantiates a new Shake around api. + * + * @param tokenManager the token manager + */ + public ShakeAroundApi(TokenManager tokenManager) { + this.tokenManager = tokenManager; + } + + /** + * 申请配置设备所需的UUID、Major、Minor。申请成功后返回批次ID,可用返回的批次ID通过“查询设备ID申请状态”接口查询目前申请的审核状态。 + * 若单次申请的设备ID数量小于500个,系统会进行快速审核;若单次申请的设备ID数量大于等 500个 ,会在三个工作日内完成审核。 + * 如果已审核通过,可用返回的批次ID通过“查询设备列表”接口拉取本次申请的设备ID。 通过接口申请的设备ID,需先配置页面,若未配置页面,则摇不出页面信息。 + * + * @param quantity the quantity 申请的设备ID的数量,单次新增设备超过500个,需走人工审核流程 + * @param applyReason the apply reason 申请理由,不超过100个汉字或200个英文字母 + * @param comment the comment 备注,不超过15个汉字或30个英文字母 + * @return the api result + * @throws WeixinException the weixin exception + * @author fengyapeng + * @see + * @since 2016 -10-12 21:21:47 + */ + public DeviceAuditState deviceApply(Integer quantity, String applyReason, String comment) throws WeixinException { + String device_apply_uri = getRequestUri("shake_around_device_apply"); + Token token = this.tokenManager.getCache(); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("quantity", quantity); + jsonObject.put("apply_reason", applyReason); + jsonObject.put("comment", comment); + WeixinResponse response = weixinExecutor.post(String.format(device_apply_uri, token.getAccessToken()), jsonObject.toJSONString()); + DeviceAuditState result = JSON.parseObject(response.getAsJson().getString("data"), DeviceAuditState.class); + result.setApplyTime(System.currentTimeMillis() / 1000); + result.setAuditTime(0); + return result; + } + + + /** + * 查询设备ID申请的审核状态。若单次申请的设备ID数量小于等于500个, + * 系统会进行快速审核;若单次申请的设备ID数量大于500个,则在三个工作日内完成审核。 + * + * @param applyId the apply id 批次ID,申请设备ID时所返回的批次ID + * @return the device audit state + * @throws WeixinException the weixin exception + * @author fengyapeng + * @see + * @since 2016 -10-12 21:57:04 + */ + public DeviceAuditState deviceQueryApplyStatus(int applyId) throws WeixinException { + String device_apply_status_uri = getRequestUri("shake_around_device_apply_status_uri"); + Token token = this.tokenManager.getCache(); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("apply_id", applyId); + WeixinResponse response = weixinExecutor + .post(String.format(device_apply_status_uri, token.getAccessToken()), jsonObject.toJSONString()); + DeviceAuditState result = JSON.parseObject(response.getAsJson().getString("data"), DeviceAuditState.class); + result.setApplyId(applyId); + return result; + } + + /** + * 查询已有的设备ID、UUID、Major、Minor、激活状态、备注信息、关联门店、关联页面等信息。 + * 查询指定设备的信息 + * + * @param device the device + * @return the list + * @throws WeixinException the weixin exception + * @author fengyapeng + * @since 2016 -10-13 10:11:34 + */ + public List deviceSearchDevices(List device) throws WeixinException { + String device_search_uri = getRequestUri("shake_around_device_search_uri"); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", 1); + jsonObject.put("device_identifiers", device); + WeixinResponse response = weixinExecutor + .post(String.format(device_search_uri, tokenManager.getAccessToken()), jsonObject.toJSONString()); + JSONObject json = response.getAsJson(); + String deviceStr = json.getJSONObject("data").getString("devices"); + return JSON.parseArray(deviceStr, Device.class); + } + + /** + * 查询已有的设备ID、UUID、Major、Minor、激活状态、备注信息、关联门店、关联页面等信息。 + * 按照分页信息查询设备 + * + * @return the list + * @throws WeixinException the weixin exception + * @author fengyapeng + * @since 2016 -10-13 10:11:34 + */ + public Pagedata deviceSearchDevices(int pageSize) throws WeixinException { + return this.deviceSearchDevices(0, pageSize); + } + + /** + * 查询已有的设备ID、UUID、Major、Minor、激活状态、备注信息、关联门店、关联页面等信息 + * 根据上次查询的最后的设备编号按照分页查询 + * + * @param lastDeviceId the last device id + * @param pageSize the page size + * @return list pagedata + * @throws WeixinException the weixin exception + * @author fengyapeng + * @since 2016 -10-13 10:52:20 + */ + public Pagedata deviceSearchDevices(int lastDeviceId, int pageSize) throws WeixinException { + String device_search_uri = getRequestUri("shake_around_device_search_uri"); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", 2); + jsonObject.put("last_seen", lastDeviceId); + if (pageSize > 50) { + pageSize = 50; + } + jsonObject.put("count", pageSize); + WeixinResponse response = weixinExecutor + .post(String.format(device_search_uri, tokenManager.getAccessToken()), jsonObject.toJSONString()); + JSONObject json = response.getAsJson(); + JSONObject data = json.getJSONObject("data"); + String deviceStr = data.getString("devices"); + List devices = JSON.parseArray(deviceStr, Device.class); + Pagedata pagedata = new Pagedata(null, data.getIntValue("total_count"), devices); + return pagedata; + } + + /** + * 查询已有的设备ID、UUID、Major、Minor、激活状态、备注信息、关联门店、关联页面等信息 + * 查询 设备Id 下的所有的设备 + * + * @param applyId the apply id + * @return the list + * @author fengyapeng + * @since 2016 -10-13 10:49:39 + */ + public List deviceSearchDevicesByApplyId(Integer applyId) throws WeixinException { + List devices = new ArrayList(); + Pagedata pagedata = this.deviceSearchDevicesByApplyId(applyId, 50); + devices = pagedata.getContent(); + for (int page = 50; page < pagedata.getTotalElements(); page = page + 50) { + List _devices = pagedata.getContent(); + pagedata = this.deviceSearchDevicesByApplyId(applyId, _devices.get(_devices.size() - 1).getDeviceId(), 50); + _devices = pagedata.getContent(); + devices.addAll(_devices); + } + return devices; + } + + + /** + * 查询已有的设备ID、UUID、Major、Minor、激活状态、备注信息、关联门店、关联页面等信息 + * 分页获取设备id下的前多少设备 + * + * @param applyId the apply id + * @return the list + * @author fengyapeng + * @since 2016 -10-13 10:49:39 + */ + public Pagedata deviceSearchDevicesByApplyId(Integer applyId, int pageSize) throws WeixinException { + return this.deviceSearchDevicesByApplyId(applyId, 0, pageSize); + } + + /** + * 查询已有的设备ID、UUID、Major、Minor、激活状态、备注信息、关联门店、关联页面等信息 + * 分页获取设备id下的根据上次查询的最后的设备编号前多少设备 + * + * @param applyId the apply id + * @return the list + * @author fengyapeng + * @since 2016 -10-13 10:49:39 + */ + public Pagedata deviceSearchDevicesByApplyId(Integer applyId, int lastDeviceId, int pageSize) throws WeixinException { + String device_search_uri = getRequestUri("shake_around_device_search_uri"); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type", 3); + jsonObject.put("apply_id", applyId); + jsonObject.put("last_seen", lastDeviceId); + if (pageSize > 50) { + pageSize = 50; + } + jsonObject.put("count", pageSize); + WeixinResponse response = weixinExecutor + .post(String.format(device_search_uri, tokenManager.getAccessToken()), jsonObject.toJSONString()); + JSONObject json = response.getAsJson(); + JSONObject data = json.getJSONObject("data"); + String deviceStr = data.getString("devices"); + List devices = JSON.parseArray(deviceStr, Device.class); + Pagedata pagedata = new Pagedata(null, data.getIntValue("total_count"), devices); + return pagedata; + } + + + /** + * 编辑设备的备注信息。可用设备ID或完整的UUID、Major、Minor指定设备,二者选其一。 + * + * @param device the device + * @param comment the comment + * @return api result + * @author fengyapeng + * @since 2016 -10-13 14:33:06 + */ + public ApiResult deviceUpdateComment(Device device, String comment) throws WeixinException { + String device_update_uri = getRequestUri("shake_around_device_update_uri"); + JSONObject jsonObject = new JSONObject(); + JSONObject deviceJsonObj = new JSONObject(); + jsonObject.put("device_identifier", deviceJsonObj); + jsonObject.put("comment", comment); + if (device.getDeviceId() == null) { + deviceJsonObj.put("uuid", device.getUuid()); + deviceJsonObj.put("major", device.getMajor()); + deviceJsonObj.put("minor", device.getMinor()); + } else { + deviceJsonObj.put("device_id", device.getDeviceId()); + } + WeixinResponse weixinResponse = weixinExecutor + .post(String.format(device_update_uri, tokenManager.getAccessToken()), jsonObject.toJSONString()); + return weixinResponse.getAsResult(); + + } + + /** + * 获取设备信息,包括UUID、major、minor,以及距离、openID等信息. + * + * + * + * + * @param ticket the ticket 摇周边业务的ticket,可在摇到的URL中得到,ticket生效时间为30分钟,每一次摇都会重新生成新的ticket + * @return shake user info + * @author fengyapeng + * @since 2016 -10-21 19:34:38 + */ + public ShakeUserInfo getShakeUserInfo(String ticket) throws WeixinException { + String user_get_shake_info_url = getRequestUri("shake_around_user_get_shake_info"); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("ticket", ticket); + WeixinResponse weixinResponse = weixinExecutor + .post(String.format(user_get_shake_info_url, tokenManager.getAccessToken()), jsonObject.toJSONString()); + return weixinResponse.getAsJson().getObject("data", ShakeUserInfo.class); + + } +} diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties index 503db113..faf57280 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/weixin.properties @@ -1,4 +1,4 @@ -# \u5fae\u4fe1\u516c\u4f17\u5e73\u53f0\u6587\u6863\u8bf4\u660e +# \u5FAE\u4FE1\u516C\u4F17\u5E73\u53F0\u6587\u6863\u8BF4\u660E # http://mp.weixin.qq.com/wiki/index.php # ---------------------------------------------------------------------------- @@ -9,186 +9,186 @@ tenpay_base_url=http://mch.tenpay.com tenpay_ssl_base_url=https://mch.tenpay.com tenpay_gw_base_url=https://gw.tenpay.com -# \u7f51\u9875oauth\u6388\u6743URL +# \u7F51\u9875oauth\u6388\u6743URL sns_user_auth_uri=https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect -# \u7b2c\u4e09\u65b9\u7ec4\u4ef6\u4ee3\u516c\u4f17\u53f7\u7f51\u9875oauth\u6388\u6743URL +# \u7B2C\u4E09\u65B9\u7EC4\u4EF6\u4EE3\u516C\u4F17\u53F7\u7F51\u9875oauth\u6388\u6743URL sns_component_user_auth_uri=https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&component_appid=%s#wechat_redirect -# \u7f51\u9875oauth\u6388\u6743\u83b7\u53d6token +# \u7F51\u9875oauth\u6388\u6743\u83B7\u53D6token sns_user_token_uri={api_base_url}/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code -# \u7b2c\u4e09\u65b9\u7ec4\u4ef6\u4ee3\u516c\u4f17\u53f7\u7f51\u9875oauth\u6388\u6743\u83b7\u53d6token +# \u7B2C\u4E09\u65B9\u7EC4\u4EF6\u4EE3\u516C\u4F17\u53F7\u7F51\u9875oauth\u6388\u6743\u83B7\u53D6token sns_component_user_token_uri={api_base_url}/sns/oauth2/component/access_token?appid=%s&code=%s&grant_type=authorization_code&component_appid=%s&component_access_token=%s -# \u7f51\u9875oauth\u6388\u6743\u5237\u65b0token +# \u7F51\u9875oauth\u6388\u6743\u5237\u65B0token sns_token_refresh_uri={api_base_url}/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s -# \u7b2c\u4e09\u65b9\u7ec4\u4ef6\u4ee3\u516c\u4f17\u53f7\u7f51\u9875oauth\u6388\u6743\u5237\u65b0token +# \u7B2C\u4E09\u65B9\u7EC4\u4EF6\u4EE3\u516C\u4F17\u53F7\u7F51\u9875oauth\u6388\u6743\u5237\u65B0token sns_component_token_refresh_uri={api_base_url}/sns/oauth2/component/refresh_token?appid=%s&grant_type=refresh_token&component_appid=%s&component_access_token=%s&refresh_token=%s -# \u7f51\u9875oauthoauth\u6388\u6743\u9a8c\u8bc1token +# \u7F51\u9875oauthoauth\u6388\u6743\u9A8C\u8BC1token sns_auth_token_uri={api_base_url}/sns/auth?access_token=%s&openid=%s -# \u7f51\u9875oauth\u6388\u6743\u83b7\u53d6\u7528\u6237\u4fe1\u606f +# \u7F51\u9875oauth\u6388\u6743\u83B7\u53D6\u7528\u6237\u4FE1\u606F sns_user_info_uri={api_base_url}/sns/userinfo?access_token=%s&openid=%s&lang=%s -# \u5f00\u653e\u5e73\u53f0\u626b\u7801\u767b\u9646\u6388\u6743 +# \u5F00\u653E\u5E73\u53F0\u626B\u7801\u767B\u9646\u6388\u6743 open_user_auth_uri=https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect -# \u76f4\u63a5\u83b7\u53d6\u7528\u6237\u4fe1\u606f +# \u76F4\u63A5\u83B7\u53D6\u7528\u6237\u4FE1\u606F api_user_info_uri={api_cgi_url}/user/info?access_token=%s&openid=%s&lang=%s -# \u6279\u91cf\u83b7\u53d6\u7528\u6237\u4fe1\u606f +# \u6279\u91CF\u83B7\u53D6\u7528\u6237\u4FE1\u606F api_users_info_uri={api_cgi_url}/user/info/batchget?access_token=%s -# \u83b7\u53d6token +# \u83B7\u53D6token api_token_uri={api_cgi_url}/token?grant_type=client_credential&appid=%s&secret=%s -# \u83b7\u53d6\u4e8c\u7ef4\u7801 +# \u83B7\u53D6\u4E8C\u7EF4\u7801 qr_ticket_uri={api_cgi_url}/qrcode/create?access_token=%s qr_image_uri={mp_base_url}/showqrcode?ticket=%s -# \u4e0a\u4f20\u5a92\u4f53\u6587\u4ef6 +# \u4E0A\u4F20\u5A92\u4F53\u6587\u4EF6 media_upload_uri={api_cgi_url}/media/upload?access_token=%s&type=%s -# \u4e0a\u4f20\u56fe\u7247 +# \u4E0A\u4F20\u56FE\u7247 image_upload_uri={api_cgi_url}/media/uploadimg?access_token=%s -# \u4e0b\u8f7d\u5a92\u4f53\u6587\u4ef6 +# \u4E0B\u8F7D\u5A92\u4F53\u6587\u4EF6 meida_download_uri={api_cgi_url}/media/get?access_token=%s&media_id=%s -# \u53d1\u9001\u5ba2\u670d\u6d88\u606f +# \u53D1\u9001\u5BA2\u670D\u6D88\u606F custom_notify_uri={api_cgi_url}/message/custom/send?access_token=%s -# \u521b\u5efa\u5206\u7ec4 +# \u521B\u5EFA\u5206\u7EC4 group_create_uri={api_cgi_url}/groups/create?access_token=%s -# \u67e5\u8be2\u5206\u7ec4 +# \u67E5\u8BE2\u5206\u7EC4 group_get_uri={api_cgi_url}/groups/get?access_token=%s -# \u67e5\u8be2\u7528\u6237\u6240\u5728\u5206\u7ec4 +# \u67E5\u8BE2\u7528\u6237\u6240\u5728\u5206\u7EC4 group_getid_uri={api_cgi_url}/groups/getid?access_token=%s -# \u4fee\u6539\u5206\u7ec4\u540d +# \u4FEE\u6539\u5206\u7EC4\u540D group_modify_uri={api_cgi_url}/groups/update?access_token=%s -# \u79fb\u52a8\u7528\u6237\u5206\u7ec4 +# \u79FB\u52A8\u7528\u6237\u5206\u7EC4 group_move_uri={api_cgi_url}/groups/members/update?access_token=%s -# \u6279\u91cf\u79fb\u52a8\u7528\u6237\u5206\u7ec4 +# \u6279\u91CF\u79FB\u52A8\u7528\u6237\u5206\u7EC4 group_batchmove_uri={api_cgi_url}/groups/members/batchupdate?access_token=%s -# \u5220\u9664\u7528\u6237\u5206\u7ec4 +# \u5220\u9664\u7528\u6237\u5206\u7EC4 group_delete_uri={api_cgi_url}/groups/delete?access_token=%s -# \u83b7\u53d6\u5173\u6ce8\u7740 +# \u83B7\u53D6\u5173\u6CE8\u7740 following_uri={api_cgi_url}/user/get?access_token=%s&next_openid=%s -# \u81ea\u5b9a\u4e49\u83dc\u5355 +# \u81EA\u5B9A\u4E49\u83DC\u5355 menu_create_uri={api_cgi_url}/menu/create?access_token=%s -# \u521b\u5efa\u4e2a\u6027\u5316\u83dc\u5355 +# \u521B\u5EFA\u4E2A\u6027\u5316\u83DC\u5355 menu_custom_create_uri={api_cgi_url}/menu/addconditional?access_token=%s -# \u67e5\u8be2\u83dc\u5355 +# \u67E5\u8BE2\u83DC\u5355 menu_get_uri={api_cgi_url}/menu/get?access_token=%s -# \u67e5\u8be2\u901a\u8fc7\u63a5\u53e3\u6216\u8005\u5728\u516c\u4f17\u5e73\u53f0\u4e0a\u8bbe\u7f6e\u7684\u83dc\u5355\u914d\u7f6e\u4fe1\u606f +# \u67E5\u8BE2\u901A\u8FC7\u63A5\u53E3\u6216\u8005\u5728\u516C\u4F17\u5E73\u53F0\u4E0A\u8BBE\u7F6E\u7684\u83DC\u5355\u914D\u7F6E\u4FE1\u606F menu_get_selfmenu_uri={api_cgi_url}/get_current_selfmenu_info?access_token=%s -# \u5220\u9664\u83dc\u5355 +# \u5220\u9664\u83DC\u5355 menu_delete_uri={api_cgi_url}/menu/delete?access_token=%s -# \u5220\u9664\u4e2a\u6027\u5316\u83dc\u5355 +# \u5220\u9664\u4E2A\u6027\u5316\u83DC\u5355 menu_delete_custom_uri={api_cgi_url}/menu/delconditional?access_token=%s -# \u6d4b\u8bd5\u4e2a\u6027\u5316\u83dc\u5355\u5339\u914d\u7ed3\u679c +# \u6D4B\u8BD5\u4E2A\u6027\u5316\u83DC\u5355\u5339\u914D\u7ED3\u679C menu_trymatch_uri={api_cgi_url}/menu/trymatch?access_token=%s -# \u4e0a\u4f20\u56fe\u6587 +# \u4E0A\u4F20\u56FE\u6587 article_upload_uri={api_cgi_url}/media/uploadnews?access_token=%s -# \u4e0a\u4f20\u89c6\u9891 +# \u4E0A\u4F20\u89C6\u9891 video_upload_uri={api_cgi_url}/media/uploadvideo?access_token=%s -# \u5206\u7ec4\u7fa4\u53d1 +# \u5206\u7EC4\u7FA4\u53D1 mass_group_uri={api_cgi_url}/message/mass/sendall?access_token=%s -# openId\u7fa4\u53d1 +# openId\u7FA4\u53D1 mass_openid_uri={api_cgi_url}/message/mass/send?access_token=%s -# \u5220\u9664\u7fa4\u53d1 +# \u5220\u9664\u7FA4\u53D1 mass_delete_uri={api_cgi_url}/message/mass/delete?access_token=%s -# \u7fa4\u53d1\u9884\u89c8 +# \u7FA4\u53D1\u9884\u89C8 mass_preview_uri={api_cgi_url}/message/mass/preview?access_token=%s -# \u67e5\u8be2\u7fa4\u53d1\u72b6\u6001 +# \u67E5\u8BE2\u7FA4\u53D1\u72B6\u6001 mass_get_uri={api_cgi_url}/message/mass/get?access_token=%s -# \u5ba2\u670d\u804a\u5929\u8bb0\u5f55 +# \u5BA2\u670D\u804A\u5929\u8BB0\u5F55 kf_chatrecord_uri={api_base_url}/customservice/msgrecord/getmsglist?access_token=%s -# \u5ba2\u670d\u57fa\u672c\u4fe1\u606f +# \u5BA2\u670D\u57FA\u672C\u4FE1\u606F kf_list_uri={api_cgi_url}/customservice/getkflist?access_token=%s -# \u5728\u7ebf\u5ba2\u670d\u57fa\u672c\u4fe1\u606f +# \u5728\u7EBF\u5BA2\u670D\u57FA\u672C\u4FE1\u606F kf_onlinelist_uri={api_cgi_url}/customservice/getonlinekflist?access_token=%s -# \u65b0\u589e\u591a\u5ba2\u670d\u8d26\u53f7 +# \u65B0\u589E\u591A\u5BA2\u670D\u8D26\u53F7 kf_create_uri={api_base_url}/customservice/kfaccount/add?access_token=%s -# \u9080\u8bf7\u7ed1\u5b9a\u5ba2\u670d\u5e10\u53f7 +# \u9080\u8BF7\u7ED1\u5B9A\u5BA2\u670D\u5E10\u53F7 kf_invite_uri={api_base_url}customservice/kfaccount/inviteworker?access_token=%s -# \u66f4\u65b0\u591a\u5ba2\u670d\u8d26\u53f7 +# \u66F4\u65B0\u591A\u5BA2\u670D\u8D26\u53F7 kf_update_uri={api_base_url}/customservice/kfaccount/update?access_token=%s -# \u4e0a\u4f20\u5ba2\u670d\u5934\u50cf +# \u4E0A\u4F20\u5BA2\u670D\u5934\u50CF kf_avatar_uri={api_base_url}/customservice/kfacount/uploadheadimg?access_token=%s&kf_account=%s -# \u5220\u9664\u5ba2\u670d\u8d26\u53f7 +# \u5220\u9664\u5BA2\u670D\u8D26\u53F7 kf_delete_uri={api_base_url}/customservice/kfaccount/del?access_token=%s&kf_account=%s -# \u521b\u5efa\u5ba2\u670d\u4f1a\u8bdd +# \u521B\u5EFA\u5BA2\u670D\u4F1A\u8BDD kfsession_create_uri={api_base_url}/customservice/kfsession/create?access_token=%s -# \u5173\u95ed\u5ba2\u670d\u4f1a\u8bdd +# \u5173\u95ED\u5BA2\u670D\u4F1A\u8BDD kfsession_close_uri={api_base_url}/customservice/kfsession/close?access_token=%s -# \u83b7\u53d6\u5ba2\u670d\u4f1a\u8bdd\u72b6\u6001 +# \u83B7\u53D6\u5BA2\u670D\u4F1A\u8BDD\u72B6\u6001 kfsession_get_uri={api_base_url}/customservice/kfsession/getsession?access_token=%s&openid=%s -# \u83b7\u53d6\u5ba2\u670d\u7684\u4f1a\u8bdd\u5217\u8868 +# \u83B7\u53D6\u5BA2\u670D\u7684\u4F1A\u8BDD\u5217\u8868 kfsession_list_uri={api_base_url}/customservice/kfsession/getsessionlist?access_token=%s&kf_account=%s -# \u83b7\u53d6\u672a\u63a5\u5165\u4f1a\u8bdd\u5217\u8868 +# \u83B7\u53D6\u672A\u63A5\u5165\u4F1A\u8BDD\u5217\u8868 kfsession_wait_uri={api_base_url}/customservice/kfsession/getwaitcase?access_token=%s -# \u957f\u94fe\u63a5\u8f6c\u77ed\u94fe\u63a5 +# \u957F\u94FE\u63A5\u8F6C\u77ED\u94FE\u63A5 shorturl_uri={api_cgi_url}/shorturl?access_token=%s -# \u8bbe\u7f6e\u5907\u6ce8\u540d +# \u8BBE\u7F6E\u5907\u6CE8\u540D username_remark_uri={api_cgi_url}/user/info/updateremark?access_token=%s -# \u8bbe\u7f6e\u6a21\u677f\u6d88\u606f\u6240\u5904\u884c\u4e1a +# \u8BBE\u7F6E\u6A21\u677F\u6D88\u606F\u6240\u5904\u884C\u4E1A template_set_industry_uri={api_cgi_url}/template/api_set_industry?access_token=%s -# \u83b7\u53d6\u8bbe\u7f6e\u7684\u884c\u4e1a\u4fe1\u606f +# \u83B7\u53D6\u8BBE\u7F6E\u7684\u884C\u4E1A\u4FE1\u606F template_get_industry_uri={api_cgi_url}/template/get_industry?access_token=%s -# \u83b7\u53d6\u6a21\u677f\u6d88\u606fID +# \u83B7\u53D6\u6A21\u677F\u6D88\u606FID template_getid_uri={api_cgi_url}/template/api_add_template?access_token=%s -# \u83b7\u53d6\u6a21\u677f\u5217\u8868 +# \u83B7\u53D6\u6A21\u677F\u5217\u8868 template_getall_uri={api_cgi_url}/template/get_all_private_template?access_token=%s -# \u5220\u9664\u6a21\u677f +# \u5220\u9664\u6A21\u677F template_del_uri={api_cgi_url}/template/del_private_template?access_token=%s -# \u53d1\u9001\u6a21\u677f\u6d88\u606f +# \u53D1\u9001\u6A21\u677F\u6D88\u606F template_send_uri={api_cgi_url}/message/template/send?access_token=%s -# \u8bed\u4e49\u7406\u89e3 +# \u8BED\u4E49\u7406\u89E3 semantic_uri={api_base_url}/semantic/semproxy/search?access_token=%s -# \u5fae\u4fe1\u670d\u52a1\u5730\u5740 +# \u5FAE\u4FE1\u670D\u52A1\u5730\u5740 getcallbackip_uri={api_cgi_url}/getcallbackip?access_token=%s -# \u63a5\u53e3\u8c03\u7528\u6b21\u6570\u6e05\u96f6 +# \u63A5\u53E3\u8C03\u7528\u6B21\u6570\u6E05\u96F6 clearquota_uri={api_cgi_url}/clear_quota?access_token=%s -# \u6570\u636e\u7edf\u8ba1 +# \u6570\u636E\u7EDF\u8BA1 datacube_uri={api_base_url}/datacube/%s?access_token=%s -##########################\u8001\u7248\u672c\u652f\u4ed8~start -# \u8ba2\u5355\u67e5\u8be2 +##########################\u8001\u7248\u672C\u652F\u4ED8~start +# \u8BA2\u5355\u67E5\u8BE2 orderquery_old_uri={api_base_url}/pay/orderquery?access_token=%s -# \u53d1\u8d27\u901a\u77e5 +# \u53D1\u8D27\u901A\u77E5 delivernotify_old_uri={api_base_url}/pay/delivernotify?access_token=%s -# \u7ef4\u6743\u5904\u7406 +# \u7EF4\u6743\u5904\u7406 payfeedback_old_uri={api_base_url}/payfeedback/update?access_token=%s&openid=%s&feedbackid=%s -# \u5bf9\u8d26\u5355\u4e0b\u8f7d +# \u5BF9\u8D26\u5355\u4E0B\u8F7D downloadbill_old_uri={tenpay_base_url}/cgi-bin/mchdown_real_new.cgi -# \u9000\u6b3e\u67e5\u8be2 +# \u9000\u6B3E\u67E5\u8BE2 refundquery_old_uri={tenpay_gw_base_url}/gateway/normalrefundquery.xml -# \u9000\u6b3e\u7533\u8bf7 +# \u9000\u6B3E\u7533\u8BF7 refundapply_old_uri={tenpay_ssl_base_url}/refundapi/gateway/refund.xml -# native\u652f\u4ed8 +# native\u652F\u4ED8 nativepay_old_uri=weixin://wxpay/bizpayurl?sign=%s&appid=%s&productid=%s×tamp=%s&noncestr=%s -##########################\u8001\u7248\u672c\u652f\u4ed8~end +##########################\u8001\u7248\u672C\u652F\u4ED8~end -# \u4e0a\u4f20\u6c38\u4e45\u56fe\u6587\u7d20\u6750 +# \u4E0A\u4F20\u6C38\u4E45\u56FE\u6587\u7D20\u6750 material_article_upload_uri={api_cgi_url}/material/add_news?access_token=%s -# \u4e0a\u4f20\u6c38\u4e45\u5a92\u4f53\u7d20\u6750 +# \u4E0A\u4F20\u6C38\u4E45\u5A92\u4F53\u7D20\u6750 material_media_upload_uri={api_cgi_url}/material/add_material?access_token=%s -# \u4e0b\u8f7d\u6c38\u4e45\u5a92\u4f53\u7d20\u6750 +# \u4E0B\u8F7D\u6C38\u4E45\u5A92\u4F53\u7D20\u6750 material_media_download_uri={api_cgi_url}/material/get_material?access_token=%s -# \u66f4\u65b0\u6c38\u4e45\u56fe\u6587\u7d20\u6750 +# \u66F4\u65B0\u6C38\u4E45\u56FE\u6587\u7D20\u6750 material_article_update_uri={api_cgi_url}/material/update_news?access_token=%s -# \u5220\u9664\u6c38\u4e45\u5a92\u4f53\u7d20\u6750 +# \u5220\u9664\u6C38\u4E45\u5A92\u4F53\u7D20\u6750 material_media_del_uri={api_cgi_url}/material/del_material?access_token=%s -# \u83b7\u53d6\u5a92\u4f53\u7d20\u6750\u603b\u6570 +# \u83B7\u53D6\u5A92\u4F53\u7D20\u6750\u603B\u6570 material_media_count_uri={api_cgi_url}/material/get_materialcount?access_token=%s -# \u83b7\u53d6\u5a92\u4f53\u7d20\u6750\u5217\u8868 +# \u83B7\u53D6\u5A92\u4F53\u7D20\u6750\u5217\u8868 material_media_list_uri={api_cgi_url}/material/batchget_material?access_token=%s -# \u81ea\u52a8\u56de\u590d\u89c4\u5219 +# \u81EA\u52A8\u56DE\u590D\u89C4\u5219 autoreply_setting_get_uri={api_cgi_url}/get_current_autoreply_info?access_token=%s -# \u521b\u5efa\u6807\u7b7e +# \u521B\u5EFA\u6807\u7B7E tag_create_uri={api_cgi_url}/tags/create?access_token=%s -# \u83b7\u53d6\u6807\u7b7e +# \u83B7\u53D6\u6807\u7B7E tag_get_uri={api_cgi_url}/tags/get?access_token=%s -# \u66f4\u65b0\u6807\u7b7e +# \u66F4\u65B0\u6807\u7B7E tag_update_uri={api_cgi_url}/tags/update?access_token=%s -# \u5220\u9664\u6807\u7b7e +# \u5220\u9664\u6807\u7B7E tag_delete_uri={api_cgi_url}/tags/delete?access_token=%s -# \u4e3a\u7528\u6237\u6253\u6807\u7b7e +# \u4E3A\u7528\u6237\u6253\u6807\u7B7E tag_tagging_uri={api_cgi_url}/tags/members/batchtagging?access_token=%s -# \u4e3a\u7528\u6237\u53d6\u6d88\u6807\u7b7e +# \u4E3A\u7528\u6237\u53D6\u6D88\u6807\u7B7E tag_untagging_uri={api_cgi_url}/tags/members/batchuntagging?access_token=%s -# \u83b7\u53d6\u7528\u6237\u8eab\u4e0a\u7684\u6807\u7b7e\u5217\u8868 +# \u83B7\u53D6\u7528\u6237\u8EAB\u4E0A\u7684\u6807\u7B7E\u5217\u8868 tag_userids_uri={api_cgi_url}/tags/getidlist?access_token=%s -# \u83b7\u53d6\u6807\u7b7e\u4e0b\u7c89\u4e1d\u5217\u8868 +# \u83B7\u53D6\u6807\u7B7E\u4E0B\u7C89\u4E1D\u5217\u8868 tag_user_uri={api_cgi_url}/user/tag/get?access_token=%s # \u83b7\u53d6\u9ed1\u540d\u5355\u5217\u8868 getblacklist_uri={api_cgi_url}/tags/members/getblacklist?access_token=%s @@ -197,20 +197,31 @@ batchblacklist_uri={api_cgi_url}/tags/members/batchblacklist?access_token=%s # \u53d6\u6d88\u62c9\u9ed1\u7528\u6237 batchunblacklist_uri={api_cgi_url}/tags/members/batchunblacklist?access_token=%s -# \u521b\u5efa\u5361\u5238 +# \u521B\u5EFA\u5361\u5238 card_create_uri={api_base_url}/card/create?access_token=%s -# \u8bbe\u7f6e\u4e70\u5355\u63a5\u53e3 +# \u8BBE\u7F6E\u4E70\u5355\u63A5\u53E3 card_paycell_uri={api_base_url}/card/paycell/set?access_token=%s -# \u8bbe\u7f6e\u81ea\u52a9\u6838\u9500\u63a5\u53e3 +# \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 +# \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 +# \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 -# \u83b7\u53d6\u6388\u6743\u65b9\u7684\u516c\u4f17\u53f7\u5e10\u53f7\u57fa\u672c\u4fe1\u606f +# \u83B7\u53D6\u6388\u6743\u65B9\u7684\u516C\u4F17\u53F7\u5E10\u53F7\u57FA\u672C\u4FE1\u606F component_get_authorizer_uri={api_cgi_url}/component/api_get_authorizer_info?component_access_token=%s -# \u83b7\u53d6\u6388\u6743\u65b9\u7684\u9009\u9879\u8bbe\u7f6e\u4fe1\u606f +# \u83B7\u53D6\u6388\u6743\u65B9\u7684\u9009\u9879\u8BBE\u7F6E\u4FE1\u606F component_get_authorizer_option_uri={api_cgi_url}/component/api_get_authorizer_option?component_access_token=%s -# \u8bbe\u7f6e\u6388\u6743\u65b9\u7684\u9009\u9879\u4fe1\u606f -component_set_authorizer_option_uri={api_cgi_url}component/api_set_authorizer_option?component_access_token=%s \ No newline at end of file +# \u8BBE\u7F6E\u6388\u6743\u65B9\u7684\u9009\u9879\u4FE1\u606F +component_set_authorizer_option_uri={api_cgi_url}component/api_set_authorizer_option?component_access_token=%s + +# \u6447\u4E00\u6447\u5468\u8FB9-\u7533\u8BF7\u8BBE\u5907ID +shake_around_device_apply_uri={api_base_url}/shakearound/device/applyid?access_token=%s +# \u6447\u4E00\u6447\u5468\u8FB9-\u8BBE\u5907ID\u7533\u8BF7\u72B6\u6001\u67E5\u8BE2 +shake_around_device_apply_status_uri={api_base_url}/shakearound/device/applystatus?access_token=%s +#\u6447\u4E00\u6447\u5468\u8FB9-\u8BBE\u5907\u7F16\u8F91\u5907\u6CE8\u4FE1\u606F +shake_around_device_update_uri={api_base_url}/shakearound/device/update?access_token=%s +#\u6447\u4E00\u6447\u5468\u8FB9-\u67E5\u8BE2\u8BBE\u5907\u5217\u8868 +shake_around_device_search_uri={api_base_url}/shakearound/device/search?access_token=%s +#\u6447\u4E00\u6447\u5468\u8FB9-\u83B7\u53D6\u8BBE\u5907\u548C\u7528\u6237\u4FE1\u606F +shake_around_user_get_shake_info={api_base_url}/shakearound/user/getshakeinfo?access_token=%s \ No newline at end of file diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/shakearound/Device.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/shakearound/Device.java new file mode 100644 index 00000000..bdfadd6b --- /dev/null +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/shakearound/Device.java @@ -0,0 +1,158 @@ +package com.foxinmy.weixin4j.mp.model.shakearound; + +import com.alibaba.fastjson.annotation.JSONField; + +/** + * 摇一摇设备信息。device_id 和 uuid major minor 可以2者选一 + * @auther: Feng Yapeng + * @since: 2016/10/13 9:59 + */ +public class Device { + + /** + * 设备编号 + */ + @JSONField(name = "device_id") + private Integer deviceId; + + + private String uuid; + + private Integer major; + + private Integer minor; + + /** + * 激活状态,0:未激活,1:已激活 + */ + private int status; + + /** + * 设备最近一次被摇到的日期(最早只能获取前一天的数据);新申请的设备该字段值为0 + */ + @JSONField(name = "last_active_time") + private String lastActiveTime; + + /** + * 若配置了设备与其他公众账号门店关联关系,则返回配置门店归属的公众账号appid。 + * 查看配置设备与其他公众账号门店关联关系接口 + */ + @JSONField(name = "poi_appid") + private String poiAppId; + + /** + * 设备关联的门店ID,关联门店后,在门店1KM的范围内有优先摇出信息的机会。 + * 门店相关信息具体可查看门店相关的接口文档 + */ + @JSONField(name = "poi_id") + private String poiId; + + /** + * 设备的备注信息 + */ + private String comment; + + + public Device() { + } + + /** + * + * @param deviceId + */ + public Device(Integer deviceId) { + this.deviceId = deviceId; + } + + public Device(String uuid, Integer major, Integer minor) { + this.uuid = uuid; + this.major = major; + this.minor = minor; + } + + public Integer getDeviceId() { + return deviceId; + } + + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Integer getMajor() { + return major; + } + + public void setMajor(int major) { + this.major = major; + } + + public Integer getMinor() { + return minor; + } + + public void setMinor(int minor) { + this.minor = minor; + } + + public void setDeviceId(Integer deviceId) { + this.deviceId = deviceId; + } + + public void setMajor(Integer major) { + this.major = major; + } + + public void setMinor(Integer minor) { + this.minor = minor; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getLastActiveTime() { + return lastActiveTime; + } + + public void setLastActiveTime(String lastActiveTime) { + this.lastActiveTime = lastActiveTime; + } + + public String getPoiAppId() { + return poiAppId; + } + + public void setPoiAppId(String poiAppId) { + this.poiAppId = poiAppId; + } + + public String getPoiId() { + return poiId; + } + + public void setPoiId(String poiId) { + this.poiId = poiId; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + +} diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/shakearound/DeviceAuditState.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/shakearound/DeviceAuditState.java new file mode 100644 index 00000000..7594a883 --- /dev/null +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/shakearound/DeviceAuditState.java @@ -0,0 +1,84 @@ +package com.foxinmy.weixin4j.mp.model.shakearound; + +import com.alibaba.fastjson.annotation.JSONField; + +import java.util.Date; + +/** + * 摇一摇周边设备审核信息 + * + * @auther: Feng Yapeng + * @since: 2016/10/12 21:47 + */ +public class DeviceAuditState { + + /** + * 申请设备ID时所返回的批次ID + */ + @JSONField(name = "apply_id") + private Integer applyId; + /** + * 审核状态。0:审核未通过、1:审核中、2:审核已通过; + * 若单次申请的设备ID数量小于等于500个,系统会进行快速审核; + * 若单次申请的设备ID数量大于500个,会在三个工作日内完成审核; + */ + @JSONField(name = "audit_status") + private String auditStatus; + + /** + * 审核备注,对审核状态的文字说明 + */ + @JSONField(name = "audit_comment") + private String auditComment; + /** + * 提交申请的时间戳 + */ + @JSONField(name = "apply_time") + private long applyTime; + + /** + * 确定审核结果的时间戳,若状态为审核中,则该时间值为0 + */ + @JSONField(name = "audit_time") + private long auditTime; + + public Integer getApplyId() { + return applyId; + } + + public void setApplyId(Integer applyId) { + this.applyId = applyId; + } + + public String getAuditStatus() { + return auditStatus; + } + + public void setAuditStatus(String auditStatus) { + this.auditStatus = auditStatus; + } + + public String getAuditComment() { + return auditComment; + } + + public void setAuditComment(String auditComment) { + this.auditComment = auditComment; + } + + public long getApplyTime() { + return applyTime; + } + + public void setApplyTime(long applyTime) { + this.applyTime = applyTime; + } + + public long getAuditTime() { + return auditTime; + } + + public void setAuditTime(long auditTime) { + this.auditTime = auditTime; + } +} diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/shakearound/ShakeUserInfo.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/shakearound/ShakeUserInfo.java new file mode 100644 index 00000000..37260164 --- /dev/null +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/shakearound/ShakeUserInfo.java @@ -0,0 +1,58 @@ +package com.foxinmy.weixin4j.mp.model.shakearound; + +import com.alibaba.fastjson.annotation.JSONField; + +/** + * 获取设备信息,包括UUID、major、minor,以及距离、openID等信息。 + * + * @author fengyapeng + * @auther: Feng Yapeng + * @since: 2016 /10/21 19:21 + * @since 2016 -10-21 19:21:59 + */ +public class ShakeUserInfo { + + + @JSONField(name = "page_id") + private Long pageId; + @JSONField(name = "beacon_info") + private Device device; + + @JSONField(name = "poi_id") + private Long poiId; + + @JSONField(name = "openid") + private String openId; + + public Long getPageId() { + return pageId; + } + + public void setPageId(Long pageId) { + this.pageId = pageId; + } + + public Device getDevice() { + return device; + } + + public void setDevice(Device device) { + this.device = device; + } + + public Long getPoiId() { + return poiId; + } + + public void setPoiId(Long poiId) { + this.poiId = poiId; + } + + public String getOpenId() { + return openId; + } + + public void setOpenId(String openId) { + this.openId = openId; + } +} diff --git a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/HelpTest.java b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/HelpTest.java new file mode 100644 index 00000000..c2e0e06b --- /dev/null +++ b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/HelpTest.java @@ -0,0 +1,35 @@ +package com.foxinmy.weixin4j.mp.test; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.foxinmy.weixin4j.exception.WeixinException; +import com.foxinmy.weixin4j.mp.api.HelperApi; + +public class HelpTest extends TokenTest { + private HelperApi helperApi; + + @Before + public void init() { + helperApi = new HelperApi(tokenManager); + } + + @Test + public void getWechatServerIp() throws WeixinException { + List ipList = helperApi.getWechatServerIp(); + Assert.assertFalse(ipList.isEmpty()); + } + + @Test + public void getMenuSetting() throws WeixinException { + System.err.println(helperApi.getMenuSetting()); + } + + @Test + public void getAutoReplySetting() throws WeixinException { + System.err.println(helperApi.getAutoReplySetting()); + } +}