From 8f301500efb06e8b44267811370bd43e76fb6609 Mon Sep 17 00:00:00 2001 From: 0katekate0 <32161300+0katekate0@users.noreply.github.com> Date: Thu, 21 Jul 2022 15:29:01 +0800 Subject: [PATCH] =?UTF-8?q?:art:=20=E4=BF=AE=E5=A4=8D=E5=AE=B6=E6=A0=A1?= =?UTF-8?q?=E6=B2=9F=E9=80=9A=E9=83=A8=E5=88=86=E6=8E=A5=E5=8F=A3=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cp/bean/message/WxCpXmlApprovalInfo.java | 214 ++++++++++++++++++ .../cp/bean/message/WxCpXmlMessage.java | 9 + .../cp/bean/school/user/WxCpAllowScope.java | 19 +- .../weixin/cp/constant/WxCpConsts.java | 1 + .../cp/util/xml/XStreamTransformer.java | 10 +- .../weixin/cp/api/WxCpOaAgentTest.java | 148 ++++++++++++ .../message/WxCpSchoolContactMessageTest.java | 39 +++- 7 files changed, 425 insertions(+), 15 deletions(-) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlApprovalInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlApprovalInfo.java index 5035390db..33d1375b1 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlApprovalInfo.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlApprovalInfo.java @@ -12,6 +12,12 @@ import java.util.List; /** * 审批信息 * + * 审批申请状态变化回调通知 + * https://developer.work.weixin.qq.com/document/path/91815 + * + * 自建应用审批状态变化通知回调 + * https://developer.work.weixin.qq.com/document/path/90269 + * * @author Gyv12345 */ @XStreamAlias("ApprovalInfo") @@ -19,6 +25,212 @@ import java.util.List; public class WxCpXmlApprovalInfo implements Serializable { private static final long serialVersionUID = 8136329462880646091L; + + // 自建应用审批状态变化通知回调 + /** + * 审批单编号,由开发者在发起申请时自定义 + */ + @XStreamAlias("ThirdNo") + @XStreamConverter(value = XStreamCDataConverter.class) + private String thirdNo; + + /** + * 审批模板名称 + */ + @XStreamAlias("OpenSpName") + @XStreamConverter(value = XStreamCDataConverter.class) + private String openSpName; + + /** + * 审批模板id + */ + @XStreamAlias("OpenTemplateId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String openTemplateId; + + /** + * 申请单当前审批状态:1-审批中;2-已通过;3-已驳回;4-已撤销 + */ + @XStreamAlias("OpenSpStatus") + private Integer openSpStatus; + + /** + * 提交者姓名 + */ + @XStreamAlias("ApplyUserName") + @XStreamConverter(value = XStreamCDataConverter.class) + private String applyUserName; + + /** + * 提交者userid + */ + @XStreamAlias("ApplyUserId") + @XStreamConverter(value = XStreamCDataConverter.class) + private String applyUserId; + + /** + * 提交者所在部门 + */ + @XStreamAlias("ApplyUserParty") + @XStreamConverter(value = XStreamCDataConverter.class) + private String applyUserParty; + + /** + * 提交者头像 + */ + @XStreamAlias("ApplyUserImage") + @XStreamConverter(value = XStreamCDataConverter.class) + private String applyUserImage; + + /** + * 当前审批节点:0-第一个审批节点;1-第二个审批节点…以此类推 + */ + @XStreamAlias("ApproverStep") + private Integer approverStep; + + /** + * 审批流程信息 + */ + @XStreamImplicit(itemFieldName = "ApprovalNodes") + private List approvalNodes; + + /** + * 抄送信息,可能有多个抄送人 + */ + @XStreamImplicit(itemFieldName = "NotifyNodes") + private List notifyNodes; + + /** + * 抄送人信息 + */ + @XStreamAlias("NotifyNodes") + @Data + public static class NotifyNode implements Serializable { + private static final long serialVersionUID = -979255011922209018L; + + /** + * 抄送人姓名 + */ + @XStreamAlias("ItemName") + @XStreamConverter(value = XStreamCDataConverter.class) + private String itemName; + + /** + * 抄送人userid + */ + @XStreamAlias("ItemUserid") + @XStreamConverter(value = XStreamCDataConverter.class) + private String itemUserId; + + /** + * 抄送人所在部门 + */ + @XStreamAlias("ItemParty") + @XStreamConverter(value = XStreamCDataConverter.class) + private String itemParty; + + /** + * 抄送人头像 + */ + @XStreamAlias("ItemImage") + @XStreamConverter(value = XStreamCDataConverter.class) + private String itemImage; + + } + + /** + * 审批流程信息,可以有多个审批节点 + */ + @XStreamAlias("ApprovalNodes") + @Data + public static class ApprovalNode implements Serializable { + private static final long serialVersionUID = -979255011922209018L; + + /** + * 节点审批操作状态:1-审批中;2-已同意;3-已驳回;4-已转审 + */ + @XStreamAlias("NodeStatus") + private Integer nodeStatus; + + /** + * 审批节点属性:1-或签;2-会签 + */ + @XStreamAlias("NodeAttr") + private Integer nodeAttr; + + /** + * 审批节点类型:1-固定成员;2-标签;3-上级 + */ + @XStreamAlias("NodeType") + private Integer nodeType; + + /** + * 审批节点信息,当节点为标签或上级时,一个节点可能有多个分支 + */ + @XStreamImplicit(itemFieldName = "Items") + private List items; + + } + + /** + * 审批节点分支,当节点为标签或上级时,一个节点可能有多个分支 + */ + @XStreamAlias("Items") + @Data + public static class Item implements Serializable { + private static final long serialVersionUID = -979255011922209018L; + + /** + * 分支审批人姓名 + */ + @XStreamAlias("ItemName") + @XStreamConverter(value = XStreamCDataConverter.class) + private String itemName; + + /** + * 分支审批人userid + */ + @XStreamAlias("ItemUserid") + @XStreamConverter(value = XStreamCDataConverter.class) + private String itemUserId; + + /** + * 分支审批人所在部门 + */ + @XStreamAlias("ItemParty") + @XStreamConverter(value = XStreamCDataConverter.class) + private String itemParty; + + /** + * 分支审批人头像 + */ + @XStreamAlias("ItemImage") + @XStreamConverter(value = XStreamCDataConverter.class) + private String itemImage; + + /** + * 分支审批人审批意见 + */ + @XStreamAlias("ItemSpeech") + @XStreamConverter(value = XStreamCDataConverter.class) + private String itemSpeech; + + /** + * 分支审批审批操作状态:1-审批中;2-已同意;3-已驳回;4-已转审 + */ + @XStreamAlias("ItemStatus") + private Integer itemStatus; + + /** + * 分支审批人操作时间 + */ + @XStreamAlias("ItemOpTime") + private Long itemOpTime; + + } + + + // 审批申请状态变化回调通知 /** * 审批编号 */ @@ -44,6 +256,7 @@ public class WxCpXmlApprovalInfo implements Serializable { @XStreamAlias("TemplateId") @XStreamConverter(value = XStreamCDataConverter.class) private String templateId; + /** * 审批申请提交时间,Unix时间戳 */ @@ -249,4 +462,5 @@ public class WxCpXmlApprovalInfo implements Serializable { @XStreamAlias("UserId") private String userId; } + } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlMessage.java index bb7025edf..68dbc6987 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpXmlMessage.java @@ -474,6 +474,15 @@ public class WxCpXmlMessage implements Serializable { private SendLocationInfo sendLocationInfo = new SendLocationInfo(); + /** + * 审批消息 + * + * 审批申请状态变化回调通知 + * https://developer.work.weixin.qq.com/document/path/91815 + * + * 自建应用审批状态变化通知回调 + * https://developer.work.weixin.qq.com/document/path/90269 + */ @XStreamAlias("ApprovalInfo") private WxCpXmlApprovalInfo approvalInfo = new WxCpXmlApprovalInfo(); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/user/WxCpAllowScope.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/user/WxCpAllowScope.java index b5a594e19..902cc4adc 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/user/WxCpAllowScope.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/user/WxCpAllowScope.java @@ -30,7 +30,7 @@ public class WxCpAllowScope extends WxCpBaseResp implements Serializable { private List students; @SerializedName("departments") - private List departments; + private Department departments; public static AllowScope fromJson(String json) { return WxCpGsonBuilder.create().fromJson(json, AllowScope.class); @@ -42,6 +42,23 @@ public class WxCpAllowScope extends WxCpBaseResp implements Serializable { } + @Setter + @Getter + public static class Department implements Serializable { + + @SerializedName("partyid") + private List partyId; + + public static Department fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, Department.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + } + @Setter @Getter public static class Student implements Serializable { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java index 51219328a..b422c9d23 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java @@ -110,6 +110,7 @@ public class WxCpConsts { /** * 企业微信审批事件推送(自建应用审批) + * https://developer.work.weixin.qq.com/document/path/90269 */ public static final String OPEN_APPROVAL_CHANGE = "open_approval_change"; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java index 62ea5072e..2fb09ce4c 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java @@ -1,14 +1,14 @@ package me.chanjar.weixin.cp.util.xml; +import com.thoughtworks.xstream.XStream; +import me.chanjar.weixin.common.util.xml.XStreamInitializer; +import me.chanjar.weixin.cp.bean.WxCpTpXmlPackage; +import me.chanjar.weixin.cp.bean.message.*; + import java.io.InputStream; import java.util.HashMap; import java.util.Map; -import com.thoughtworks.xstream.XStream; -import me.chanjar.weixin.common.util.xml.XStreamInitializer; -import me.chanjar.weixin.cp.bean.message.*; -import me.chanjar.weixin.cp.bean.WxCpTpXmlPackage; - public class XStreamTransformer { protected static final Map CLASS_2_XSTREAM_INSTANCE = configXStreamInstance(); diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpOaAgentTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpOaAgentTest.java index 88d990e4f..94169e416 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpOaAgentTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpOaAgentTest.java @@ -3,12 +3,17 @@ package me.chanjar.weixin.cp.api; import com.google.gson.reflect.TypeToken; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.XmlUtils; import me.chanjar.weixin.common.util.json.GsonParser; import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; import me.chanjar.weixin.cp.bean.oa.selfagent.WxCpOpenApprovalData; import me.chanjar.weixin.cp.config.WxCpConfigStorage; +import me.chanjar.weixin.cp.constant.WxCpConsts; import me.chanjar.weixin.cp.demo.WxCpDemoInMemoryConfigStorage; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; +import me.chanjar.weixin.cp.util.xml.XStreamTransformer; +import org.eclipse.jetty.util.ajax.JSON; import org.testng.annotations.Test; import java.io.InputStream; @@ -16,6 +21,7 @@ import java.io.InputStream; /** * 企业微信自建应用接口测试类. * https://developer.work.weixin.qq.com/document/path/90269 + * https://developer.work.weixin.qq.com/document/path/90240#%E5%AE%A1%E6%89%B9%E7%8A%B6%E6%80%81%E9%80%9A%E7%9F%A5%E4%BA%8B%E4%BB%B6 * * @author Wang_Wong * @date 2022-04-06 @@ -37,6 +43,148 @@ public class WxCpOaAgentTest { cpService = new WxCpServiceImpl(); cpService.setWxCpConfigStorage(config); + + /** + * 测试 审批状态通知事件 + */ + String testXml2 = "\n" + + " \n" + + " \n" + + " 1527838022\n" + + " \n" + + " \n" + + " 1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " 1527837645\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " 1\n" + + " 1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " \n" + + " 0\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 0\n" + + " \n" + + "\n"; + final WxCpXmlMessage mess2 = XStreamTransformer.fromXml(WxCpXmlMessage.class, testXml2); + mess2.setAllFieldsMap(XmlUtils.xml2Map(testXml2)); + log.info("xmlJson: {}", JSON.toString(mess2)); + + + /** + * 测试 弹出微信相册发图器的事件推送 + * + * https://developer.work.weixin.qq.com/document/path/90240 + */ + String testXml = "\n" + + "\t\n" + + "\t\n" + + "\t1408090816\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t1\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t\n" + + "\t1\n" + + "\n"; + + final WxCpXmlMessage mess = XStreamTransformer.fromXml(WxCpXmlMessage.class, testXml); + mess.setAllFieldsMap(XmlUtils.xml2Map(testXml)); + log.info("xmlJson: {}", JSON.toString(mess)); + + + /** + * 审批流程引擎 + * 自建应用审批状态变化通知回调 + * + * https://developer.work.weixin.qq.com/document/path/90269 + */ + String approvalInfoXml = "\n" + + " wwd08c8e7c775abaaa \n" + + " sys \n" + + " 1527838022 \n" + + " event \n" + + " open_approval_change\n" + + " 1\n" + + " \n" + + " thirdNoxxx \n" + + " 付款 \n" + + " 1234567111 \n" + + " 1 \n" + + " 1527837645 \n" + + " jackiejjwu \n" + + " WuJunJie \n" + + " 产品部 \n" + + " http://www.qq.com/xxx.png \n" + + " \n" + + " \n" + + " 1 \n" + + " 1 \n" + + " 1 \n" + + " \n" + + " \n" + + " chauvetxiao \n" + + " XiaoWen \n" + + " 产品部 \n" + + " http://www.qq.com/xxx.png \n" + + " 1 \n" + + " \n" + + " 0 \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " jinhuiguo \n" + + " GuoJinHui \n" + + " 行政部 \n" + + " http://www.qq.com/xxx.png \n" + + " \n" + + " \n" + + " 0 \n" + + " \n" + + "\n"; + + final WxCpXmlMessage msg = XStreamTransformer.fromXml(WxCpXmlMessage.class, approvalInfoXml); + msg.setAllFieldsMap(XmlUtils.xml2Map(approvalInfoXml)); + log.info("xmlJson: {}", JSON.toString(msg)); + + /** + * 增加 + * 自建应用审批状态变化通知回调类型 + */ + String openApprovalChange = WxCpConsts.EventType.OPEN_APPROVAL_CHANGE; + + /** * Test */ diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpSchoolContactMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpSchoolContactMessageTest.java index aa1236c58..85b734034 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpSchoolContactMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpSchoolContactMessageTest.java @@ -9,11 +9,16 @@ import me.chanjar.weixin.cp.api.WxCpService; import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; import me.chanjar.weixin.cp.bean.article.MpnewsArticle; import me.chanjar.weixin.cp.bean.article.NewArticle; +import me.chanjar.weixin.cp.bean.school.user.WxCpAllowScope; +import me.chanjar.weixin.cp.bean.school.user.WxCpListParentResult; +import me.chanjar.weixin.cp.bean.school.user.WxCpUserListResult; import me.chanjar.weixin.cp.config.WxCpConfigStorage; import me.chanjar.weixin.cp.demo.WxCpDemoInMemoryConfigStorage; import org.testng.annotations.Test; import java.io.InputStream; +import java.util.List; +import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; @@ -52,20 +57,36 @@ public class WxCpSchoolContactMessageTest { cpService = new WxCpServiceImpl(); cpService.setWxCpConfigStorage(config); + // 获取可使用的家长范围 返回的数据 + WxCpAllowScope allowScope = cpService.getSchoolUserService().getAllowScope(1000002); + + WxCpUserListResult userList = cpService.getSchoolUserService().getUserList(1, 1); + + // 测试发送给家长 [学校通知] + WxCpListParentResult userListParent = cpService.getSchoolUserService().getUserListParent(1); + List collect = userListParent.getParents() + .stream() + .filter(parent -> parent.getMobile().equals("13079226621")) + .collect(Collectors.toList()); + + String[] parentsId = {"ab0b1691d0204d4900f6b7a7e5a6aa8f", collect.get(0).getParentUserId()}; + WxCpSchoolContactMessageSendResult sendResult = this.cpService.getMessageService().sendSchoolContactMessage( WxCpSchoolContactMessage.builder() .recvScope(0) - .msgType(WxConsts.SchoolContactMsgType.TEXT) - .toParentUserId(new String[]{"parent_userid1", "parent_userid2"}) - .toStudentUserId(new String[]{"student_userid1", "student_userid2"}) - .toParty(new String[]{"partyid1", "partyid2"}) + .msgType(WxConsts.SchoolContactMsgType.NEWS) + .toParentUserId(parentsId) +// .toStudentUserId(new String[]{"student_userid1", "student_userid2"}) +// .toParty(new String[]{"partyid1", "partyid2"}) .toAll(false) - .agentId(1) - .content("你的快递已到,请携带工卡前往邮件中心领取。\n出发前可查看邮件中心视频实况,聪明避开排队。") - .enableIdTrans(false) - .enableDuplicateCheck(false) - .duplicateCheckInterval(1800) + .agentId(cpService.getWxCpConfigStorage().getAgentId()) + .articles(Lists.newArrayList(NewArticle.builder() + .title("这是接口测试标题") + .description("今年中秋节公司有豪礼相送哦") + .url("https://www.baidu.com/") + .picUrl("http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png") + .build())) .build() );