Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【企业微信】增加家校应用-复学码接口支持 #2676

Merged
merged 3 commits into from
Jun 5, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public class WxCpProperties {
* 微信企业号应用 EncodingAESKey
*/
private String aesKey;
/**
* 微信企业号应用 会话存档私钥
*/
private String msgAuditPriKey;
/**
* 微信企业号应用 会话存档类库路径
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ protected WxCpDefaultConfigImpl config(WxCpDefaultConfigImpl config, WxCpPropert
String token = properties.getToken();
Integer agentId = properties.getAgentId();
String aesKey = properties.getAesKey();
// 企业微信,会话存档路径
// 企业微信,私钥,会话存档路径
String msgAuditPriKey = properties.getMsgAuditPriKey();
String msgAuditLibPath = properties.getMsgAuditLibPath();

config.setCorpId(corpId);
Expand All @@ -32,6 +33,9 @@ protected WxCpDefaultConfigImpl config(WxCpDefaultConfigImpl config, WxCpPropert
if (StringUtils.isNotBlank(aesKey)) {
config.setAesKey(aesKey);
}
if (StringUtils.isNotBlank(msgAuditPriKey)) {
config.setMsgAuditPriKey(msgAuditPriKey);
}
if (StringUtils.isNotBlank(msgAuditLibPath)) {
config.setMsgAuditLibPath(msgAuditLibPath);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package me.chanjar.weixin.cp.api;

import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.bean.school.WxCpCustomizeHealthInfo;
import me.chanjar.weixin.cp.bean.school.WxCpResultList;

import javax.validation.constraints.NotNull;
import java.util.List;

/**
* 企业微信家校应用 复学码相关接口.
* https://developer.work.weixin.qq.com/document/path/93744
* <p>
* 权限说明:
* 仅复学码应用可以调用
*
* @author <a href="https://github.com/0katekate0">Wang_Wong</a>
* @date: 2022/5/31 9:10
*/
public interface WxCpSchoolService {

/**
* 获取老师健康信息
* 请求方式: POST(HTTPS)
* 请求地址: https://qyapi.weixin.qq.com/cgi-bin/school/user/get_teacher_customize_health_info?access_token=ACCESS_TOKEN
*
* @param date
* @param nextKey
* @param limit
* @return
* @throws WxErrorException
*/
WxCpCustomizeHealthInfo getTeacherCustomizeHealthInfo(@NotNull String date, String nextKey, Integer limit) throws WxErrorException;

/**
* 获取学生健康信息
* 请求方式: POST(HTTPS)
* 请求地址: https://qyapi.weixin.qq.com/cgi-bin/school/user/get_student_customize_health_info?access_token=ACCESS_TOKEN
*
* @param date
* @param nextKey
* @param limit
* @return
* @throws WxErrorException
*/
WxCpCustomizeHealthInfo getStudentCustomizeHealthInfo(@NotNull String date, String nextKey, Integer limit) throws WxErrorException;

/**
* 获取师生健康码
* 请求方式:POST(HTTPS)
* 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/get_health_qrcode?access_token=ACCESS_TOKEN
*
* @param userIds
* @param type
* @return
* @throws WxErrorException
*/
WxCpResultList getHealthQrCode(@NotNull List<String> userIds, @NotNull Integer type) throws WxErrorException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,13 @@ public interface WxCpService extends WxService {
*/
WxCpOaService getOaService();

/**
* 获取家校应用复学码相关接口的服务类对象
*
* @return
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EmptyBlockTag: A block tag (@param, @return, @throws, @deprecated) has an empty description. Block tags without descriptions don't add much value for future readers of the code; consider removing the tag entirely or adding a description.

Suggested change
* @return
*

(at-me in a reply with help or ignore)


Was this a good recommendation?
[ 🙁 Not relevant ] - [ 😕 Won't fix ] - [ 😑 Not critical, will fix ] - [ 🙂 Critical, will fix ] - [ 😊 Critical, fixing now ]

*/
WxCpSchoolService getSchoolService();

/**
* 获取家校应用健康上报的服务类对象
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH
private WxCpTagService tagService = new WxCpTagServiceImpl(this);
private WxCpAgentService agentService = new WxCpAgentServiceImpl(this);
private WxCpOaService oaService = new WxCpOaServiceImpl(this);
private WxCpSchoolService schoolService = new WxCpSchoolServiceImpl(this);
private WxCpSchoolHealthService schoolHealthService = new WxCpSchoolHealthServiceImpl(this);
private WxCpLivingService livingService = new WxCpLivingServiceImpl(this);
private WxCpOaAgentService oaAgentService = new WxCpOaAgentServiceImpl(this);
Expand Down Expand Up @@ -494,6 +495,11 @@ public WxCpOaService getOaService() {
return oaService;
}

@Override
public WxCpSchoolService getSchoolService() {
return schoolService;
}

@Override
public WxCpSchoolHealthService getSchoolHealthService() {
return schoolHealthService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public WxCpChatDatas getChatDatas(long seq, @NonNull long limit, String proxy, S
Finance.FreeSlice(slice);
WxCpChatDatas chatDatas = WxCpChatDatas.fromJson(content);
if (chatDatas.getErrCode().intValue() != 0) {
Finance.DestroySingletonSDK(sdk);
throw new WxErrorException(chatDatas.toJson());
}

Expand All @@ -110,14 +111,19 @@ public WxCpChatModel getDecryptData(@NonNull WxCpChatDatas.WxCpChatData chatData
}

public String decryptChatData(WxCpChatDatas.WxCpChatData chatData) throws Exception {
// 企业获取的会话内容将用公钥加密,企业可用自行保存的私钥解开会话内容数据,aeskey不能为空
String priKey = cpService.getWxCpConfigStorage().getAesKey();
/**
* 企业获取的会话内容,使用企业自行配置的消息加密公钥进行加密,企业可用自行保存的私钥解开会话内容数据。
* msgAuditPriKey 会话存档私钥不能为空
*/
String priKey = cpService.getWxCpConfigStorage().getMsgAuditPriKey();
if (StringUtils.isEmpty(priKey)) {
throw new WxErrorException("请配置会话存档私钥【aesKey】");
throw new WxErrorException("请配置会话存档私钥【msgAuditPriKey】");
}

String decryptByPriKey = WxCpCryptUtil.decryptByPriKey(chatData.getEncryptRandomKey(), priKey);
// 每次使用DecryptData解密会话存档前需要调用NewSlice获取一个slice,在使用完slice中数据后,还需要调用FreeSlice释放。
/**
* 每次使用DecryptData解密会话存档前需要调用NewSlice获取一个slice,在使用完slice中数据后,还需要调用FreeSlice释放。
*/
long sdk = Finance.SingletonSDK();
long msg = Finance.NewSlice();

Expand All @@ -128,7 +134,9 @@ public String decryptChatData(WxCpChatDatas.WxCpChatData chatData) throws Except
throw new WxErrorException("msg err ret " + ret);
}

// 明文
/**
* 明文
*/
String plainText = Finance.GetContentFromSlice(msg);
Finance.FreeSlice(msg);
return plainText;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package me.chanjar.weixin.cp.api.impl;

import com.google.gson.JsonObject;
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.WxCpResultList;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Optional;

import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.School.*;

/**
* 企业微信家校应用 复学码相关接口实现类.
* https://developer.work.weixin.qq.com/document/path/93744
*
* @author <a href="https://github.com/0katekate0">Wang_Wong</a>
* @date: 2022/6/1 14:05
*/
@Slf4j
@RequiredArgsConstructor
public class WxCpSchoolServiceImpl implements WxCpSchoolService {

private final WxCpService cpService;

@Override
public WxCpCustomizeHealthInfo getTeacherCustomizeHealthInfo(@NotNull String date, String nextKey, Integer limit) throws WxErrorException {
String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(GET_TEACHER_CUSTOMIZE_HEALTH_INFO);
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("date", date);
jsonObject.addProperty("limit", Optional.ofNullable(limit).orElse(100));
if (nextKey != null) {
jsonObject.addProperty("next_key", nextKey);
}
String responseContent = this.cpService.post(apiUrl, jsonObject.toString());
return WxCpCustomizeHealthInfo.fromJson(responseContent);
}

@Override
public WxCpCustomizeHealthInfo getStudentCustomizeHealthInfo(@NotNull String date, String nextKey, Integer limit) throws WxErrorException {
String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(GET_STUDENT_CUSTOMIZE_HEALTH_INFO);
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("date", date);
jsonObject.addProperty("limit", Optional.ofNullable(limit).orElse(100));
if (nextKey != null) {
jsonObject.addProperty("next_key", nextKey);
}
String responseContent = this.cpService.post(apiUrl, jsonObject.toString());
return WxCpCustomizeHealthInfo.fromJson(responseContent);
}

@Override
public WxCpResultList getHealthQrCode(@NotNull List<String> userIds, @NotNull Integer type) throws WxErrorException {
String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(GET_HEALTH_QRCODE);
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("type", type);
jsonObject.addProperty("userids", userIds.toString());
String responseContent = this.cpService.post(apiUrl, jsonObject.toString());
return WxCpResultList.fromJson(responseContent);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
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 WxCpCustomizeHealthInfo extends WxCpBaseResp implements Serializable {
private static final long serialVersionUID = -5028321625142879581L;

@SerializedName("health_infos")
private List<HealthInfo> healthInfos;

@SerializedName("template_id")
private String templateId;

@SerializedName("next_key")
private String nextKey;

@SerializedName("ending")
private Integer ending;

@Getter
@Setter
public static class HealthInfo implements Serializable {
private static final long serialVersionUID = -5696099236344075582L;

@SerializedName("userid")
private String userId;

@SerializedName("health_qrcode_status")
private Integer healthQrCodeStatus;

@SerializedName("self_submit")
private Integer selfSubmit;

@SerializedName("report_values")
private List<ReportValue> reportValues;

@SerializedName("question_templates")
private List<QuestionTemplate> questionTemplates;

public static HealthInfo fromJson(String json) {
return WxCpGsonBuilder.create().fromJson(json, HealthInfo.class);
}

public String toJson() {
return WxCpGsonBuilder.create().toJson(this);
}

}

@Getter
@Setter
public static class ReportValue implements Serializable {
private static final long serialVersionUID = -5696099236344075582L;

@SerializedName("question_id")
private Integer questionId;

@SerializedName("single_chose")
private Integer singleChose;

@SerializedName("text")
private String text;

public static ReportValue fromJson(String json) {
return WxCpGsonBuilder.create().fromJson(json, ReportValue.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("title")
private String title;

@SerializedName("is_must_fill")
private Integer isMustFill;

@SerializedName("is_not_display")
private Integer isNotDisplay;

@SerializedName("option_list")
private List<OptionList> 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 WxCpCustomizeHealthInfo fromJson(String json) {
return WxCpGsonBuilder.create().fromJson(json, WxCpCustomizeHealthInfo.class);
}

public String toJson() {
return WxCpGsonBuilder.create().toJson(this);
}

}
Loading