diff --git a/pom.xml b/pom.xml index 4864cc360..4091a237b 100644 --- a/pom.xml +++ b/pom.xml @@ -92,6 +92,11 @@ huangxm129@163.com https://github.com/huangxm129 + + xiaohe + xiaohe@53jy.net + https://github.com/xiaohe-53 + @@ -302,7 +307,7 @@ org.projectlombok lombok - 1.18.8 + 1.18.24 provided diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTaskCardService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTaskCardService.java index 3d97cb928..4109c0a03 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTaskCardService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTaskCardService.java @@ -8,6 +8,7 @@ import java.util.List; *
  *  任务卡片管理接口.
  *  Created by Jeff on 2019-05-16.
+ *  Updted by HeXiao on 2022-03-09.
  * 
* * @author Jeff @@ -23,9 +24,26 @@ public interface WxCpTaskCardService { * 注意: 这个方法使用WxCpConfigStorage里的agentId * * - * @param userIds 企业的成员ID列表 - * @param taskId 任务卡片ID + * @param userIds 企业的成员ID列表 + * @param taskId 任务卡片ID * @param replaceName 替换文案 */ void update(List userIds, String taskId, String replaceName) throws WxErrorException; + + + /** + * 更新按钮为不可点击状态 + * 详情请见https://developer.work.weixin.qq.com/document/path/94888#%E6%9B%B4%E6%96%B0%E6%8C%89%E9%92%AE%E4%B8%BA%E4%B8%8D%E5%8F%AF%E7%82%B9%E5%87%BB%E7%8A%B6%E6%80%81 + * @param userIds 企业的成员ID列表 + * @param partyIds 企业的部门ID列表 + * @param tagIds 企业的标签ID列表 + * @param atAll 更新整个任务接收人员 + * @param responseCode 更新卡片所需要消费的code,可通过发消息接口和回调接口返回值获取,一个code只能调用一次该接口,且只能在24小时内调用 + * @param replaceName 需要更新的按钮的文案 + * @throws WxErrorException + */ + void updateTemplateCardButton(List userIds, List partyIds, + List tagIds, Integer atAll, String responseCode, + String replaceName) throws WxErrorException; + } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImpl.java index 384a3d30c..9e9e7dea0 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImpl.java @@ -38,4 +38,25 @@ public class WxCpTaskCardServiceImpl implements WxCpTaskCardService { String url = this.mainService.getWxCpConfigStorage().getApiUrl(UPDATE_TASK_CARD); this.mainService.post(url, WxGsonBuilder.create().toJson(data)); } + + @Override + public void updateTemplateCardButton(List userIds, List partyIds, + List tagIds, Integer atAll, + String responseCode, String replaceName) throws WxErrorException { + Integer agentId = this.mainService.getWxCpConfigStorage().getAgentId(); + Map data = new HashMap<>(7); + data.put("userids", userIds); + data.put("partyids", partyIds); + data.put("tagids", tagIds); + data.put("atall", atAll); + data.put("agentid", agentId); + data.put("response_code", responseCode); + Map btnMap = new HashMap<>(); + btnMap.put("replace_name", replaceName); + data.put("button", btnMap); + + String url = this.mainService.getWxCpConfigStorage().getApiUrl(UPDATE_TEMPLATE_CARD); + this.mainService.post(url, WxGsonBuilder.create().toJson(data)); + + } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpMessage.java index 780305ddd..1ce367d9f 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpMessage.java @@ -92,6 +92,21 @@ public class WxCpMessage implements Serializable { */ private String sourceDesc; + /** + * 来源文字的颜色,目前支持:0(默认) 灰色,1 黑色,2 红色,3 绿色 + */ + private Integer sourceDescColor; + + /** + * 更多操作界面的描述 + */ + private String actionMenuDesc; + + /** + * 操作列表,列表长度取值范围为 [1, 3] + */ + private List actionMenuActionList; + /** * 一级标题,建议不超过36个字 */ @@ -482,9 +497,22 @@ public class WxCpMessage implements Serializable { if (StringUtils.isNotBlank(this.getSourceDesc())) { source.addProperty("desc", this.getSourceDesc()); } + source.addProperty("desc_color", this.getSourceDescColor()); template.add("source", source); } + if (StringUtils.isNotBlank(this.getActionMenuDesc())) { + JsonObject action_menu = new JsonObject(); + action_menu.addProperty("desc", this.getActionMenuDesc()); + JsonArray actionList = new JsonArray(); + List actionMenuItemList = this.getActionMenuActionList(); + for (ActionMenuItem actionItemI : actionMenuItemList) { + actionList.add(actionItemI.toJson()); + } + action_menu.add("action_list", actionList); + template.add("action_menu", action_menu); + } + if (StringUtils.isNotBlank(this.getMainTitleTitle()) || StringUtils.isNotBlank(this.getMainTitleDesc())) { JsonObject mainTitle = new JsonObject(); if (StringUtils.isNotBlank(this.getMainTitleTitle())) { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TemplateCardBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TemplateCardBuilder.java index 09a506d8e..866b5b7a0 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TemplateCardBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TemplateCardBuilder.java @@ -36,6 +36,21 @@ public class TemplateCardBuilder extends BaseBuilder { */ private String sourceDesc; + /** + * 来源文字的颜色,目前支持:0(默认) 灰色,1 黑色,2 红色,3 绿色 + */ + private Integer sourceDescColor; + + /** + * 更多操作界面的描述 + */ + private String actionMenuDesc; + + /** + * 操作列表,列表长度取值范围为 [1, 3] + */ + private List actionMenuActionList; + /** * 一级标题,建议不超过36个字 */ @@ -172,6 +187,16 @@ public class TemplateCardBuilder extends BaseBuilder { return this; } + public TemplateCardBuilder actionMenuDesc(String actionMenuDesc) { + this.actionMenuDesc = actionMenuDesc; + return this; + } + + public TemplateCardBuilder actionMenuActionList(List actionMenuItemList) { + this.actionMenuActionList = actionMenuItemList; + return this; + } + public TemplateCardBuilder sourceIconUrl(String sourceIconUrl) { this.sourceIconUrl = sourceIconUrl; return this; @@ -182,6 +207,11 @@ public class TemplateCardBuilder extends BaseBuilder { return this; } + public TemplateCardBuilder sourceDescColor(Integer sourceDescColor) { + this.sourceDescColor = sourceDescColor; + return this; + } + public TemplateCardBuilder mainTitleTitle(String mainTitleTitle) { this.mainTitleTitle = mainTitleTitle; return this; @@ -294,6 +324,9 @@ public class TemplateCardBuilder extends BaseBuilder { m.setCardType(this.cardType); m.setSourceIconUrl(this.sourceIconUrl); m.setSourceDesc(this.sourceDesc); + m.setSourceDescColor(this.sourceDescColor); + m.setActionMenuDesc(this.actionMenuDesc); + m.setActionMenuActionList(this.actionMenuActionList); m.setMainTitleTitle(this.mainTitleTitle); m.setMainTitleDesc(this.mainTitleDesc); m.setCardImageUrl(this.cardImageUrl); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/templatecard/ActionMenuItem.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/templatecard/ActionMenuItem.java new file mode 100644 index 000000000..54950fb82 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/templatecard/ActionMenuItem.java @@ -0,0 +1,40 @@ +package me.chanjar.weixin.cp.bean.templatecard; + +import com.google.gson.JsonObject; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 卡片右上角更多操作按钮点击后出现的操作列表,列表长度取值范围为 [1, 3] + * @author xiaohe + * @date 2022-03-06 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ActionMenuItem implements Serializable { + private static final long serialVersionUID = 400885585614100693L; + + /** + * 操作的描述文案 + */ + private String text; + + /** + * 按钮key值,用户点击后,会产生回调事件将本参数作为EventKey返回,回调事件会带上该key值,最长支持1024字节,不可重复 + */ + private String key; + + public JsonObject toJson() { + JsonObject btnObject = new JsonObject(); + btnObject.addProperty("text", this.getText()); + btnObject.addProperty("key", this.getKey()); + return btnObject; + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/templatecard/HorizontalContent.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/templatecard/HorizontalContent.java index 397420820..393a99dac 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/templatecard/HorizontalContent.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/templatecard/HorizontalContent.java @@ -44,6 +44,11 @@ public class HorizontalContent implements Serializable { */ private String media_id; + /** + * 成员详情的userid,horizontal_content_list.type是3时必填 + */ + private String userid; + public JsonObject toJson() { JsonObject hContentJson = new JsonObject(); @@ -61,6 +66,9 @@ public class HorizontalContent implements Serializable { if (StringUtils.isNotBlank(this.getMedia_id())) { hContentJson.addProperty("media_id", this.getMedia_id()); } + if (StringUtils.isNotBlank(this.getUserid())) { + hContentJson.addProperty("userid", this.getUserid()); + } return hContentJson; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java index afef5193c..dbf78fe73 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java @@ -187,6 +187,7 @@ public interface WxCpApiPathConsts { interface TaskCard { String UPDATE_TASK_CARD = "/cgi-bin/message/update_taskcard"; + String UPDATE_TEMPLATE_CARD = "/cgi-bin/message/update_template_card"; } interface Tp { diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpMessageTest.java index c8a367614..06c895d25 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpMessageTest.java @@ -166,6 +166,12 @@ public class WxCpMessageTest { .value("企业微信.apk") .media_id("文件的media_id") .build(); + HorizontalContent hContent4 = HorizontalContent.builder() + .type(3) + .keyname("员工信息") + .value("点击查看") + .userid("zhangsan") + .build(); TemplateCardJump jump1 = TemplateCardJump.builder() .type(1) @@ -178,7 +184,7 @@ public class WxCpMessageTest { .appid("小程序的appid") .pagepath("/index.html") .build(); - QuoteArea quoteArea=QuoteArea.builder() + QuoteArea quoteArea = QuoteArea.builder() .type(1) .title("引用文献标题") .appid("小程序的appid") @@ -186,17 +192,31 @@ public class WxCpMessageTest { .url("https://work.weixin.qq.com") .quoteText("引用文献样式的引用文案") .build(); + ActionMenuItem action1 = ActionMenuItem.builder() + .text("接受推送") + .key("A") + .build(); + ActionMenuItem action2 = ActionMenuItem.builder() + .text("不再推送") + .key("B") + .build(); WxCpMessage reply = WxCpMessage.TEMPLATECARD().toUser("OPENID") + .toParty("PartyID1 | PartyID2") + .toTag("TagID1 | TagID2") .agentId(1000002) .cardType(WxConsts.TemplateCardType.TEXT_NOTICE) + .taskId("task_id") .sourceIconUrl("图片的url") .sourceDesc("企业微信") + .sourceDescColor(1) + .actionMenuDesc("卡片副交互辅助文本说明") + .actionMenuActionList(Arrays.asList(action1, action2)) .mainTitleTitle("欢迎使用企业微信") .mainTitleDesc("您的好友正在邀请您加入企业微信") .emphasisContentTitle("100") .emphasisContentDesc("核心数据") .subTitleText("下载企业微信还能抢红包!") - .horizontalContents(Arrays.asList(hContent1,hContent2,hContent3)) + .horizontalContents(Arrays.asList(hContent1, hContent2, hContent3, hContent4)) .jumps(Arrays.asList(jump1,jump2)) .cardActionType(2) .cardActionAppid("小程序的appid") @@ -209,8 +229,7 @@ public class WxCpMessageTest { reply.setDuplicateCheckInterval(1800); // System.out.println(reply.toJson()); assertThat(reply.toJson()) - .isEqualTo("{\"agentid\":1000002,\"touser\":\"OPENID\",\"msgtype\":\"template_card\",\"duplicate_check_interval\":1800,\"template_card\":{\"card_type\":\"text_notice\",\"source\":{\"icon_url\":\"图片的url\",\"desc\":\"企业微信\"},\"main_title\":{\"title\":\"欢迎使用企业微信\",\"desc\":\"您的好友正在邀请您加入企业微信\"},\"emphasis_content\":{\"title\":\"100\",\"desc\":\"核心数据\"},\"sub_title_text\":\"下载企业微信还能抢红包!\",\"horizontal_content_list\":[{\"keyname\":\"邀请人\",\"value\":\"张三\"},{\"type\":1,\"keyname\":\"企业微信官网\",\"value\":\"点击访问\",\"url\":\"https://work.weixin.qq.com\"},{\"type\":2,\"keyname\":\"企业微信下载\",\"value\":\"企业微信.apk\",\"media_id\":\"文件的media_id\"}],\"jump_list\":[{\"type\":1,\"title\":\"企业微信官网\",\"url\":\"https://work.weixin.qq.com\"},{\"type\":2,\"title\":\"跳转小程序\",\"appid\":\"小程序的appid\",\"pagepath\":\"/index.html\"}],\"card_action\":{\"type\":2,\"url\":\"https://work.weixin.qq.com\",\"appid\":\"小程序的appid\",\"pagepath\":\"/index.html\"},\"quote_area\":{\"type\":1,\"url\":\"https://work.weixin.qq.com\",\"appid\":\"小程序的appid\",\"pagepath\":\"/index.html\",\"title\":\"引用文献标题\",\"quote_text\":\"引用文献样式的引用文案\"}}}"); - + .isEqualTo("{\"agentid\":1000002,\"touser\":\"OPENID\",\"msgtype\":\"template_card\",\"toparty\":\"PartyID1 | PartyID2\",\"totag\":\"TagID1 | TagID2\",\"duplicate_check_interval\":1800,\"template_card\":{\"card_type\":\"text_notice\",\"source\":{\"icon_url\":\"图片的url\",\"desc\":\"企业微信\",\"desc_color\":1},\"action_menu\":{\"desc\":\"卡片副交互辅助文本说明\",\"action_list\":[{\"text\":\"接受推送\",\"key\":\"A\"},{\"text\":\"不再推送\",\"key\":\"B\"}]},\"main_title\":{\"title\":\"欢迎使用企业微信\",\"desc\":\"您的好友正在邀请您加入企业微信\"},\"emphasis_content\":{\"title\":\"100\",\"desc\":\"核心数据\"},\"sub_title_text\":\"下载企业微信还能抢红包!\",\"task_id\":\"task_id\",\"horizontal_content_list\":[{\"keyname\":\"邀请人\",\"value\":\"张三\"},{\"type\":1,\"keyname\":\"企业微信官网\",\"value\":\"点击访问\",\"url\":\"https://work.weixin.qq.com\"},{\"type\":2,\"keyname\":\"企业微信下载\",\"value\":\"企业微信.apk\",\"media_id\":\"文件的media_id\"},{\"type\":3,\"keyname\":\"员工信息\",\"value\":\"点击查看\",\"userid\":\"zhangsan\"}],\"jump_list\":[{\"type\":1,\"title\":\"企业微信官网\",\"url\":\"https://work.weixin.qq.com\"},{\"type\":2,\"title\":\"跳转小程序\",\"appid\":\"小程序的appid\",\"pagepath\":\"/index.html\"}],\"card_action\":{\"type\":2,\"url\":\"https://work.weixin.qq.com\",\"appid\":\"小程序的appid\",\"pagepath\":\"/index.html\"},\"quote_area\":{\"type\":1,\"url\":\"https://work.weixin.qq.com\",\"appid\":\"小程序的appid\",\"pagepath\":\"/index.html\",\"title\":\"引用文献标题\",\"quote_text\":\"引用文献样式的引用文案\"}}}"); } /** @@ -404,13 +423,13 @@ public class WxCpMessageTest { .question_key("question_key1") .title("选择器标签1") .selected_id("selection_id1") - .options(Arrays.asList(option1,option2)) + .options(Arrays.asList(option1, option2)) .build(); MultipleSelect mSelect2 = MultipleSelect.builder() .question_key("question_key2") .title("选择器标签2") .selected_id("selection_id3") - .options(Arrays.asList(option3,option4)) + .options(Arrays.asList(option3, option4)) .build();