| @@ -24,7 +24,9 @@ public interface WxMpTemplateMsgService { | |||||
| * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN | * 详情请见:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN | ||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @param wxMpIndustry 行业信息 | |||||
| * @return 是否成功 | * @return 是否成功 | ||||
| * @throws WxErrorException . | |||||
| */ | */ | ||||
| boolean setIndustry(WxMpTemplateIndustry wxMpIndustry) throws WxErrorException; | boolean setIndustry(WxMpTemplateIndustry wxMpIndustry) throws WxErrorException; | ||||
| @@ -35,6 +37,7 @@ public interface WxMpTemplateMsgService { | |||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @return wxMpIndustry | * @return wxMpIndustry | ||||
| * @throws WxErrorException . | |||||
| */ | */ | ||||
| WxMpTemplateIndustry getIndustry() throws WxErrorException; | WxMpTemplateIndustry getIndustry() throws WxErrorException; | ||||
| @@ -44,7 +47,9 @@ public interface WxMpTemplateMsgService { | |||||
| * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN | * 详情请见: http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN | ||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @param templateMessage 模板消息 | |||||
| * @return 消息Id | * @return 消息Id | ||||
| * @throws WxErrorException . | |||||
| */ | */ | ||||
| String sendTemplateMsg(WxMpTemplateMessage templateMessage) throws WxErrorException; | String sendTemplateMsg(WxMpTemplateMessage templateMessage) throws WxErrorException; | ||||
| @@ -58,6 +63,7 @@ public interface WxMpTemplateMsgService { | |||||
| * | * | ||||
| * @param shortTemplateId 模板库中模板的编号,有“TM**”和“OPENTMTM**”等形式 | * @param shortTemplateId 模板库中模板的编号,有“TM**”和“OPENTMTM**”等形式 | ||||
| * @return templateId 模板Id | * @return templateId 模板Id | ||||
| * @throws WxErrorException . | |||||
| */ | */ | ||||
| String addTemplate(String shortTemplateId) throws WxErrorException; | String addTemplate(String shortTemplateId) throws WxErrorException; | ||||
| @@ -70,6 +76,7 @@ public interface WxMpTemplateMsgService { | |||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @return templateId 模板Id | * @return templateId 模板Id | ||||
| * @throws WxErrorException . | |||||
| */ | */ | ||||
| List<WxMpTemplate> getAllPrivateTemplate() throws WxErrorException; | List<WxMpTemplate> getAllPrivateTemplate() throws WxErrorException; | ||||
| @@ -82,6 +89,8 @@ public interface WxMpTemplateMsgService { | |||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @param templateId 模板Id | * @param templateId 模板Id | ||||
| * @return . | |||||
| * @throws WxErrorException . | |||||
| */ | */ | ||||
| boolean delPrivateTemplate(String templateId) throws WxErrorException; | boolean delPrivateTemplate(String templateId) throws WxErrorException; | ||||
| } | } | ||||
| @@ -42,8 +42,8 @@ public class WxMpTemplateMsgServiceImpl implements WxMpTemplateMsgService { | |||||
| @Override | @Override | ||||
| public boolean setIndustry(WxMpTemplateIndustry wxMpIndustry) throws WxErrorException { | public boolean setIndustry(WxMpTemplateIndustry wxMpIndustry) throws WxErrorException { | ||||
| if (null == wxMpIndustry.getPrimaryIndustry() || null == wxMpIndustry.getPrimaryIndustry().getId() | |||||
| || null == wxMpIndustry.getSecondIndustry() || null == wxMpIndustry.getSecondIndustry().getId()) { | |||||
| if (null == wxMpIndustry.getPrimaryIndustry() || null == wxMpIndustry.getPrimaryIndustry().getCode() | |||||
| || null == wxMpIndustry.getSecondIndustry() || null == wxMpIndustry.getSecondIndustry().getCode()) { | |||||
| throw new IllegalArgumentException("行业Id不能为空,请核实"); | throw new IllegalArgumentException("行业Id不能为空,请核实"); | ||||
| } | } | ||||
| @@ -1,28 +1,26 @@ | |||||
| package me.chanjar.weixin.mp.bean.template; | package me.chanjar.weixin.mp.bean.template; | ||||
| import java.io.Serializable; | |||||
| import lombok.AllArgsConstructor; | |||||
| import lombok.Data; | import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | |||||
| import lombok.experimental.Accessors; | |||||
| import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; | ||||
| import java.io.Serializable; | |||||
| /** | /** | ||||
| * @author miller | * @author miller | ||||
| */ | */ | ||||
| @Data | @Data | ||||
| @NoArgsConstructor | |||||
| @AllArgsConstructor | |||||
| @Accessors(chain = true) | |||||
| public class WxMpTemplateIndustry implements Serializable { | public class WxMpTemplateIndustry implements Serializable { | ||||
| private static final long serialVersionUID = -7700398224795914722L; | private static final long serialVersionUID = -7700398224795914722L; | ||||
| private Industry primaryIndustry; | |||||
| private Industry secondIndustry; | |||||
| public WxMpTemplateIndustry() { | |||||
| } | |||||
| public WxMpTemplateIndustry(Industry primaryIndustry, Industry secondIndustry) { | |||||
| this.primaryIndustry = primaryIndustry; | |||||
| this.secondIndustry = secondIndustry; | |||||
| } | |||||
| private WxMpTemplateIndustryEnum primaryIndustry; | |||||
| private WxMpTemplateIndustryEnum secondIndustry; | |||||
| public static WxMpTemplateIndustry fromJson(String json) { | public static WxMpTemplateIndustry fromJson(String json) { | ||||
| return WxMpGsonBuilder.create().fromJson(json, WxMpTemplateIndustry.class); | return WxMpGsonBuilder.create().fromJson(json, WxMpTemplateIndustry.class); | ||||
| @@ -41,29 +39,22 @@ public class WxMpTemplateIndustry implements Serializable { | |||||
| * 官方文档中,创建和获取的数据结构不一样。所以采用冗余字段的方式,实现相应的接口. | * 官方文档中,创建和获取的数据结构不一样。所以采用冗余字段的方式,实现相应的接口. | ||||
| */ | */ | ||||
| @Data | @Data | ||||
| @NoArgsConstructor | |||||
| @AllArgsConstructor | |||||
| @Accessors(chain = true) | |||||
| public static class Industry implements Serializable { | public static class Industry implements Serializable { | ||||
| private static final long serialVersionUID = -1707184885588012142L; | private static final long serialVersionUID = -1707184885588012142L; | ||||
| private String id; | private String id; | ||||
| private String firstClass; | private String firstClass; | ||||
| private String secondClass; | private String secondClass; | ||||
| public Industry() { | |||||
| } | |||||
| public Industry(String id) { | public Industry(String id) { | ||||
| this.id = id; | this.id = id; | ||||
| } | } | ||||
| public Industry(String id, String firstClass, String secondClass) { | |||||
| this.id = id; | |||||
| this.firstClass = firstClass; | |||||
| this.secondClass = secondClass; | |||||
| } | |||||
| @Override | @Override | ||||
| public String toString() { | public String toString() { | ||||
| return WxMpGsonBuilder.create().toJson(this); | return WxMpGsonBuilder.create().toJson(this); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,224 @@ | |||||
| package me.chanjar.weixin.mp.bean.template; | |||||
| import lombok.AllArgsConstructor; | |||||
| import lombok.Getter; | |||||
| /** | |||||
| * 模版消息行业枚举. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * @date 2019-10-18 | |||||
| */ | |||||
| @Getter | |||||
| @AllArgsConstructor | |||||
| public enum WxMpTemplateIndustryEnum { | |||||
| /** | |||||
| * IT科技 - 互联网|电子商务 | |||||
| */ | |||||
| E_COMMERCE("IT科技", "互联网|电子商务", 1), | |||||
| /** | |||||
| * IT科技 - IT软件与服务 | |||||
| */ | |||||
| IT_SOFTWARE_AND_SERVICES("IT科技", "IT软件与服务", 2), | |||||
| /** | |||||
| * IT科技 - IT硬件与设备 | |||||
| */ | |||||
| IT_HARDWARE_AND_EQUIPMENT("IT科技", "IT硬件与设备", 3), | |||||
| /** | |||||
| * IT科技 - 电子技术 | |||||
| */ | |||||
| ELECTRONIC_TECHNIQUE("IT科技", "电子技术", 4), | |||||
| /** | |||||
| * IT科技 - 通信与运营商 | |||||
| */ | |||||
| COMMUNICATION_AND_OPERATOR("IT科技", "通信与运营商", 5), | |||||
| /** | |||||
| * IT科技 - 网络游戏 | |||||
| */ | |||||
| ONLINE_GAME("IT科技", "网络游戏", 6), | |||||
| /** | |||||
| * 金融业 - 银行 | |||||
| */ | |||||
| BANK("金融业", "银行", 7), | |||||
| /** | |||||
| * 金融业 - 基金|理财|信托 | |||||
| */ | |||||
| FUND("金融业", "基金|理财|信托", 8), | |||||
| /** | |||||
| * 金融业 - 保险 | |||||
| */ | |||||
| INSURANCE("金融业", "保险", 9), | |||||
| /** | |||||
| * 餐饮 - 餐饮 | |||||
| */ | |||||
| REPAST("餐饮", "餐饮", 10), | |||||
| /** | |||||
| * 酒店旅游 - 酒店 | |||||
| */ | |||||
| HOTEL("酒店旅游", "酒店", 11), | |||||
| /** | |||||
| * 酒店旅游 - 旅游 | |||||
| */ | |||||
| TRAVEL("酒店旅游", "旅游", 12), | |||||
| /** | |||||
| * 运输与仓储 - 快递 | |||||
| */ | |||||
| EXPRESS("运输与仓储", "快递", 13), | |||||
| /** | |||||
| * 运输与仓储 - 物流 | |||||
| */ | |||||
| LOGISTICS("运输与仓储", "物流", 14), | |||||
| /** | |||||
| * 运输与仓储 - 仓储 | |||||
| */ | |||||
| STORAGE("运输与仓储", "仓储", 15), | |||||
| /** | |||||
| * 教育 - 培训 | |||||
| */ | |||||
| CULTIVATE("教育", "培训", 16), | |||||
| /** | |||||
| * 教育 - 院校 | |||||
| */ | |||||
| ACADEMY("教育", "院校", 17), | |||||
| /** | |||||
| * 政府与公共事业 - 学术科研 | |||||
| */ | |||||
| ACADEMIC_RESEARCH("政府与公共事业", "学术科研", 18), | |||||
| /** | |||||
| * 政府与公共事业 - 交警 | |||||
| */ | |||||
| TRAFFIC_POLICE("政府与公共事业", "交警", 19), | |||||
| /** | |||||
| * 政府与公共事业 - 博物馆 | |||||
| */ | |||||
| MUSEUM("政府与公共事业", "博物馆", 20), | |||||
| /** | |||||
| * 政府与公共事业 - 公共事业|非盈利机构 | |||||
| */ | |||||
| PUBLIC_WORKS_NONPROFIT("政府与公共事业", "公共事业|非盈利机构", 21), | |||||
| /** | |||||
| * 医药护理 - 医药医疗 | |||||
| */ | |||||
| MEDICAL_HEALTH("医药护理", "医药医疗", 22), | |||||
| /** | |||||
| * 医药护理 - 护理美容 | |||||
| */ | |||||
| CARE_AND_BEAUTY("医药护理", "护理美容", 23), | |||||
| /** | |||||
| * 医药护理 - 保健与卫生 | |||||
| */ | |||||
| HEALTH_AND_HYGIENE("医药护理", "保健与卫生", 24), | |||||
| /** | |||||
| * 交通工具 - 汽车相关 | |||||
| */ | |||||
| AUTOMOTIVE_RELATED("交通工具", "汽车相关", 25), | |||||
| /** | |||||
| * 交通工具 - 摩托车相关 | |||||
| */ | |||||
| MOTORCYCLE_CORRELATION("交通工具", "摩托车相关", 26), | |||||
| /** | |||||
| * 交通工具 - 火车相关 | |||||
| */ | |||||
| THE_TRAIN_RELATED("交通工具", "火车相关", 27), | |||||
| /** | |||||
| * 交通工具 - 飞机相关 | |||||
| */ | |||||
| THE_PLANE_RELATED("交通工具", "飞机相关", 28), | |||||
| /** | |||||
| * 房地产 - 建筑 | |||||
| */ | |||||
| ARCHITECTURE("房地产", "建筑", 29), | |||||
| /** | |||||
| * 房地产 - 物业 | |||||
| */ | |||||
| REAL_ESTATE("房地产", "物业", 30), | |||||
| /** | |||||
| * 消费品 - 消费品 | |||||
| */ | |||||
| CONSUMER_GOODS("消费品", "消费品", 31), | |||||
| /** | |||||
| * 商业服务 - 法律 | |||||
| */ | |||||
| LEGISLATION("商业服务", "法律", 32), | |||||
| /** | |||||
| * 商业服务 - 会展 | |||||
| */ | |||||
| CONVENTION_AND_EXHIBITION("商业服务", "会展", 33), | |||||
| /** | |||||
| * 商业服务 - 中介服务 | |||||
| */ | |||||
| INTERMEDIARY_SERVICES("商业服务", "中介服务", 34), | |||||
| /** | |||||
| * 商业服务 - 认证 | |||||
| */ | |||||
| AUTHENTICATION("商业服务", "认证", 35), | |||||
| /** | |||||
| * 商业服务 - 会计|审计 | |||||
| */ | |||||
| AUDIT("商业服务", "会计|审计", 36), | |||||
| /** | |||||
| * 文体娱乐 - 传媒 | |||||
| */ | |||||
| MASS_MEDIA("文体娱乐", "传媒", 37), | |||||
| /** | |||||
| * 文体娱乐 - 体育 | |||||
| */ | |||||
| SPORTS("文体娱乐", "体育", 38), | |||||
| /** | |||||
| * 文体娱乐 - 娱乐休闲 | |||||
| */ | |||||
| LEISURE_AND_ENTERTAINMENT("文体娱乐", "娱乐休闲", 39), | |||||
| /** | |||||
| * 印刷 - 印刷 | |||||
| */ | |||||
| PRINTING("印刷", "印刷", 40), | |||||
| /** | |||||
| * 其它 - 其它 | |||||
| */ | |||||
| OTHER("其它", "其它", 41); | |||||
| /** | |||||
| * 主行业(一级行业) | |||||
| */ | |||||
| public final String firstClass; | |||||
| /** | |||||
| * 副行业(二级行业) | |||||
| */ | |||||
| public final String secondClass; | |||||
| /** | |||||
| * 行业代码 | |||||
| */ | |||||
| public final Integer code; | |||||
| /** | |||||
| * 查找行业 | |||||
| * | |||||
| * @param industry 二级行业名称 | |||||
| * @return . | |||||
| */ | |||||
| public static WxMpTemplateIndustryEnum findBySecondary(String industry) { | |||||
| for (WxMpTemplateIndustryEnum industryEnum : WxMpTemplateIndustryEnum.values()) { | |||||
| if (industryEnum.secondClass.equals(industry)) { | |||||
| return industryEnum; | |||||
| } | |||||
| } | |||||
| return null; | |||||
| } | |||||
| /** | |||||
| * 查找行业 | |||||
| * | |||||
| * @param code 行业编码 | |||||
| * @return . | |||||
| */ | |||||
| public static WxMpTemplateIndustryEnum findByCode(int code) { | |||||
| for (WxMpTemplateIndustryEnum industryEnum : WxMpTemplateIndustryEnum.values()) { | |||||
| if (industryEnum.code == code) { | |||||
| return industryEnum; | |||||
| } | |||||
| } | |||||
| return null; | |||||
| } | |||||
| } | |||||
| @@ -3,41 +3,32 @@ package me.chanjar.weixin.mp.util.json; | |||||
| import com.google.gson.*; | import com.google.gson.*; | ||||
| import me.chanjar.weixin.common.util.json.GsonHelper; | import me.chanjar.weixin.common.util.json.GsonHelper; | ||||
| import me.chanjar.weixin.mp.bean.template.WxMpTemplateIndustry; | import me.chanjar.weixin.mp.bean.template.WxMpTemplateIndustry; | ||||
| import me.chanjar.weixin.mp.bean.template.WxMpTemplateIndustryEnum; | |||||
| import java.lang.reflect.Type; | import java.lang.reflect.Type; | ||||
| /** | /** | ||||
| * @author miller | * @author miller | ||||
| */ | */ | ||||
| public class WxMpIndustryGsonAdapter | |||||
| implements JsonSerializer<WxMpTemplateIndustry>, JsonDeserializer<WxMpTemplateIndustry> { | |||||
| private static WxMpTemplateIndustry.Industry convertFromJson(JsonObject json) { | |||||
| WxMpTemplateIndustry.Industry industry = new WxMpTemplateIndustry.Industry(); | |||||
| industry.setFirstClass(GsonHelper.getString(json, "first_class")); | |||||
| industry.setSecondClass(GsonHelper.getString(json, "second_class")); | |||||
| return industry; | |||||
| } | |||||
| public class WxMpIndustryGsonAdapter implements JsonSerializer<WxMpTemplateIndustry>, JsonDeserializer<WxMpTemplateIndustry> { | |||||
| @Override | @Override | ||||
| public JsonElement serialize(WxMpTemplateIndustry wxMpIndustry, Type type, | |||||
| JsonSerializationContext jsonSerializationContext) { | |||||
| public JsonElement serialize(WxMpTemplateIndustry wxMpIndustry, Type type, JsonSerializationContext context) { | |||||
| JsonObject json = new JsonObject(); | JsonObject json = new JsonObject(); | ||||
| json.addProperty("industry_id1", wxMpIndustry.getPrimaryIndustry().getId()); | |||||
| json.addProperty("industry_id2", wxMpIndustry.getSecondIndustry().getId()); | |||||
| json.addProperty("industry_id1", wxMpIndustry.getPrimaryIndustry().getCode()); | |||||
| json.addProperty("industry_id2", wxMpIndustry.getSecondIndustry().getCode()); | |||||
| return json; | return json; | ||||
| } | } | ||||
| @Override | @Override | ||||
| public WxMpTemplateIndustry deserialize(JsonElement jsonElement, Type type, | |||||
| JsonDeserializationContext jsonDeserializationContext) | |||||
| public WxMpTemplateIndustry deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) | |||||
| throws JsonParseException { | throws JsonParseException { | ||||
| WxMpTemplateIndustry wxMpIndustry = new WxMpTemplateIndustry(); | |||||
| JsonObject primaryIndustry = jsonElement.getAsJsonObject() | |||||
| .get("primary_industry").getAsJsonObject(); | |||||
| wxMpIndustry.setPrimaryIndustry(convertFromJson(primaryIndustry)); | |||||
| JsonObject secondaryIndustry = jsonElement.getAsJsonObject() | |||||
| .get("secondary_industry").getAsJsonObject(); | |||||
| wxMpIndustry.setSecondIndustry(convertFromJson(secondaryIndustry)); | |||||
| return wxMpIndustry; | |||||
| return new WxMpTemplateIndustry() | |||||
| .setPrimaryIndustry(this.convertFromJson(jsonElement.getAsJsonObject().get("primary_industry").getAsJsonObject())) | |||||
| .setSecondIndustry(this.convertFromJson(jsonElement.getAsJsonObject().get("secondary_industry").getAsJsonObject())); | |||||
| } | } | ||||
| private WxMpTemplateIndustryEnum convertFromJson(JsonObject json) { | |||||
| return WxMpTemplateIndustryEnum.findBySecondary(GsonHelper.getString(json, "second_class")); | |||||
| } | |||||
| } | } | ||||
| @@ -5,10 +5,7 @@ import me.chanjar.weixin.common.error.WxErrorException; | |||||
| import me.chanjar.weixin.mp.api.WxMpService; | import me.chanjar.weixin.mp.api.WxMpService; | ||||
| import me.chanjar.weixin.mp.api.test.ApiTestModule; | import me.chanjar.weixin.mp.api.test.ApiTestModule; | ||||
| import me.chanjar.weixin.mp.api.test.TestConfigStorage; | import me.chanjar.weixin.mp.api.test.TestConfigStorage; | ||||
| import me.chanjar.weixin.mp.bean.template.WxMpTemplate; | |||||
| import me.chanjar.weixin.mp.bean.template.WxMpTemplateData; | |||||
| import me.chanjar.weixin.mp.bean.template.WxMpTemplateIndustry; | |||||
| import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage; | |||||
| import me.chanjar.weixin.mp.bean.template.*; | |||||
| import org.apache.commons.lang3.RandomStringUtils; | import org.apache.commons.lang3.RandomStringUtils; | ||||
| import org.testng.Assert; | import org.testng.Assert; | ||||
| import org.testng.annotations.Guice; | import org.testng.annotations.Guice; | ||||
| @@ -32,10 +29,8 @@ public class WxMpTemplateMsgServiceImplTest { | |||||
| @Test(invocationCount = 5, threadPoolSize = 3) | @Test(invocationCount = 5, threadPoolSize = 3) | ||||
| public void testSendTemplateMsg() throws WxErrorException { | public void testSendTemplateMsg() throws WxErrorException { | ||||
| SimpleDateFormat dateFormat = new SimpleDateFormat( | |||||
| "yyyy-MM-dd HH:mm:ss.SSS"); | |||||
| TestConfigStorage configStorage = (TestConfigStorage) this.wxService | |||||
| .getWxMpConfigStorage(); | |||||
| SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); | |||||
| TestConfigStorage configStorage = (TestConfigStorage) this.wxService.getWxMpConfigStorage(); | |||||
| WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder() | WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder() | ||||
| .toUser(configStorage.getOpenid()) | .toUser(configStorage.getOpenid()) | ||||
| .templateId(configStorage.getTemplateId()) | .templateId(configStorage.getTemplateId()) | ||||
| @@ -58,8 +53,8 @@ public class WxMpTemplateMsgServiceImplTest { | |||||
| @Test | @Test | ||||
| public void testSetIndustry() throws Exception { | public void testSetIndustry() throws Exception { | ||||
| WxMpTemplateIndustry industry = new WxMpTemplateIndustry(new WxMpTemplateIndustry.Industry("1"), | |||||
| new WxMpTemplateIndustry.Industry("04")); | |||||
| WxMpTemplateIndustry industry = new WxMpTemplateIndustry(WxMpTemplateIndustryEnum.findByCode(1), | |||||
| WxMpTemplateIndustryEnum.findByCode(4)); | |||||
| boolean result = this.wxService.getTemplateMsgService().setIndustry(industry); | boolean result = this.wxService.getTemplateMsgService().setIndustry(industry); | ||||
| Assert.assertTrue(result); | Assert.assertTrue(result); | ||||
| } | } | ||||