diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpSchoolUserService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpSchoolUserService.java new file mode 100644 index 0000000000..7a97914a1f --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpSchoolUserService.java @@ -0,0 +1,104 @@ +package me.chanjar.weixin.cp.api; + +import lombok.NonNull; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.bean.WxCpBaseResp; +import me.chanjar.weixin.cp.bean.school.user.WxCpCreateParentRequest; +import me.chanjar.weixin.cp.bean.school.user.WxCpUpdateParentRequest; + +import java.util.List; + +/** + * 企业微信家校沟通相关接口. + * https://developer.work.weixin.qq.com/document/path/91638 + * + * @author Wang_Wong + * @date: 2022/6/18 9:10 + */ +public interface WxCpSchoolUserService { + + /** + * 创建学生 + * 请求方式:POST(HTTPS) + * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/create_student?access_token=ACCESS_TOKEN + * + * @param studentUserId + * @param name + * @param departments + * @return + * @throws WxErrorException + */ + WxCpBaseResp createStudent(@NonNull String studentUserId, @NonNull String name, @NonNull List departments) throws WxErrorException; + + /** + * 删除学生 + * 请求方式:GET(HTTPS) + * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/delete_student?access_token=ACCESS_TOKEN&userid=USERID + * + * @param studentUserId + * @return + * @throws WxErrorException + */ + WxCpBaseResp deleteStudent(@NonNull String studentUserId) throws WxErrorException; + + /** + * 更新学生 + * 请求方式:POST(HTTPS) + * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/update_student?access_token=ACCESS_TOKEN + * + * @param studentUserId + * @param newStudentUserId + * @param name + * @param departments + * @return + * @throws WxErrorException + */ + WxCpBaseResp updateStudent(@NonNull String studentUserId, String newStudentUserId, String name, List departments) throws WxErrorException; + + /** + * 创建家长 + * 请求方式:POST(HTTPS) + * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/create_parent?access_token=ACCESS_TOKEN + * + * @param request + * @return + * @throws WxErrorException + */ + WxCpBaseResp createParent(@NonNull WxCpCreateParentRequest request) throws WxErrorException; + + /** + * 更新家长 + * 请求方式:POST(HTTPS) + * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/update_parent?access_token=ACCESS_TOKEN + * + * @param request + * @return + * @throws WxErrorException + */ + WxCpBaseResp updateParent(@NonNull WxCpUpdateParentRequest request) throws WxErrorException; + + /** + * 删除家长 + * 请求方式:GET(HTTPS) + * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/user/delete_parent?access_token=ACCESS_TOKEN&userid=USERID + * + * @param userId + * @return + * @throws WxErrorException + */ + WxCpBaseResp deleteParent(@NonNull String userId) throws WxErrorException; + + /** + * 设置家校通讯录自动同步模式 + * 企业和第三方可通过此接口修改家校通讯录与班级标签之间的自动同步模式,注意,一旦设置禁止自动同步,将无法再次开启。 + *

+ * 请求方式:POST(HTTPS) + * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/school/set_arch_sync_mode?access_token=ACCESS_TOKEN + * + * @param archSyncMode 家校通讯录同步模式:1-禁止将标签同步至家校通讯录,2-禁止将家校通讯录同步至标签,3-禁止家校通讯录和标签相互同步 + * @return + * @throws WxErrorException + */ + WxCpBaseResp setArchSyncMode(@NonNull Integer archSyncMode) 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 32606b205d..60cfda149d 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 @@ -407,6 +407,13 @@ public interface WxCpService extends WxService { */ WxCpSchoolService getSchoolService(); + /** + * 获取家校沟通相关接口的服务类对象 + * + * @return + */ + WxCpSchoolUserService getSchoolUserService(); + /** * 获取家校应用健康上报的服务类对象 * 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 fbfdbf3834..b72f0f0fb9 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 @@ -50,6 +50,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH private WxCpAgentService agentService = new WxCpAgentServiceImpl(this); private WxCpOaService oaService = new WxCpOaServiceImpl(this); private WxCpSchoolService schoolService = new WxCpSchoolServiceImpl(this); + private WxCpSchoolUserService schoolUserService = new WxCpSchoolUserServiceImpl(this); private WxCpSchoolHealthService schoolHealthService = new WxCpSchoolHealthServiceImpl(this); private WxCpLivingService livingService = new WxCpLivingServiceImpl(this); private WxCpOaAgentService oaAgentService = new WxCpOaAgentServiceImpl(this); @@ -500,6 +501,11 @@ public WxCpSchoolService getSchoolService() { return schoolService; } + @Override + public WxCpSchoolUserService getSchoolUserService() { + return schoolUserService; + } + @Override public WxCpSchoolHealthService getSchoolHealthService() { return schoolHealthService; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpSchoolUserServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpSchoolUserServiceImpl.java new file mode 100644 index 0000000000..404797f2ce --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpSchoolUserServiceImpl.java @@ -0,0 +1,108 @@ +package me.chanjar.weixin.cp.api.impl; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.api.WxCpSchoolUserService; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.WxCpBaseResp; +import me.chanjar.weixin.cp.bean.school.user.WxCpCreateParentRequest; +import me.chanjar.weixin.cp.bean.school.user.WxCpUpdateParentRequest; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; + +import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.School.*; + +/** + * 企业微信家校沟通相关接口. + * https://developer.work.weixin.qq.com/document/path/91638 + * + * @author Wang_Wong + * @date: 2022/6/18 9:10 + */ +@Slf4j +@RequiredArgsConstructor +public class WxCpSchoolUserServiceImpl implements WxCpSchoolUserService { + + private final WxCpService cpService; + + @Override + public WxCpBaseResp createStudent(@NonNull String studentUserId, @NonNull String name, @NonNull List departments) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(CREATE_STUDENT); + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("student_userid", studentUserId); + jsonObject.addProperty("name", name); + JsonArray jsonArray = new JsonArray(); + for (Integer depart : departments) { + jsonArray.add(new JsonPrimitive(depart)); + } + jsonObject.add("department", jsonArray); + String responseContent = this.cpService.post(apiUrl, jsonObject.toString()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpBaseResp deleteStudent(@NonNull String studentUserId) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(DELETE_STUDENT) + studentUserId; + String responseContent = this.cpService.get(apiUrl, null); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpBaseResp updateStudent(@NonNull String studentUserId, String newStudentUserId, String name, List departments) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(UPDATE_STUDENT); + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("student_userid", studentUserId); + if (StringUtils.isNotEmpty(newStudentUserId)) { + jsonObject.addProperty("new_student_userid", newStudentUserId); + } + if (StringUtils.isNotEmpty(name)) { + jsonObject.addProperty("name", name); + } + if (departments != null && departments.size() > 0) { + JsonArray jsonArray = new JsonArray(); + for (Integer depart : departments) { + jsonArray.add(new JsonPrimitive(depart)); + } + jsonObject.add("department", jsonArray); + } + String responseContent = this.cpService.post(apiUrl, jsonObject.toString()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpBaseResp createParent(@NonNull WxCpCreateParentRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(CREATE_PARENT); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpBaseResp updateParent(@NonNull WxCpUpdateParentRequest request) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(UPDATE_PARENT); + String responseContent = this.cpService.post(apiUrl, request.toJson()); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpBaseResp deleteParent(@NonNull String userId) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(DELETE_PARENT) + userId; + String responseContent = this.cpService.get(apiUrl, null); + return WxCpBaseResp.fromJson(responseContent); + } + + @Override + public WxCpBaseResp setArchSyncMode(@NonNull Integer archSyncMode) throws WxErrorException { + String apiUrl = this.cpService.getWxCpConfigStorage().getApiUrl(SET_ARCH_SYNC_MODE); + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("arch_sync_mode", archSyncMode); + String responseContent = this.cpService.post(apiUrl, jsonObject.toString()); + return WxCpBaseResp.fromJson(responseContent); + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/user/WxCpCreateParentRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/user/WxCpCreateParentRequest.java new file mode 100644 index 0000000000..f97a3c48b1 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/user/WxCpCreateParentRequest.java @@ -0,0 +1,65 @@ +package me.chanjar.weixin.cp.bean.school.user; + +import com.google.gson.annotations.SerializedName; +import lombok.*; +import lombok.experimental.Accessors; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +/** + * 创建家长请求. + * + * @author Wang_Wong + * @date 2022-06-20 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpCreateParentRequest implements Serializable { + private static final long serialVersionUID = -4960239393895754138L; + + @SerializedName("parent_userid") + private String parentUserId; + + @SerializedName("mobile") + private String mobile; + + @SerializedName("to_invite") + private Boolean toInvite; + + @SerializedName("children") + private List children; + + @Setter + @Getter + public static class Children implements Serializable { + + @SerializedName("student_userid") + private String studentUserId; + + @SerializedName("relation") + private String relation; + + public static Children fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, Children.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + } + + public static WxCpCreateParentRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpCreateParentRequest.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/user/WxCpUpdateParentRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/user/WxCpUpdateParentRequest.java new file mode 100644 index 0000000000..23f404f4dd --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/school/user/WxCpUpdateParentRequest.java @@ -0,0 +1,65 @@ +package me.chanjar.weixin.cp.bean.school.user; + +import com.google.gson.annotations.SerializedName; +import lombok.*; +import lombok.experimental.Accessors; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +/** + * 更新家长请求. + * + * @author Wang_Wong + * @date 2022-06-20 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class WxCpUpdateParentRequest implements Serializable { + private static final long serialVersionUID = -4960239393895754138L; + + @SerializedName("parent_userid") + private String parentUserId; + + @SerializedName("mobile") + private String mobile; + + @SerializedName("new_parent_userid") + private String newParentUserId; + + @SerializedName("children") + private List children; + + @Setter + @Getter + public static class Children implements Serializable { + + @SerializedName("student_userid") + private String studentUserId; + + @SerializedName("relation") + private String relation; + + public static Children fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, Children.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + } + + public static WxCpUpdateParentRequest fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpUpdateParentRequest.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 dc308feb45..476f827adf 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 @@ -183,6 +183,14 @@ interface School { String GET_STUDENT_CUSTOMIZE_HEALTH_INFO = "/cgi-bin/school/user/get_student_customize_health_info"; String GET_HEALTH_QRCODE = "/cgi-bin/school/user/get_health_qrcode"; + String CREATE_STUDENT = "/cgi-bin/school/user/create_student"; + String DELETE_STUDENT = "/cgi-bin/school/user/delete_student?userid="; + String UPDATE_STUDENT = "/cgi-bin/school/user/update_student"; + String CREATE_PARENT = "/cgi-bin/school/user/create_parent"; + String UPDATE_PARENT = "/cgi-bin/school/user/update_parent"; + String DELETE_PARENT = "/cgi-bin/school/user/delete_parent?userid="; + String SET_ARCH_SYNC_MODE = "/cgi-bin/school/set_arch_sync_mode"; + String GET_PAYMENT_RESULT = "/cgi-bin/school/get_payment_result"; String GET_TRADE = "/cgi-bin/school/get_trade"; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpSchoolUserTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpSchoolUserTest.java new file mode 100644 index 0000000000..a201da2836 --- /dev/null +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpSchoolUserTest.java @@ -0,0 +1,130 @@ +package me.chanjar.weixin.cp.api; + +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import lombok.var; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; +import me.chanjar.weixin.cp.bean.WxCpBaseResp; +import me.chanjar.weixin.cp.bean.school.user.WxCpCreateParentRequest; +import me.chanjar.weixin.cp.bean.school.user.WxCpUpdateParentRequest; +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; + +/** + * 企业微信家校沟通相关接口. + * https://developer.work.weixin.qq.com/document/path/91638 + * + * @author Wang_Wong + * @date: 2022/6/18 9:10 + */ +@Slf4j +public class WxCpSchoolUserTest { + + 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); + + List list = Lists.newArrayList(); + list.add(1); + list.add(2); + list.add(3); + log.info("list:{}", list.toString()); + + + /** + * 更新家长 + * https://developer.work.weixin.qq.com/document/path/92333 + */ + String str2 = "{\"parent_userid\":\"zhangsan_parent_userid\",\"new_parent_userid\":\"NEW_ID\",\"mobile\":\"18000000000\",\"children\":[{\"student_userid\":\"zhangsan\",\"relation\":\"爸爸\"},{\"student_userid\":\"lisi\",\"relation\":\"伯父\"}]}"; + WxCpUpdateParentRequest updateParentRequest1 = WxCpUpdateParentRequest.fromJson(str2); + log.info("updateParentRequest1:{}", updateParentRequest1.toJson()); + + WxCpUpdateParentRequest updateParentRequest = new WxCpUpdateParentRequest(); + updateParentRequest.setParentUserId("zhangsan"); + updateParentRequest.setMobile("17324399999"); + updateParentRequest.setNewParentUserId("wangkai"); + + var child = new WxCpUpdateParentRequest.Children(); + child.setStudentUserId("zhangguiyuan"); + child.setRelation("伯父"); + + List childList = Lists.newArrayList(); + childList.add(child); + updateParentRequest.setChildren(childList); + + WxCpBaseResp updateParent = cpService.getSchoolUserService().updateParent(updateParentRequest); + log.info("updateParent:{}", updateParent.toJson()); + + /** + * 删除家长 + * https://developer.work.weixin.qq.com/document/path/92332 + */ + WxCpBaseResp deleteParent = cpService.getSchoolUserService().deleteParent("zhangsan"); + log.info("deleteParent:{}", deleteParent.toJson()); + + /** + * 创建家长 + * https://developer.work.weixin.qq.com/document/path/92331 + */ + String str1 = "{\"parent_userid\":\"zhangsan_parent_userid\",\"mobile\":\"10000000000\",\"to_invite\":false,\"children\":[{\"student_userid\":\"zhangsan\",\"relation\":\"爸爸\"},{\"student_userid\":\"lisi\",\"relation\":\"伯父\"}]}"; + WxCpCreateParentRequest createParentRequest1 = WxCpCreateParentRequest.fromJson(str1); + log.info("createParentRequest1:{}", createParentRequest1.toJson()); + + WxCpCreateParentRequest createParentRequest = new WxCpCreateParentRequest(); + createParentRequest.setParentUserId("wangkai"); + createParentRequest.setMobile("17324398888"); + createParentRequest.setToInvite(false); + + var children1 = new WxCpCreateParentRequest.Children(); + children1.setStudentUserId("zhangguiyuan"); + children1.setRelation("伯父"); + + List children = Lists.newArrayList(); + children.add(children1); + createParentRequest.setChildren(children); + + WxCpBaseResp createParent = cpService.getSchoolUserService().createParent(createParentRequest); + log.info("createParent:{}", createParent.toJson()); + + /** + * 设置家校通讯录自动同步模式 + * 企业和第三方可通过此接口修改家校通讯录与班级标签之间的自动同步模式,注意,一旦设置禁止自动同步,将无法再次开启。 + */ + WxCpBaseResp setArchSyncMode = cpService.getSchoolUserService().setArchSyncMode(2); + log.info("setArchSyncMode:{}", setArchSyncMode.toJson()); + + /** + * 更新学生 + */ + WxCpBaseResp updateStudent = cpService.getSchoolUserService().updateStudent("WangKai", "wangkai", "王", list); + log.info("updateStudent:{}", updateStudent.toJson()); + + /** + * 删除学生 + */ + WxCpBaseResp deleteStudent = cpService.getSchoolUserService().deleteStudent("WangKai"); + log.info("deleteStudent:{}", deleteStudent.toJson()); + + /** + * 创建学生 + */ + WxCpBaseResp student = cpService.getSchoolUserService().createStudent("WangKai", "王", list); + log.info("student:{}", student.toJson()); + + } + +}