diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpSchoolHealthService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpSchoolHealthService.java
new file mode 100644
index 000000000..0d852e74b
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpSchoolHealthService.java
@@ -0,0 +1,57 @@
+package me.chanjar.weixin.cp.api;
+
+import lombok.NonNull;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.bean.school.health.WxCpGetHealthReportStat;
+import me.chanjar.weixin.cp.bean.school.health.WxCpGetReportJobIds;
+import me.chanjar.weixin.cp.bean.school.health.WxCpGetReportJobInfo;
+
+/**
+ * 企业微信家校应用 健康上报接口.
+ * https://developer.work.weixin.qq.com/document/path/93676
+ *
+ * @author Wang_Wong
+ * @date: 2022/5/31 9:10
+ */
+public interface WxCpSchoolHealthService {
+
+ /**
+ * 获取健康上报使用统计
+ * 请求方式:POST(HTTPS)
+ * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/health/get_health_report_stat?access_token=ACCESS_TOKEN
+ *
+ * @param date 具体某天的使用统计,最长支持获取30天前数据
+ * @return
+ * @throws WxErrorException
+ */
+ WxCpGetHealthReportStat getHealthReportStat(@NonNull String date) throws WxErrorException;
+
+ /**
+ * 获取健康上报任务ID列表
+ * 通过此接口可以获取企业当前正在运行的上报任务ID列表。
+ *
+ * 请求方式:POST(HTTPS)
+ * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/health/get_report_jobids?access_token=ACCESS_TOKEN
+ *
+ * @param offset 否 分页,偏移量, 默认为0
+ * @param limit 否 分页,预期请求的数据量,默认为100,取值范围 1 ~ 100
+ * @return
+ * @throws WxErrorException
+ */
+ WxCpGetReportJobIds getReportJobIds(Integer offset, Integer limit) throws WxErrorException;
+
+ /**
+ * 获取健康上报任务详情
+ * 通过此接口可以获取指定的健康上报任务详情。
+ *
+ * 请求方式:POST(HTTPS)
+ * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/health/get_report_job_info?access_token=ACCESS_TOKEN
+ *
+ * @param jobId 是 任务ID
+ * @param date 是 具体某天任务详情,仅支持获取最近14天数据
+ * @return
+ * @throws WxErrorException
+ */
+ WxCpGetReportJobInfo getReportJobInfo(@NonNull String jobId, @NonNull String date) 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 769ef0d2e..00be57b10 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
@@ -400,6 +400,13 @@ public interface WxCpService extends WxService {
*/
WxCpOaService getOaService();
+ /**
+ * 获取家校应用健康上报的服务类对象
+ *
+ * @return
+ */
+ WxCpSchoolHealthService getSchoolHealthService();
+
/**
* 获取直播相关接口的服务类对象
*
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 6de02c3e2..890253b11 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
@@ -49,6 +49,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
private WxCpTagService tagService = new WxCpTagServiceImpl(this);
private WxCpAgentService agentService = new WxCpAgentServiceImpl(this);
private WxCpOaService oaService = new WxCpOaServiceImpl(this);
+ private WxCpSchoolHealthService schoolHealthService = new WxCpSchoolHealthServiceImpl(this);
private WxCpLivingService livingService = new WxCpLivingServiceImpl(this);
private WxCpOaAgentService oaAgentService = new WxCpOaAgentServiceImpl(this);
private WxCpOaWeDriveService oaWeDriveService = new WxCpOaWeDriveServiceImpl(this);
@@ -493,6 +494,11 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
return oaService;
}
+ @Override
+ public WxCpSchoolHealthService getSchoolHealthService() {
+ return schoolHealthService;
+ }
+
@Override
public WxCpLivingService getLivingService() {
return livingService;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpSchoolHealthServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpSchoolHealthServiceImpl.java
new file mode 100644
index 000000000..bee4bf030
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpSchoolHealthServiceImpl.java
@@ -0,0 +1,59 @@
+package me.chanjar.weixin.cp.api.impl;
+
+import com.google.gson.JsonObject;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.api.WxCpSchoolHealthService;
+import me.chanjar.weixin.cp.api.WxCpService;
+import me.chanjar.weixin.cp.bean.school.health.WxCpGetHealthReportStat;
+import me.chanjar.weixin.cp.bean.school.health.WxCpGetReportJobIds;
+import me.chanjar.weixin.cp.bean.school.health.WxCpGetReportJobInfo;
+
+import java.util.Optional;
+
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.School.*;
+
+/**
+ * 企业微信家校应用 健康上报接口实现类.
+ *
+ * @author Wang_Wong
+ * @date: 2022/5/31 9:16
+ */
+@Slf4j
+@RequiredArgsConstructor
+public class WxCpSchoolHealthServiceImpl implements WxCpSchoolHealthService {
+
+ private final WxCpService cpService;
+
+ @Override
+ public WxCpGetHealthReportStat getHealthReportStat(@NonNull String date) throws WxErrorException {
+ String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(GET_HEALTH_REPORT_STAT);
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("date", date);
+ String responseContent = this.cpService.post(apiUrl, jsonObject.toString());
+ return WxCpGetHealthReportStat.fromJson(responseContent);
+ }
+
+ @Override
+ public WxCpGetReportJobIds getReportJobIds(Integer offset, Integer limit) throws WxErrorException {
+ String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(GET_REPORT_JOBIDS);
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("offset", Optional.ofNullable(offset).orElse(0));
+ jsonObject.addProperty("limit", Optional.ofNullable(limit).orElse(100));
+ String responseContent = this.cpService.post(apiUrl, jsonObject.toString());
+ return WxCpGetReportJobIds.fromJson(responseContent);
+ }
+
+ @Override
+ public WxCpGetReportJobInfo getReportJobInfo(@NonNull String jobId, @NonNull String date) throws WxErrorException {
+ String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(GET_REPORT_JOB_INFO);
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("jobid", jobId);
+ jsonObject.addProperty("date", date);
+ String responseContent = this.cpService.post(apiUrl, jsonObject.toString());
+ return WxCpGetReportJobInfo.fromJson(responseContent);
+ }
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/health/WxCpGetHealthReportStat.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/health/WxCpGetHealthReportStat.java
new file mode 100644
index 000000000..3bd444832
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/health/WxCpGetHealthReportStat.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.cp.bean.school.health;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.cp.bean.WxCpBaseResp;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+import java.io.Serializable;
+
+/**
+ * 获取健康上报使用统计.
+ *
+ * @author Wang_Wong
+ */
+@Data
+public class WxCpGetHealthReportStat extends WxCpBaseResp implements Serializable {
+ private static final long serialVersionUID = -5028321625142879581L;
+
+ @SerializedName("pv")
+ private Integer pv;
+
+ @SerializedName("uv")
+ private Integer uv;
+
+ public static WxCpGetHealthReportStat fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, WxCpGetHealthReportStat.class);
+ }
+
+ public String toJson() {
+ return WxCpGsonBuilder.create().toJson(this);
+ }
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/health/WxCpGetReportJobIds.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/health/WxCpGetReportJobIds.java
new file mode 100644
index 000000000..768dcec21
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/health/WxCpGetReportJobIds.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.cp.bean.school.health;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.cp.bean.WxCpBaseResp;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 获取健康上报使用统计.
+ *
+ * @author Wang_Wong
+ */
+@Data
+public class WxCpGetReportJobIds extends WxCpBaseResp implements Serializable {
+ private static final long serialVersionUID = -5028321625142879581L;
+
+ @SerializedName("ending")
+ private Integer ending;
+
+ @SerializedName("jobids")
+ private List jobIds;
+
+ public static WxCpGetReportJobIds fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, WxCpGetReportJobIds.class);
+ }
+
+ public String toJson() {
+ return WxCpGsonBuilder.create().toJson(this);
+ }
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/health/WxCpGetReportJobInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/health/WxCpGetReportJobInfo.java
new file mode 100644
index 000000000..5ca603101
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/health/WxCpGetReportJobInfo.java
@@ -0,0 +1,165 @@
+package me.chanjar.weixin.cp.bean.school.health;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+import me.chanjar.weixin.cp.bean.WxCpBaseResp;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 获取健康上报任务详情.
+ *
+ * @author Wang_Wong
+ */
+@Data
+public class WxCpGetReportJobInfo extends WxCpBaseResp implements Serializable {
+ private static final long serialVersionUID = -5028321625142879581L;
+
+ @SerializedName("job_info")
+ private JobInfo jobInfo;
+
+ @Getter
+ @Setter
+ public static class JobInfo implements Serializable {
+ private static final long serialVersionUID = -5696099236344075582L;
+
+ @SerializedName("title")
+ private String title;
+
+ @SerializedName("creator")
+ private String creator;
+
+ @SerializedName("type")
+ private Integer type;
+
+ @SerializedName("report_type")
+ private Integer reportType;
+
+ @SerializedName("skip_weekend")
+ private Integer skipWeekend;
+
+ @SerializedName("finish_cnt")
+ private Integer finishCnt;
+
+ @SerializedName("apply_range")
+ private ApplyRange applyRange;
+
+ @SerializedName("report_to")
+ private ReportTo reportTo;
+
+ @SerializedName("question_templates")
+ private List questionTemplates;
+
+ public static JobInfo fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, JobInfo.class);
+ }
+
+ public String toJson() {
+ return WxCpGsonBuilder.create().toJson(this);
+ }
+
+ }
+
+ @Getter
+ @Setter
+ public static class ApplyRange implements Serializable {
+ private static final long serialVersionUID = -5696099236344075582L;
+
+ @SerializedName("userids")
+ private List userIds;
+
+ @SerializedName("partyids")
+ private List partyIds;
+
+ public static ApplyRange fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, ApplyRange.class);
+ }
+
+ public String toJson() {
+ return WxCpGsonBuilder.create().toJson(this);
+ }
+
+ }
+
+ @Getter
+ @Setter
+ public static class ReportTo implements Serializable {
+ private static final long serialVersionUID = -5696099236344075582L;
+
+ @SerializedName("userids")
+ private List userIds;
+
+ public static ReportTo fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, ReportTo.class);
+ }
+
+ public String toJson() {
+ return WxCpGsonBuilder.create().toJson(this);
+ }
+
+ }
+
+ @Getter
+ @Setter
+ public static class QuestionTemplate implements Serializable {
+ private static final long serialVersionUID = -5696099236344075582L;
+
+ @SerializedName("question_id")
+ private Integer questionId;
+
+ @SerializedName("question_type")
+ private Integer questionType;
+
+ @SerializedName("is_required")
+ private Integer isRequired;
+
+ @SerializedName("title")
+ private String title;
+
+ @SerializedName("option_list")
+ private List optionList;
+
+ public static QuestionTemplate fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, QuestionTemplate.class);
+ }
+
+ public String toJson() {
+ return WxCpGsonBuilder.create().toJson(this);
+ }
+
+ }
+
+ @Getter
+ @Setter
+ public static class OptionList implements Serializable {
+ private static final long serialVersionUID = -5696099236344075582L;
+
+ @SerializedName("option_id")
+ private Integer optionId;
+
+ @SerializedName("option_text")
+ private String optionText;
+
+ public static OptionList fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, OptionList.class);
+ }
+
+ public String toJson() {
+ return WxCpGsonBuilder.create().toJson(this);
+ }
+
+ }
+
+ public static WxCpGetReportJobInfo fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, WxCpGetReportJobInfo.class);
+ }
+
+ public String toJson() {
+ return WxCpGsonBuilder.create().toJson(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 7493806d1..93246c526 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
@@ -173,6 +173,12 @@ public interface WxCpApiPathConsts {
String GET_OPEN_APPROVAL_DATA = "/cgi-bin/corp/getopenapprovaldata";
}
+ interface School {
+ String GET_HEALTH_REPORT_STAT = "/cgi-bin/health/get_health_report_stat";
+ String GET_REPORT_JOBIDS = "/cgi-bin/health/get_report_jobids";
+ String GET_REPORT_JOB_INFO = "/cgi-bin/health/get_report_job_info";
+ }
+
interface Living {
String GET_LIVING_CODE = "/cgi-bin/living/get_living_code";
String GET_LIVING_INFO = "/cgi-bin/living/get_living_info?livingid=";
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMsgAuditTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMsgAuditTest.java
index 457996a0e..47e511be7 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMsgAuditTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMsgAuditTest.java
@@ -168,7 +168,14 @@ public class WxCpMsgAuditTest {
return;
}
- // 拉取媒体文件
+ /**
+ * 拉取媒体文件
+ *
+ * 注意:
+ * 1、根据上面返回的文件类型,拼接好存放文件的绝对路径即可。此时绝对路径写入文件流,来达到获取媒体文件的目的。
+ * 2、拉取完媒体文件之后,此时文件已经存在绝对路径,可以通过mq异步上传到对象存储
+ * 3、比如可以上传到阿里云oss或者腾讯云cos
+ */
String targetPath = path + md5Sum + suffix;
cpService.getMsgAuditService().getMediaFile(sdkFileId, null, null, 1000L, targetPath);
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpSchoolHealthTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpSchoolHealthTest.java
new file mode 100644
index 000000000..2ed24719b
--- /dev/null
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpSchoolHealthTest.java
@@ -0,0 +1,66 @@
+package me.chanjar.weixin.cp.api;
+
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
+import me.chanjar.weixin.cp.bean.school.health.WxCpGetHealthReportStat;
+import me.chanjar.weixin.cp.bean.school.health.WxCpGetReportJobIds;
+import me.chanjar.weixin.cp.bean.school.health.WxCpGetReportJobInfo;
+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.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 企业微信家校应用 健康上报接口.
+ * https://developer.work.weixin.qq.com/document/path/93676
+ *
+ * @author Wang_Wong
+ * @date: 2022/5/31 9:10
+ */
+@Slf4j
+public class WxCpSchoolHealthTest {
+
+ private static WxCpConfigStorage wxCpConfigStorage;
+ private static WxCpService cpService;
+
+ @Test
+ public void test() throws WxErrorException {
+
+ InputStream inputStream = ClassLoader.getSystemResourceAsStream("test-config.xml");
+ WxCpDemoInMemoryConfigStorage config = WxCpDemoInMemoryConfigStorage.fromXml(inputStream);
+
+ wxCpConfigStorage = config;
+ cpService = new WxCpServiceImpl();
+ cpService.setWxCpConfigStorage(config);
+ String currDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
+
+
+ /**
+ * 获取健康上报任务ID列表
+ * https://developer.work.weixin.qq.com/document/path/93677
+ */
+ WxCpGetReportJobIds reportJobids = cpService.getSchoolHealthService().getReportJobIds(null, null);
+ log.info("返回的reportJobids为:{}", reportJobids.toJson());
+
+ /**
+ * 获取健康上报任务详情
+ * https://developer.work.weixin.qq.com/document/path/93678
+ */
+ WxCpGetReportJobInfo reportJobInfo = cpService.getSchoolHealthService().getReportJobInfo(null, currDate);
+ log.info("返回的reportJobInfo为:{}", reportJobInfo.toJson());
+
+ /**
+ * 获取健康上报使用统计
+ * https://developer.work.weixin.qq.com/document/path/93676
+ */
+ String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
+ WxCpGetHealthReportStat healthReportStat = cpService.getSchoolHealthService().getHealthReportStat(date);
+ log.info("返回的healthReportStat为:{}", healthReportStat.toJson());
+
+ }
+
+}