🆕 #2698【企业微信】增加家校应用-上课直播相关接口

This commit is contained in:
0katekate0 2022-06-20 16:25:10 +08:00 committed by GitHub
parent 5ac2e690c0
commit d5c6803260
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 446 additions and 20 deletions

View File

@ -48,7 +48,7 @@ public interface WxCpLivingService {
* @return
* @throws WxErrorException
*/
WxCpWatchStat getWatchStat(@NonNull String livingId, Integer nextKey) throws WxErrorException;
WxCpWatchStat getWatchStat(@NonNull String livingId, String nextKey) throws WxErrorException;
/**
* 获取成员直播ID列表

View File

@ -1,10 +1,9 @@
package me.chanjar.weixin.cp.api;
import lombok.NonNull;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.bean.school.WxCpCustomizeHealthInfo;
import me.chanjar.weixin.cp.bean.school.WxCpPaymentResult;
import me.chanjar.weixin.cp.bean.school.WxCpResultList;
import me.chanjar.weixin.cp.bean.school.WxCpTrade;
import me.chanjar.weixin.cp.bean.living.WxCpLivingResult;
import me.chanjar.weixin.cp.bean.school.*;
import javax.validation.constraints.NotNull;
import java.util.List;
@ -82,4 +81,68 @@ public interface WxCpSchoolService {
*/
WxCpTrade getTrade(@NotNull String paymentId, @NotNull String tradeNo) throws WxErrorException;
/**
* 获取直播详情
* 请求方式GETHTTPS
* 请求地址https://qyapi.weixin.qq.com/cgi-bin/school/living/get_living_info?access_token=ACCESS_TOKEN&livingid=LIVINGID
*
* @param livingId
* @return
*/
WxCpSchoolLivingInfo getLivingInfo(@NotNull String livingId) throws WxErrorException;
/**
* 获取老师直播ID列表
* 通过此接口可以获取指定老师的所有直播ID
* <p>
* 请求方式POSTHTTPS
* 请求地址https://qyapi.weixin.qq.com/cgi-bin/living/get_user_all_livingid?access_token=ACCESS_TOKEN
*
* @param userId
* @param cursor
* @param limit
* @return
* @throws WxErrorException
*/
WxCpLivingResult.LivingIdResult getUserAllLivingId(@NonNull String userId, String cursor, Integer limit) throws WxErrorException;
/**
* 获取观看直播统计
* 通过该接口可以获取所有观看直播的人员统计
* <p>
* 请求方式POSTHTTPS
* 请求地址https://qyapi.weixin.qq.com/cgi-bin/school/living/get_watch_stat?access_token=ACCESS_TOKEN
*
* @param livingId
* @param nextKey
* @return
* @throws WxErrorException
*/
WxCpSchoolWatchStat getWatchStat(@NonNull String livingId, String nextKey) throws WxErrorException;
/**
* 获取未观看直播统计
* 通过该接口可以获取未观看直播的学生统计学生的家长必须是已经关注学校通知才会纳入统计范围
* <p>
* 请求方式POSTHTTPS
* 请求地址https://qyapi.weixin.qq.com/cgi-bin/school/living/get_unwatch_stat?access_token=ACCESS_TOKEN
*
* @param livingId
* @param nextKey
* @return
* @throws WxErrorException
*/
WxCpSchoolUnwatchStat getUnwatchStat(@NonNull String livingId, String nextKey) throws WxErrorException;
/**
* 删除直播回放
* 请求方式 POSTHTTPS
* 请求地址 https://qyapi.weixin.qq.com/cgi-bin/living/delete_replay_data?access_token=ACCESS_TOKEN
*
* @param livingId
* @return
* @throws WxErrorException
*/
WxCpLivingResult deleteReplayData(@NonNull String livingId) throws WxErrorException;
}

View File

