diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaCalendarService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaCalendarService.java
new file mode 100644
index 000000000..8dc0d3136
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOaCalendarService.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.cp.api;
+
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.bean.oa.calendar.WxCpOaCalendar;
+
+/**
+ * 企业微信日历接口.
+ *
+ * @author Binary Wang
+ * @date 2020-09-20
+ */
+public interface WxCpOaCalendarService {
+ /**
+ * 创建日历.
+ *
+ * 该接口用于通过应用在企业内创建一个日历。
+ * 注: 企业微信需要更新到3.0.2及以上版本
+ * 请求方式: POST(HTTPS)
+ * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/oa/calendar/add?access_token=ACCESS_TOKEN
+ *
+ * 文档地址:https://work.weixin.qq.com/api/doc/90000/90135/92618
+ *
+ *
+ * @param calendar 日历对象
+ * @return 日历ID
+ * @throws WxErrorException .
+ */
+ String add(WxCpOaCalendar calendar) throws WxErrorException;
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
index 3378f8862..465090f19 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
@@ -388,7 +388,14 @@ public interface WxCpService {
*
* @return the oa service
*/
- WxCpOaService getOAService();
+ WxCpOaService getOaService();
+
+ /**
+ * 获取日历相关接口的服务类对象
+ *
+ * @return the menu service
+ */
+ WxCpOaCalendarService getOaCalendarService();
/**
* 获取群机器人消息推送服务
@@ -445,4 +452,5 @@ public interface WxCpService {
* @param tagService the tag service
*/
void setTagService(WxCpTagService tagService);
+
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
index a04f46989..81c577eb9 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
@@ -52,6 +52,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
private WxCpExternalContactService externalContactService = new WxCpExternalContactServiceImpl(this);
private WxCpGroupRobotService groupRobotService = new WxCpGroupRobotServiceImpl(this);
private WxCpMessageService messageService = new WxCpMessageServiceImpl(this);
+ private WxCpOaCalendarService oaCalendarService = new WxCpOaCalendarServiceImpl(this);
/**
* 全局的是否正在刷新access token的锁.
@@ -305,7 +306,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
return null;
} catch (IOException e) {
log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uri, data, e.getMessage());
- throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).errorCode(-1).build(),e);
+ throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).errorCode(-1).build(), e);
}
}
@@ -421,10 +422,15 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
}
@Override
- public WxCpOaService getOAService() {
+ public WxCpOaService getOaService() {
return oaService;
}
+ @Override
+ public WxCpOaCalendarService getOaCalendarService() {
+ return this.oaCalendarService;
+ }
+
@Override
public WxCpGroupRobotService getGroupRobotService() {
return groupRobotService;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaCalendarServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaCalendarServiceImpl.java
new file mode 100644
index 000000000..c5b0a4aac
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaCalendarServiceImpl.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.cp.api.impl;
+
+import lombok.RequiredArgsConstructor;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.api.WxCpOaCalendarService;
+import me.chanjar.weixin.cp.api.WxCpService;
+import me.chanjar.weixin.cp.bean.oa.calendar.WxCpOaCalendar;
+
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Oa.CALENDAR_ADD;
+
+/**
+ * .
+ *
+ * @author Binary Wang
+ * @date 2020-09-20
+ */
+@RequiredArgsConstructor
+public class WxCpOaCalendarServiceImpl implements WxCpOaCalendarService {
+ private final WxCpService wxCpService;
+
+ @Override
+ public String add(WxCpOaCalendar calendar) throws WxErrorException {
+ return this.wxCpService.post(this.wxCpService.getWxCpConfigStorage().getApiUrl(CALENDAR_ADD),calendar.toJson());
+ }
+}
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 a035f1d54..42f25add3 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
@@ -294,6 +294,20 @@ public class WxCpXmlMessage implements Serializable {
@XStreamConverter(value = XStreamCDataConverter.class)
private String address;
+ /**
+ * 日程ID.
+ */
+ @XStreamAlias("ScheduleId")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ private String scheduleId;
+
+ /**
+ * 日历ID.
+ */
+ @XStreamAlias("CalId")
+ @XStreamConverter(value = XStreamCDataConverter.class)
+ private String calId;
+
/**
* 扩展属性.
*/
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/calendar/WxCpOaCalendar.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/calendar/WxCpOaCalendar.java
new file mode 100644
index 000000000..d4d9fd7f7
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/calendar/WxCpOaCalendar.java
@@ -0,0 +1,105 @@
+package me.chanjar.weixin.cp.bean.oa.calendar;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.gson.annotations.SerializedName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 日历.
+ *
+ * @author Binary Wang
+ * @date 2020-09-20
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Accessors(chain = true)
+public class WxCpOaCalendar implements Serializable {
+ private static final long serialVersionUID = -817988838579546989L;
+
+ /**
+ * 变量名:organizer
+ * 是否必须:是
+ * 描述:指定的组织者userid。注意该字段指定后不可更新
+ */
+ @SerializedName("organizer")
+ private String organizer;
+
+ /**
+ * 变量名:readonly
+ * 是否必须:否
+ * 描述:日历组织者对日历是否只读权限(即不可编辑日历,不可在日历上添加日程,仅可作为组织者删除日历)。0-否;1-是。默认为1,即只读
+ */
+ @SerializedName("readonly")
+ private Integer readonly;
+
+ /**
+ * 变量名:set_as_default
+ * 是否必须:否
+ * 描述:是否将该日历设置为组织者的默认日历。0-否;1-是。默认为0,即不设为默认日历
+ */
+ @SerializedName("set_as_default")
+ private Integer setAsDefault;
+
+ /**
+ * 变量名:summary
+ * 是否必须:是
+ * 描述:日历标题。1 ~ 128 字符
+ */
+ @SerializedName("summary")
+ private String summary;
+
+ /**
+ * 变量名:color
+ * 是否必须:是
+ * 描述:日历在终端上显示的颜色,RGB颜色编码16进制表示,例如:”#0000FF” 表示纯蓝色
+ */
+ @SerializedName("color")
+ private String color;
+
+ /**
+ * 变量名:description
+ * 是否必须:否
+ * 描述:日历描述。0 ~ 512 字符
+ */
+ @SerializedName("description")
+ private String description;
+
+ /**
+ * 变量名:shares
+ * 是否必须:否
+ * 描述:日历共享成员列表。最多2000人
+ */
+ @SerializedName("shares")
+ private List shares;
+
+ @Data
+ @AllArgsConstructor
+ public static class ShareInfo implements Serializable {
+ private static final long serialVersionUID = -4882781114860754679L;
+
+ /**
+ * 日历共享成员的id
+ */
+ private String userid;
+
+ /**
+ * 共享成员对日历是否只读权限(即不可编辑日历,不可在日历上添加日程,仅可以退出日历)。
+ * 0-否;1-是。默认为1,即只读
+ */
+ private Integer readonly;
+ }
+
+ public String toJson() {
+ return WxCpGsonBuilder.create().toJson(ImmutableMap.of("calendar",this));
+ }
+}
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 6e5e52a14..66132553b 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
@@ -101,6 +101,11 @@ public final class WxCpApiPathConsts {
public static final String GET_DIAL_RECORD = "/cgi-bin/dial/get_dial_record";
public static final String GET_TEMPLATE_DETAIL = "/cgi-bin/oa/gettemplatedetail";
public static final String APPLY_EVENT = "/cgi-bin/oa/applyevent";
+
+ public static final String CALENDAR_ADD = "/cgi-bin/oa/calendar/add";
+ public static final String CALENDAR_UPDATE = "/cgi-bin/oa/calendar/update";
+ public static final String CALENDAR_GET = "/cgi-bin/oa/calendar/get";
+ public static final String CALENDAR_DEL = "/cgi-bin/oa/calendar/del";
}
@UtilityClass
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 98bfd90ba..6e8fbb468 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
@@ -103,6 +103,30 @@ public class WxCpConsts {
*/
public static final String OPEN_APPROVAL_CHANGE = "open_approval_change";
+ /**
+ * 修改日历事件
+ */
+ public static final String MODIFY_CALENDAR = "modify_calendar";
+
+ /**
+ * 删除日历事件
+ */
+ public static final String DELETE_CALENDAR = "delete_calendar";
+
+ /**
+ * 添加日程事件
+ */
+ public static final String ADD_SCHEDULE = "add_schedule";
+
+ /**
+ * 修改日程事件
+ */
+ public static final String MODIFY_SCHEDULE = "modify_schedule";
+
+ /**
+ * 删除日程事件
+ */
+ public static final String DELETE_SCHEDULE = "delete_schedule";
}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaCalendarServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaCalendarServiceImplTest.java
new file mode 100644
index 000000000..905dc4995
--- /dev/null
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaCalendarServiceImplTest.java
@@ -0,0 +1,39 @@
+package me.chanjar.weixin.cp.api.impl;
+
+import com.google.inject.Inject;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.api.ApiTestModule;
+import me.chanjar.weixin.cp.api.WxCpService;
+import me.chanjar.weixin.cp.bean.oa.calendar.WxCpOaCalendar;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+
+/**
+ * 单元测试.
+ *
+ * @author Binary Wang
+ * @date 2020-09-20
+ */
+
+@Test
+@Guice(modules = ApiTestModule.class)
+public class WxCpOaCalendarServiceImplTest {
+ @Inject
+ protected WxCpService wxService;
+
+ @Test
+ public void testAdd() throws WxErrorException {
+ this.wxService.getOaCalendarService().add(WxCpOaCalendar.builder()
+ .organizer("userid1")
+ .readonly(1)
+ .setAsDefault(1)
+ .summary("test_summary")
+ .color("#FF3030")
+ .description("test_describe")
+ .shares(Arrays.asList(new WxCpOaCalendar.ShareInfo("userid2", null),
+ new WxCpOaCalendar.ShareInfo("userid3", 1)))
+ .build());
+ }
+}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImplTest.java
index 6f3a76b0a..758f77970 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImplTest.java
@@ -37,7 +37,7 @@ public class WxCpOaServiceImplTest {
Date startTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-04-11");
Date endTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-05-10");
- List results = wxService.getOAService()
+ List results = wxService.getOaService()
.getCheckinData(1, startTime, endTime, Lists.newArrayList("binary"));
assertThat(results).isNotNull();
@@ -51,7 +51,7 @@ public class WxCpOaServiceImplTest {
public void testGetCheckinOption() throws WxErrorException {
Date now = new Date();
- List results = wxService.getOAService().getCheckinOption(now, Lists.newArrayList("binary"));
+ List results = wxService.getOaService().getCheckinOption(now, Lists.newArrayList("binary"));
assertThat(results).isNotNull();
System.out.println("results ");
System.out.println(gson.toJson(results));
@@ -61,7 +61,7 @@ public class WxCpOaServiceImplTest {
public void testGetApprovalInfo() throws WxErrorException, ParseException {
Date startTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-12-01");
Date endTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-12-31");
- WxCpApprovalInfo result = wxService.getOAService().getApprovalInfo(startTime, endTime);
+ WxCpApprovalInfo result = wxService.getOaService().getApprovalInfo(startTime, endTime);
assertThat(result).isNotNull();
@@ -72,7 +72,7 @@ public class WxCpOaServiceImplTest {
@Test
public void testGetApprovalDetail() throws WxErrorException {
String spNo = "201912020001";
- WxCpApprovalDetailResult result = wxService.getOAService().getApprovalDetail(spNo);
+ WxCpApprovalDetailResult result = wxService.getOaService().getApprovalDetail(spNo);
assertThat(result).isNotNull();
@@ -83,7 +83,7 @@ public class WxCpOaServiceImplTest {
@Test
public void testGetTemplateDetail() throws WxErrorException {
String templateId = "3TkZjxugodbqpEMk9j7X6h6zKqYkc7MxQrrFmT7H";
- WxCpTemplateResult result = wxService.getOAService().getTemplateDetail(templateId);
+ WxCpTemplateResult result = wxService.getOaService().getTemplateDetail(templateId);
assertThat(result).isNotNull();
System.out.println("result ");
System.out.println(gson.toJson(result));
@@ -91,7 +91,7 @@ public class WxCpOaServiceImplTest {
@Test
public void testApply() throws WxErrorException {
- this.wxService.getOAService().apply(new WxCpOaApplyEventRequest().setCreatorUserId("123"));
+ this.wxService.getOaService().apply(new WxCpOaApplyEventRequest().setCreatorUserId("123"));
}
@Test
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/oa/calendar/WxCpOaCalendarTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/oa/calendar/WxCpOaCalendarTest.java
new file mode 100644
index 000000000..761b0f8f9
--- /dev/null
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/oa/calendar/WxCpOaCalendarTest.java
@@ -0,0 +1,52 @@
+package me.chanjar.weixin.cp.bean.oa.calendar;
+
+import me.chanjar.weixin.common.util.json.GsonParser;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * 单元测试.
+ *
+ * @author Binary Wang
+ * @date 2020-09-20
+ */
+public class WxCpOaCalendarTest {
+
+ @Test
+ public void testToJson() {
+ String json = "{\n" +
+ " \"calendar\" : {\n" +
+ " \"organizer\" : \"userid1\",\n" +
+ " \"readonly\" : 1,\n" +
+ " \"set_as_default\" : 1,\n" +
+ " \"summary\" : \"test_summary\",\n" +
+ " \"color\" : \"#FF3030\",\n" +
+ " \"description\" : \"test_describe\",\n" +
+ " \"shares\" : [\n" +
+ " {\n" +
+ " \"userid\" : \"userid2\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"userid\" : \"userid3\",\n" +
+ " \"readonly\" : 1\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ "}\n";
+
+ assertThat(WxCpOaCalendar.builder()
+ .organizer("userid1")
+ .readonly(1)
+ .setAsDefault(1)
+ .summary("test_summary")
+ .color("#FF3030")
+ .description("test_describe")
+ .shares(Arrays.asList(new WxCpOaCalendar.ShareInfo("userid2", null),
+ new WxCpOaCalendar.ShareInfo("userid3", 1)))
+ .build().toJson())
+ .isEqualTo(GsonParser.parse(json).toString());
+ }
+}