@ -12,13 +12,15 @@ import me.chanjar.weixin.cp.api.WxCpLivingService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.living.*;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
import org.apache.commons.lang3.StringUtils;
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Living.*;
/**
* 企业微信直播接口实现类.
* https://developer.work.weixin.qq.com/document/path/93633
*
* @author Wang_Wong
* @author <a href="https://github.com/0katekate0">Wang_Wong</a>
* @date 2021-12-21
*/
@Slf4j
@ -48,11 +50,11 @@ public class WxCpLivingServiceImpl implements WxCpLivingService {
}
@Override
public WxCpWatchStat getWatchStat(String livingId, Integer nextKey) throws WxErrorException {
public WxCpWatchStat getWatchStat(String livingId, String nextKey) throws WxErrorException {
String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(GET_WATCH_STAT);
JsonObject jsonObject = new JsonObject();
if (nextKey != null) {
jsonObject.addProperty("next_key", String.valueOf(nextKey));
if (StringUtils.isNotBlank(nextKey)) {
jsonObject.addProperty("next_key", nextKey);
}
jsonObject.addProperty("livingid", livingId);
String responseContent = this.cpService.post(apiUrl, jsonObject.toString());

View File

@ -1,15 +1,15 @@
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.WxCpSchoolService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.school.WxCpCustomizeHealthInfo;
import me.chanjar.weixin.cp.bean.school.WxCpPaymentResult;
import me.chanjar.weixin.cp.bean.school.WxCpResultList;
import me.chanjar.weixin.cp.bean.school.WxCpTrade;
import me.chanjar.weixin.cp.bean.living.WxCpLivingResult;
import me.chanjar.weixin.cp.bean.school.*;
import org.apache.commons.lang3.StringUtils;
import javax.validation.constraints.NotNull;
import java.util.List;
@ -85,4 +85,45 @@ public class WxCpSchoolServiceImpl implements WxCpSchoolService {
return WxCpTrade.fromJson(responseContent);
}
@Override
public WxCpSchoolLivingInfo getLivingInfo(@NotNull String livingId) throws WxErrorException {
String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(GET_LIVING_INFO) + livingId;
String responseContent = this.cpService.get(apiUrl, null);
return WxCpSchoolLivingInfo.fromJson(responseContent);
}
@Override
public WxCpLivingResult.LivingIdResult getUserAllLivingId(@NonNull String userId, String cursor, Integer limit) throws WxErrorException {
return this.cpService.getLivingService().getUserAllLivingId(userId, cursor, limit);
}
@Override
public WxCpSchoolWatchStat getWatchStat(@NonNull String livingId, String nextKey) throws WxErrorException {
String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(GET_WATCH_STAT);
JsonObject jsonObject = new JsonObject();
if (StringUtils.isNotBlank(nextKey)) {
jsonObject.addProperty("next_key", nextKey);
}
jsonObject.addProperty("livingid", livingId);
String responseContent = this.cpService.post(apiUrl, jsonObject.toString());
return WxCpSchoolWatchStat.fromJson(responseContent);
}
@Override
public WxCpSchoolUnwatchStat getUnwatchStat(@NonNull String livingId, String nextKey) throws WxErrorException {
String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(GET_UNWATCH_STAT);
JsonObject jsonObject = new JsonObject();
if (StringUtils.isNotBlank(nextKey)) {
jsonObject.addProperty("next_key", nextKey);
}
jsonObject.addProperty("livingid", livingId);
String responseContent = this.cpService.post(apiUrl, jsonObject.toString());
return WxCpSchoolUnwatchStat.fromJson(responseContent);
}
@Override
public WxCpLivingResult deleteReplayData(@NonNull String livingId) throws WxErrorException {
return cpService.getLivingService().deleteReplayData(livingId);
}
}

View File

@ -22,7 +22,7 @@ public class WxCpLivingInfo implements Serializable {
private Long livingStart;
@SerializedName("living_duration")
private Long livingDurationme;
private Long livingDuration;
@SerializedName("status")
private Integer status;

View File

@ -32,7 +32,7 @@ public class WxCpLivingResult implements Serializable {
private String nextCursor;
@SerializedName("livingid_list")
private String[] livingidList;
private String[] livingIdList;
public static LivingIdResult fromJson(String json) {
return WxCpGsonBuilder.create().fromJson(json, LivingIdResult.class);

View File

@ -0,0 +1,94 @@
package me.chanjar.weixin.cp.bean.school;
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 WxCpSchoolLivingInfo extends WxCpBaseResp implements Serializable {
private static final long serialVersionUID = -5028321625140879571L;
@SerializedName("living_info")
private LivingInfo livingInfo;
@Getter
@Setter
public static class LivingInfo implements Serializable {
@SerializedName("theme")
private String theme;
@SerializedName("living_start")
private Long livingStart;
@SerializedName("living_duration")
private Long livingDuration;
@SerializedName("anchor_userid")
private String anchorUserId;
@SerializedName("living_range")
private LivingRange livingRange;
@SerializedName("viewer_num")
private Integer viewerNum;
@SerializedName("comment_num")
private Integer commentNum;
@SerializedName("open_replay")
private Integer openReplay;
@SerializedName("push_stream_url")
private String pushStreamUrl;
public static LivingInfo fromJson(String json) {
return WxCpGsonBuilder.create().fromJson(json, LivingInfo.class);
}
public String toJson() {
return WxCpGsonBuilder.create().toJson(this);
}
}
@Getter
@Setter
public static class LivingRange implements Serializable {
@SerializedName("partyids")
private List<Integer> partyIds;
@SerializedName("group_names")
private List<String> groupNames;
public static LivingRange fromJson(String json) {
return WxCpGsonBuilder.create().fromJson(json, LivingRange.class);
}
public String toJson() {
return WxCpGsonBuilder.create().toJson(this);
}
}
public static WxCpSchoolLivingInfo fromJson(String json) {
return WxCpGsonBuilder.create().fromJson(json, WxCpSchoolLivingInfo.class);
}
public String toJson() {
return WxCpGsonBuilder.create().toJson(this);
}
}

View File

@ -0,0 +1,65 @@
package me.chanjar.weixin.cp.bean.school;
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 WxCpSchoolUnwatchStat extends WxCpBaseResp {
private static final long serialVersionUID = -5028321625140879571L;
@SerializedName("ending")
private Integer ending;
@SerializedName("next_key")
private String nextKey;
@SerializedName("stat_info")
private StatInfo statInfo;
@Getter
@Setter
public static class StatInfo implements Serializable {
private static final long serialVersionUID = -5696099236344075582L;
@SerializedName("students")
private List<Student> students;
}
@Getter
@Setter
public static class Student implements Serializable {
private static final long serialVersionUID = -5696099236344075582L;
@SerializedName("student_userid")
private String studentUserId;
@SerializedName("parent_userid")
private String parentUserId;
@SerializedName("partyids")
private List<Integer> partyIds;
}
public static WxCpSchoolUnwatchStat fromJson(String json) {
return WxCpGsonBuilder.create().fromJson(json, WxCpSchoolUnwatchStat.class);
}
public String toJson() {
return WxCpGsonBuilder.create().toJson(this);
}
}

View File

@ -0,0 +1,102 @@
package me.chanjar.weixin.cp.bean.school;
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 WxCpSchoolWatchStat extends WxCpBaseResp{
private static final long serialVersionUID = -5028321625140879571L;
@SerializedName("ending")
private Integer ending;
@SerializedName("next_key")
private String nextKey;
@SerializedName("stat_infoes")
private StatInfo statInfoes;
@Getter
@Setter
public static class StatInfo implements Serializable {
private static final long serialVersionUID = -5696099236344075582L;
@SerializedName("students")
private List<Student> students;
@SerializedName("visitors")
private List<Visitor> visitors;
}
@Getter
@Setter
public static class Student implements Serializable {
private static final long serialVersionUID = -5696099236344075582L;
@SerializedName("student_userid")
private String studentUserId;
@SerializedName("parent_userid")
private String parentUserId;
@SerializedName("watch_time")
private Integer watchTime;
@SerializedName("is_comment")
private Integer isComment;
@SerializedName("enter_time")
private Long enterTime;
@SerializedName("leave_time")
private Long leaveTime;
@SerializedName("partyids")
private List<Integer> partyIds;
}
@Getter
@Setter
public static class Visitor implements Serializable {
private static final long serialVersionUID = -5696099236344075582L;
@SerializedName("nickname")
private String nickname;
@SerializedName("watch_time")
private Integer watchTime;
@SerializedName("is_comment")
private Integer isComment;
@SerializedName("enter_time")
private Long enterTime;
@SerializedName("leave_time")
private Long leaveTime;
}
public static WxCpSchoolWatchStat fromJson(String json) {
return WxCpGsonBuilder.create().fromJson(json, WxCpSchoolWatchStat.class);
}
public String toJson() {
return WxCpGsonBuilder.create().toJson(this);
}
}

View File

@ -185,6 +185,13 @@ public interface WxCpApiPathConsts {
String GET_PAYMENT_RESULT = "/cgi-bin/school/get_payment_result";
String GET_TRADE = "/cgi-bin/school/get_trade";
/**
* 上课直播
*/
String GET_LIVING_INFO = "/cgi-bin/school/living/get_living_info?livingid=";
String GET_WATCH_STAT = "/cgi-bin/school/living/get_watch_stat";
String GET_UNWATCH_STAT = "/cgi-bin/school/living/get_unwatch_stat";
}
interface Living {

View File

@ -84,7 +84,7 @@ public class WxCpLivingTest {
log.info(livingInfo.toJson());
// 直播观看明细
WxCpWatchStat watchStat = wxCpService.getLivingService().getWatchStat("lvOQpTDwAAcP9wNOSSxTwpbni-TMPNSg", 0);
WxCpWatchStat watchStat = wxCpService.getLivingService().getWatchStat("lvOQpTDwAAcP9wNOSSxTwpbni-TMPNSg", "0");
log.info(watchStat.toJson());
final String watchStateJson = "{\"errcode\":0,\"errmsg\":\"ok\",\"ending\":1,\"next_key\":\"NEXT_KEY\",\"stat_info\":{\"users\":[{\"userid\":\"userid\",\"watch_time\":30,\"is_comment\":1,\"is_mic\":1}],\"external_users\":[{\"external_userid\":\"external_userid1\",\"type\":1,\"name\":\"user name\",\"watch_time\":30,\"is_comment\":1,\"is_mic\":1},{\"external_userid\":\"external_userid2\",\"type\":2,\"name\":\"user_name\",\"watch_time\":30,\"is_comment\":1,\"is_mic\":1}]}}";

View File

@ -4,10 +4,8 @@ import com.google.common.collect.Lists;
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.WxCpCustomizeHealthInfo;
import me.chanjar.weixin.cp.bean.school.WxCpPaymentResult;
import me.chanjar.weixin.cp.bean.school.WxCpResultList;
import me.chanjar.weixin.cp.bean.school.WxCpTrade;
import me.chanjar.weixin.cp.bean.living.WxCpLivingResult;
import me.chanjar.weixin.cp.bean.school.*;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import me.chanjar.weixin.cp.demo.WxCpDemoInMemoryConfigStorage;
import org.testng.annotations.Test;
@ -46,6 +44,60 @@ public class WxCpSchoolTest {
String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
/**
* 上课直播
*/
String livingId = "lvOQpTDwAAh0hxHsSeSwTQcmH0nWUC_Q";
/**
* 获取老师直播ID列表
* https://developer.work.weixin.qq.com/document/path/93739
*/
WxCpLivingResult.LivingIdResult result = cpService.getSchoolService().getUserAllLivingId("WangKai", null, 20);
log.info("result{}", result.toJson());
/**
* 删除直播回放
* https://developer.work.weixin.qq.com/document/path/93743
*/
WxCpLivingResult livingResult = cpService.getSchoolService().deleteReplayData(livingId);
log.info("livingResult{}", livingResult.toJson());
/**
* 获取未观看直播统计
* https://developer.work.weixin.qq.com/document/path/93742
*/
String str3 = "{\"errcode\":0,\"errmsg\":\"ok\",\"ending\":1,\"next_key\":\"NEXT_KEY\",\"stat_info\":{\"students\":[{\"student_userid\":\"zhansan_child\",\"parent_userid\":\"zhangsan\",\"partyids\":[10,11]},{\"student_userid\":\"lisi_child\",\"parent_userid\":\"lisi\",\"partyids\":[5]}]}}";
WxCpSchoolUnwatchStat schoolUnwatchStat = WxCpSchoolUnwatchStat.fromJson(str3);
log.info("unwatchStat{}", schoolUnwatchStat.toJson());
WxCpSchoolUnwatchStat unwatchStat = cpService.getSchoolService().getUnwatchStat(livingId, "0");
log.info("unwatchStat{}", unwatchStat.toJson());
/**
* 获取观看直播统计
* https://developer.work.weixin.qq.com/document/path/93741
*/
String str2 = "{\"errcode\":0,\"errmsg\":\"ok\",\"ending\":1,\"next_key\":\"NEXT_KEY\",\"stat_infoes\":{\"students\":[{\"student_userid\":\"zhansan_child\",\"parent_userid\":\"zhangsan\",\"partyids\":[10,11],\"watch_time\":30,\"enter_time\":1586433904,\"leave_time\":1586434000,\"is_comment\":1},{\"student_userid\":\"lisi_child\",\"parent_userid\":\"lisi\",\"partyids\":[10,11],\"watch_time\":30,\"enter_time\":1586433904,\"leave_time\":1586434000,\"is_comment\":0}],\"visitors\":[{\"nickname\":\"wx_nickname1\",\"watch_time\":30,\"enter_time\":1586433904,\"leave_time\":1586434000,\"is_comment\":1},{\"nickname\":\"wx_nickname2\",\"watch_time\":30,\"enter_time\":1586433904,\"leave_time\":1586434000,\"is_comment\":0}]}}";
WxCpSchoolWatchStat wxCpSchoolWatchStat = WxCpSchoolWatchStat.fromJson(str2);
log.info("wxCpSchoolWatchStat{}", wxCpSchoolWatchStat.toJson());
WxCpSchoolWatchStat watchStat = cpService.getSchoolService().getWatchStat(livingId, "0");
log.info("watchStat{}", watchStat.toJson());
String str1 = "{\"errcode\":0,\"errmsg\":\"ok\",\"living_info\":{\"theme\":\"直角三角形讲解\",\"living_start\":1586405229,\"living_duration\":1800,\"anchor_userid\":\"zhangsan\",\"living_range\":{\"partyids\":[1,4,9],\"group_names\":[\"group_name1\",\"group_name2\"]},\"viewer_num\":100,\"comment_num\":110,\"open_replay\":1,\"push_stream_url\":\"https://www.qq.test.com\"}}";
WxCpSchoolLivingInfo wxCpSchoolLivingInfo = WxCpSchoolLivingInfo.fromJson(str1);
log.info("str1{}", wxCpSchoolLivingInfo.toJson());
/**
* 获取直播详情
* https://developer.work.weixin.qq.com/document/path/93740
*/
WxCpSchoolLivingInfo schoolLivingInfo = cpService.getSchoolService().getLivingInfo(livingId);
log.info("schoolLivingInfo{}", schoolLivingInfo.toJson());
/**
* 获取学生付款结果
* https://developer.work.weixin.qq.com/document/path/94553