| @@ -1,10 +1,8 @@ | |||||
| package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
| import lombok.NonNull; | |||||
| import me.chanjar.weixin.common.error.WxErrorException; | import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.cp.bean.WxCpApprovalDataResult; | |||||
| import me.chanjar.weixin.cp.bean.WxCpCheckinData; | |||||
| import me.chanjar.weixin.cp.bean.WxCpCheckinOption; | |||||
| import me.chanjar.weixin.cp.bean.WxCpDialRecord; | |||||
| import me.chanjar.weixin.cp.bean.oa.*; | |||||
| import java.util.Date; | import java.util.Date; | ||||
| import java.util.List; | import java.util.List; | ||||
| @@ -30,7 +28,8 @@ public interface WxCpOaService { | |||||
| * @return 打卡数据列表 | * @return 打卡数据列表 | ||||
| * @throws WxErrorException 异常 | * @throws WxErrorException 异常 | ||||
| */ | */ | ||||
| List<WxCpCheckinData> getCheckinData(Integer openCheckinDataType, Date startTime, Date endTime, List<String> userIdList) throws WxErrorException; | |||||
| List<WxCpCheckinData> getCheckinData(Integer openCheckinDataType, Date startTime, Date endTime, | |||||
| List<String> userIdList) throws WxErrorException; | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| @@ -41,13 +40,63 @@ public interface WxCpOaService { | |||||
| * @param datetime 需要获取规则的当天日期 | * @param datetime 需要获取规则的当天日期 | ||||
| * @param userIdList 需要获取打卡规则的用户列表 | * @param userIdList 需要获取打卡规则的用户列表 | ||||
| * @return 打卡规则列表 | * @return 打卡规则列表 | ||||
| * @throws WxErrorException 异常 | |||||
| * @throws WxErrorException | |||||
| */ | */ | ||||
| List<WxCpCheckinOption> getCheckinOption(Date datetime, List<String> userIdList) throws WxErrorException; | List<WxCpCheckinOption> getCheckinOption(Date datetime, List<String> userIdList) throws WxErrorException; | ||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 获取审批数据 | |||||
| * | |||||
| * 批量获取审批单号 | |||||
| * | |||||
| * 审批应用及有权限的自建应用,可通过Secret调用本接口,以获取企业一段时间内企业微信“审批应用”单据的审批编号,支持按模板类型、申请人、部门、申请单审批状态等条件筛选。 | |||||
| * 自建应用调用此接口,需在“管理后台-应用管理-审批-API-审批数据权限”中,授权应用允许提交审批单据。 | |||||
| * | |||||
| * 一次拉取调用最多拉取100个审批记录,可以通过多次拉取的方式来满足需求,但调用频率不可超过600次/分。 | |||||
| * | |||||
| * API doc : https://work.weixin.qq.com/api/doc/90000/90135/91816 | |||||
| * </pre> | |||||
| * | |||||
| * @param startTime 开始时间 | |||||
| * @param endTime 结束时间 | |||||
| * @param cursor 分页查询游标,默认为0,后续使用返回的next_cursor进行分页拉取 | |||||
| * @param size 一次请求拉取审批单数量,默认值为100,上限值为100 | |||||
| * @param filters 筛选条件,可对批量拉取的审批申请设置约束条件,支持设置多个条件,nullable | |||||
| * @return WxCpApprovalInfo | |||||
| * @throws WxErrorException | |||||
| */ | |||||
| WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime, Integer cursor, Integer size, | |||||
| List<WxCpApprovalInfoQueryFilter> filters) throws WxErrorException; | |||||
| /** | |||||
| * short method | |||||
| * | |||||
| * @param startTime 开始时间 | |||||
| * @param endTime 结束时间 | |||||
| * @return WxCpApprovalInfo | |||||
| * @throws WxErrorException | |||||
| * @see me.chanjar.weixin.cp.api.WxCpOaService#getApprovalInfo | |||||
| */ | |||||
| WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 获取审批申请详情 | |||||
| * | |||||
| * 企业可通过审批应用或自建应用Secret调用本接口,根据审批单号查询企业微信“审批应用”的审批申请详情。 | |||||
| * | |||||
| * API Doc : https://work.weixin.qq.com/api/doc/90000/90135/91983 | |||||
| * </pre> | |||||
| * | |||||
| * @param spNo 审批单编号。 | |||||
| * @return WxCpApprovaldetail | |||||
| * @throws WxErrorException | |||||
| */ | |||||
| WxCpApprovalDetailResult getApprovalDetail(@NonNull String spNo) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 获取审批数据 (已过期, 请使用"批量获取审批单号" && "获取审批申请详情") | |||||
| * 通过本接口来获取公司一段时间内的审批记录。一次拉取调用最多拉取10000个审批记录,可以通过多次拉取的方式来满足需求,但调用频率不可超过600次/分。 | * 通过本接口来获取公司一段时间内的审批记录。一次拉取调用最多拉取10000个审批记录,可以通过多次拉取的方式来满足需求,但调用频率不可超过600次/分。 | ||||
| * API doc : https://work.weixin.qq.com/api/doc#90000/90135/91530 | * API doc : https://work.weixin.qq.com/api/doc#90000/90135/91530 | ||||
| * </pre> | * </pre> | ||||
| @@ -55,10 +104,24 @@ public interface WxCpOaService { | |||||
| * @param startTime 获取审批记录的开始时间 | * @param startTime 获取审批记录的开始时间 | ||||
| * @param endTime 获取审批记录的结束时间 | * @param endTime 获取审批记录的结束时间 | ||||
| * @param nextSpnum 第一个拉取的审批单号,不填从该时间段的第一个审批单拉取 | * @param nextSpnum 第一个拉取的审批单号,不填从该时间段的第一个审批单拉取 | ||||
| * @throws WxErrorException 异常 | |||||
| * @throws WxErrorException | |||||
| * @see me.chanjar.weixin.cp.api.WxCpOaService#getApprovalInfo | |||||
| * @see me.chanjar.weixin.cp.api.WxCpOaService#getApprovalDetail | |||||
| */ | */ | ||||
| @Deprecated | |||||
| WxCpApprovalDataResult getApprovalData(Date startTime, Date endTime, Long nextSpnum) throws WxErrorException; | WxCpApprovalDataResult getApprovalData(Date startTime, Date endTime, Long nextSpnum) throws WxErrorException; | ||||
| List<WxCpDialRecord> getDialRecord(Date startTime, Date endTime, Integer offset, Integer limit) throws WxErrorException; | |||||
| /** | |||||
| * 获取公费电话拨打记录 | |||||
| * | |||||
| * @param startTime 查询的起始时间戳 | |||||
| * @param endTime 查询的结束时间戳 | |||||
| * @param offset 分页查询的偏移量 | |||||
| * @param limit 分页查询的每页大小,默认为100条,如该参数大于100则按100处理 | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| */ | |||||
| List<WxCpDialRecord> getDialRecord(Date startTime, Date endTime, Integer offset, | |||||
| Integer limit) throws WxErrorException; | |||||
| } | } | ||||
| @@ -5,15 +5,12 @@ import com.google.gson.JsonElement; | |||||
| import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||
| import com.google.gson.JsonParser; | import com.google.gson.JsonParser; | ||||
| import com.google.gson.reflect.TypeToken; | import com.google.gson.reflect.TypeToken; | ||||
| import lombok.NonNull; | |||||
| import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.cp.api.WxCpOaService; | import me.chanjar.weixin.cp.api.WxCpOaService; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.bean.WxCpApprovalDataResult; | |||||
| import me.chanjar.weixin.cp.bean.WxCpCheckinData; | |||||
| import me.chanjar.weixin.cp.bean.WxCpCheckinOption; | |||||
| import me.chanjar.weixin.cp.bean.WxCpDialRecord; | |||||
| import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; | |||||
| import me.chanjar.weixin.cp.bean.oa.*; | |||||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
| import java.util.Date; | import java.util.Date; | ||||
| @@ -22,7 +19,7 @@ import java.util.List; | |||||
| import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Oa.*; | import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Oa.*; | ||||
| /** | /** | ||||
| * . | |||||
| * 企业微信 OA 接口实现 | |||||
| * | * | ||||
| * @author Element | * @author Element | ||||
| * @date 2019-04-06 11:20 | * @date 2019-04-06 11:20 | ||||
| @@ -31,6 +28,9 @@ import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Oa.*; | |||||
| public class WxCpOaServiceImpl implements WxCpOaService { | public class WxCpOaServiceImpl implements WxCpOaService { | ||||
| private final WxCpService mainService; | private final WxCpService mainService; | ||||
| private static final int MONTH_SECONDS = 30 * 24 * 60 * 60; | |||||
| private static final int USER_IDS_LIMIT = 100; | |||||
| @Override | @Override | ||||
| public List<WxCpCheckinData> getCheckinData(Integer openCheckinDataType, Date startTime, Date endTime, | public List<WxCpCheckinData> getCheckinData(Integer openCheckinDataType, Date startTime, Date endTime, | ||||
| List<String> userIdList) throws WxErrorException { | List<String> userIdList) throws WxErrorException { | ||||
| @@ -38,14 +38,14 @@ public class WxCpOaServiceImpl implements WxCpOaService { | |||||
| throw new RuntimeException("starttime and endtime can't be null"); | throw new RuntimeException("starttime and endtime can't be null"); | ||||
| } | } | ||||
| if (userIdList == null || userIdList.size() > 100) { | |||||
| throw new RuntimeException("用户列表不能为空,不超过100个,若用户超过100个,请分批获取"); | |||||
| if (userIdList == null || userIdList.size() > USER_IDS_LIMIT) { | |||||
| throw new RuntimeException("用户列表不能为空,不超过 " + USER_IDS_LIMIT + " 个,若用户超过 " + USER_IDS_LIMIT + " 个,请分批获取"); | |||||
| } | } | ||||
| long endtimestamp = endTime.getTime() / 1000L; | long endtimestamp = endTime.getTime() / 1000L; | ||||
| long starttimestamp = startTime.getTime() / 1000L; | long starttimestamp = startTime.getTime() / 1000L; | ||||
| if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= 30 * 24 * 60 * 60) { | |||||
| if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= MONTH_SECONDS) { | |||||
| throw new RuntimeException("获取记录时间跨度不超过一个月"); | throw new RuntimeException("获取记录时间跨度不超过一个月"); | ||||
| } | } | ||||
| @@ -79,8 +79,8 @@ public class WxCpOaServiceImpl implements WxCpOaService { | |||||
| throw new RuntimeException("datetime can't be null"); | throw new RuntimeException("datetime can't be null"); | ||||
| } | } | ||||
| if (userIdList == null || userIdList.size() > 100) { | |||||
| throw new RuntimeException("用户列表不能为空,不超过100个,若用户超过100个,请分批获取"); | |||||
| if (userIdList == null || userIdList.size() > USER_IDS_LIMIT) { | |||||
| throw new RuntimeException("用户列表不能为空,不超过 " + USER_IDS_LIMIT + " 个,若用户超过 " + USER_IDS_LIMIT + " 个,请分批获取"); | |||||
| } | } | ||||
| JsonArray jsonArray = new JsonArray(); | JsonArray jsonArray = new JsonArray(); | ||||
| @@ -104,6 +104,59 @@ public class WxCpOaServiceImpl implements WxCpOaService { | |||||
| ); | ); | ||||
| } | } | ||||
| @Override | |||||
| public WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime, | |||||
| Integer cursor, Integer size, List<WxCpApprovalInfoQueryFilter> filters) throws WxErrorException { | |||||
| if (cursor == null) { | |||||
| cursor = 0; | |||||
| } | |||||
| if (size == null) { | |||||
| size = 100; | |||||
| } | |||||
| if (size < 0 || size > 100) { | |||||
| throw new IllegalArgumentException("size参数错误,请使用[1-100]填充,默认100"); | |||||
| } | |||||
| JsonObject jsonObject = new JsonObject(); | |||||
| jsonObject.addProperty("starttime", startTime.getTime() / 1000L); | |||||
| jsonObject.addProperty("endtime", endTime.getTime() / 1000L); | |||||
| jsonObject.addProperty("size", size); | |||||
| jsonObject.addProperty("cursor", cursor); | |||||
| if (filters != null && !filters.isEmpty()) { | |||||
| JsonArray filterJsonArray = new JsonArray(); | |||||
| for (WxCpApprovalInfoQueryFilter filter : filters) { | |||||
| filterJsonArray.add(new JsonParser().parse(filter.toJson())); | |||||
| } | |||||
| jsonObject.add("filters", filterJsonArray); | |||||
| } | |||||
| final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_APPROVAL_INFO); | |||||
| String responseContent = this.mainService.post(url, jsonObject.toString()); | |||||
| return WxCpGsonBuilder.create().fromJson(responseContent, WxCpApprovalInfo.class); | |||||
| } | |||||
| @Override | |||||
| public WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime) throws WxErrorException { | |||||
| return this.getApprovalInfo(startTime, endTime, null, null, null); | |||||
| } | |||||
| @Override | |||||
| public WxCpApprovalDetailResult getApprovalDetail(@NonNull String spNo) throws WxErrorException { | |||||
| JsonObject jsonObject = new JsonObject(); | |||||
| jsonObject.addProperty("sp_no", spNo); | |||||
| final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_APPROVAL_DETAIL); | |||||
| String responseContent = this.mainService.post(url, jsonObject.toString()); | |||||
| return WxCpGsonBuilder.create().fromJson(responseContent, WxCpApprovalDetailResult.class); | |||||
| } | |||||
| @Override | @Override | ||||
| public WxCpApprovalDataResult getApprovalData(Date startTime, Date endTime, Long nextSpnum) throws WxErrorException { | public WxCpApprovalDataResult getApprovalData(Date startTime, Date endTime, Long nextSpnum) throws WxErrorException { | ||||
| JsonObject jsonObject = new JsonObject(); | JsonObject jsonObject = new JsonObject(); | ||||
| @@ -139,7 +192,7 @@ public class WxCpOaServiceImpl implements WxCpOaService { | |||||
| long endtimestamp = endTime.getTime() / 1000L; | long endtimestamp = endTime.getTime() / 1000L; | ||||
| long starttimestamp = startTime.getTime() / 1000L; | long starttimestamp = startTime.getTime() / 1000L; | ||||
| if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= 30 * 24 * 60 * 60) { | |||||
| if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= MONTH_SECONDS) { | |||||
| throw new RuntimeException("受限于网络传输,起止时间的最大跨度为30天,如超过30天,则以结束时间为基准向前取30天进行查询"); | throw new RuntimeException("受限于网络传输,起止时间的最大跨度为30天,如超过30天,则以结束时间为基准向前取30天进行查询"); | ||||
| } | } | ||||
| @@ -0,0 +1,21 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import lombok.Data; | |||||
| import me.chanjar.weixin.cp.bean.oa.applydata.Content; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 审批申请数据 | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalApplyData implements Serializable { | |||||
| private static final long serialVersionUID = 4061352949894274704L; | |||||
| private List<Content> contents; | |||||
| } | |||||
| @@ -0,0 +1,23 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * 申请人信息 | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalApplyer extends WxCpOperator implements Serializable { | |||||
| private static final long serialVersionUID = -8974662568286821271L; | |||||
| /** | |||||
| * 申请人所在部门id | |||||
| */ | |||||
| @SerializedName("partyid") | |||||
| private String partyId; | |||||
| } | |||||
| @@ -0,0 +1,48 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 审批申请备注信息 | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalComment implements Serializable { | |||||
| private static final long serialVersionUID = -5430367411926856292L; | |||||
| /** | |||||
| * 备注人信息 | |||||
| */ | |||||
| private WxCpOperator commentUserInfo; | |||||
| /** | |||||
| * 备注提交时间戳,Unix时间戳 | |||||
| */ | |||||
| @SerializedName("commenttime") | |||||
| private Long commentTime; | |||||
| /** | |||||
| * 备注id | |||||
| */ | |||||
| @SerializedName("commentid") | |||||
| private String commentId; | |||||
| /** | |||||
| * 备注文本内容 | |||||
| */ | |||||
| @SerializedName("commentcontent") | |||||
| private String commentContent; | |||||
| /** | |||||
| * 备注附件id,可能有多个 | |||||
| */ | |||||
| @SerializedName("media_id") | |||||
| private List<String> mediaIds; | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| package me.chanjar.weixin.cp.bean; | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||
| import lombok.Data; | import lombok.Data; | ||||
| @@ -12,6 +12,7 @@ import java.util.Map; | |||||
| * @author Element | * @author Element | ||||
| * @date 2019-04-06 14:36 | * @date 2019-04-06 14:36 | ||||
| */ | */ | ||||
| @Deprecated | |||||
| @Data | @Data | ||||
| public class WxCpApprovalDataResult implements Serializable { | public class WxCpApprovalDataResult implements Serializable { | ||||
| private static final long serialVersionUID = -1046940445840716590L; | private static final long serialVersionUID = -1046940445840716590L; | ||||
| @@ -0,0 +1,78 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 审批申请详情 | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalDetail implements Serializable { | |||||
| private static final long serialVersionUID = 1353393306564207170L; | |||||
| /** | |||||
| * 审批编号 | |||||
| */ | |||||
| @SerializedName("sp_no") | |||||
| private String spNo; | |||||
| /** | |||||
| * 审批申请类型名称(审批模板名称) | |||||
| */ | |||||
| @SerializedName("sp_name") | |||||
| private String spName; | |||||
| /** | |||||
| * 申请单状态:1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付 | |||||
| */ | |||||
| @SerializedName("sp_status") | |||||
| private WxCpSpStatus spStatus; | |||||
| /** | |||||
| * 审批模板id。可在“获取审批申请详情”、“审批状态变化回调通知”中获得,也可在审批模板的模板编辑页面链接中获得。 | |||||
| */ | |||||
| @SerializedName("template_id") | |||||
| private String templateId; | |||||
| /** | |||||
| * 审批申请提交时间,Unix时间戳 | |||||
| */ | |||||
| @SerializedName("apply_time") | |||||
| private Long applyTime; | |||||
| /** | |||||
| * 申请人信息 | |||||
| */ | |||||
| private WxCpApprovalApplyer applyer; | |||||
| /** | |||||
| * 审批流程信息,可能有多个审批节点 | |||||
| */ | |||||
| @SerializedName("sp_record") | |||||
| private WxCpApprovalRecord spRecord; | |||||
| /** | |||||
| * 抄送信息,可能有多个抄送节点 | |||||
| */ | |||||
| @SerializedName("notifyer") | |||||
| private WxCpOperator notifyer; | |||||
| /** | |||||
| * 审批申请数据 | |||||
| */ | |||||
| @SerializedName("apply_data") | |||||
| private WxCpApprovalApplyData applyData; | |||||
| /** | |||||
| * 审批申请备注信息,可能有多个备注节点 | |||||
| */ | |||||
| @SerializedName("comments") | |||||
| private List<WxCpApprovalComment> comments; | |||||
| } | |||||
| @@ -0,0 +1,27 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * 审批申请详情响应结果 | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalDetailResult implements Serializable { | |||||
| private static final long serialVersionUID = 3909779949756252918L; | |||||
| @SerializedName("errcode") | |||||
| private Integer errCode; | |||||
| @SerializedName("errmsg") | |||||
| private String errMsg; | |||||
| @SerializedName("info") | |||||
| private WxCpApprovalDetail info; | |||||
| } | |||||
| @@ -0,0 +1,29 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| /** | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalInfo implements Serializable { | |||||
| private static final long serialVersionUID = 7387181805254287167L; | |||||
| @SerializedName("errcode") | |||||
| private Integer errCode; | |||||
| @SerializedName("errmsg") | |||||
| private String errMsg; | |||||
| @SerializedName("sp_no_list") | |||||
| private List<String> spNoList; | |||||
| @SerializedName("next_cursor") | |||||
| private Integer nextCursor; | |||||
| } | |||||
| @@ -0,0 +1,61 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * <pre> | |||||
| * 批量获取审批单号的筛选条件,可对批量拉取的审批申请设置约束条件,支持设置多个条件 | |||||
| * 注意: | |||||
| * 仅“部门”支持同时配置多个筛选条件。 | |||||
| * 不同类型的筛选条件之间为“与”的关系,同类型筛选条件之间为“或”的关系 | |||||
| * </pre> | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalInfoQueryFilter implements Serializable { | |||||
| private static final long serialVersionUID = 3318064927980231802L; | |||||
| private WxCpApprovalInfoQueryFilter.KEY key; | |||||
| private Object value; | |||||
| public String toJson() { | |||||
| return WxGsonBuilder.create().toJson(this); | |||||
| } | |||||
| public static enum KEY { | |||||
| /** | |||||
| * template_id - 模板类型/模板id; | |||||
| */ | |||||
| @SerializedName("template_id") | |||||
| TEMPLATE_ID("template_id"), | |||||
| /** | |||||
| * creator - 申请人; | |||||
| */ | |||||
| @SerializedName("creator") | |||||
| CREATOR("creator"), | |||||
| /** | |||||
| * department - 审批单提单者所在部门; | |||||
| */ | |||||
| @SerializedName("department") | |||||
| DEPARTMENT("department"), | |||||
| /** | |||||
| * sp_status - 审批状态。 | |||||
| */ | |||||
| @SerializedName("sp_status") | |||||
| SP_STATUS("sp_status"); | |||||
| private String value; | |||||
| private KEY(String value) { | |||||
| this.value = value; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,26 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 审批流程信息 | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalRecord implements Serializable { | |||||
| private static final long serialVersionUID = -327230786004105887L; | |||||
| @SerializedName("sp_status") | |||||
| private WxCpRecordSpStatus status; | |||||
| @SerializedName("approverattr") | |||||
| private WxCpApproverAttr approverAttr; | |||||
| private List<WxCpApprovalRecordDetail> details; | |||||
| } | |||||
| @@ -0,0 +1,48 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 审批节点详情 | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalRecordDetail implements Serializable { | |||||
| private static final long serialVersionUID = -9142079764088495301L; | |||||
| /** | |||||
| * 分支审批人 | |||||
| */ | |||||
| @SerializedName("approver") | |||||
| private WxCpOperator approver; | |||||
| /** | |||||
| * 审批意见 | |||||
| */ | |||||
| @SerializedName("speech") | |||||
| private String speech; | |||||
| /** | |||||
| * 分支审批人审批状态 | |||||
| */ | |||||
| @SerializedName("sp_status") | |||||
| private WxCpRecordSpStatus spStatus; | |||||
| /** | |||||
| * 节点分支审批人审批操作时间戳,0表示未操作 | |||||
| */ | |||||
| @SerializedName("sptime") | |||||
| private Long spTime; | |||||
| /** | |||||
| * 节点分支审批人审批意见附件 | |||||
| */ | |||||
| @SerializedName("media_id") | |||||
| private List<String> mediaIds; | |||||
| } | |||||
| @@ -0,0 +1,28 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| /** | |||||
| * 审批方式 | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| public enum WxCpApproverAttr { | |||||
| /** | |||||
| * 或签 | |||||
| */ | |||||
| @SerializedName("1") | |||||
| ONE_SIGN(1), | |||||
| /** | |||||
| * 会签 | |||||
| */ | |||||
| @SerializedName("2") | |||||
| ALL_SIGN(2); | |||||
| private Integer attr; | |||||
| private WxCpApproverAttr(Integer attr) { | |||||
| this.attr = attr; | |||||
| } | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| package me.chanjar.weixin.cp.bean; | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||
| import lombok.Data; | import lombok.Data; | ||||
| @@ -1,4 +1,4 @@ | |||||
| package me.chanjar.weixin.cp.bean; | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||
| import lombok.Data; | import lombok.Data; | ||||
| @@ -1,4 +1,4 @@ | |||||
| package me.chanjar.weixin.cp.bean; | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||
| import lombok.Data; | import lombok.Data; | ||||
| @@ -0,0 +1,24 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * 企业微信操作人 | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpOperator implements Serializable { | |||||
| private static final long serialVersionUID = 5797144853574346736L; | |||||
| /** | |||||
| * 企业微信userid | |||||
| */ | |||||
| @SerializedName("userid") | |||||
| private String userId; | |||||
| } | |||||
| @@ -0,0 +1,41 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| /** | |||||
| * 审批记录(节点)分支审批状态 | |||||
| * | |||||
| * 1-审批中;2-已同意;3-已驳回;4-已转审 | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| public enum WxCpRecordSpStatus { | |||||
| /** | |||||
| * 审批中 | |||||
| */ | |||||
| @SerializedName("1") | |||||
| AUDITING(1), | |||||
| /** | |||||
| * 已同意 | |||||
| */ | |||||
| @SerializedName("2") | |||||
| PASSED(2), | |||||
| /** | |||||
| * 已驳回 | |||||
| */ | |||||
| @SerializedName("3") | |||||
| REJECTED(3), | |||||
| /** | |||||
| * 已转审 | |||||
| */ | |||||
| @SerializedName("4") | |||||
| TURNED(4); | |||||
| private Integer status; | |||||
| private WxCpRecordSpStatus(Integer status) { | |||||
| this.status = status; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,54 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| /** | |||||
| * 审批单状态 | |||||
| * (1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付) | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| public enum WxCpSpStatus { | |||||
| /** | |||||
| * 审批中 | |||||
| */ | |||||
| @SerializedName("1") | |||||
| AUDITING(1), | |||||
| /** | |||||
| * 已通过 | |||||
| */ | |||||
| @SerializedName("2") | |||||
| PASSED(2), | |||||
| /** | |||||
| * 已驳回 | |||||
| */ | |||||
| @SerializedName("3") | |||||
| REJECTED(3), | |||||
| /** | |||||
| * 已撤销 | |||||
| */ | |||||
| @SerializedName("4") | |||||
| UNDONE(4), | |||||
| /** | |||||
| * 通过后撤销 | |||||
| */ | |||||
| @SerializedName("6") | |||||
| PASS_UNDONE(6), | |||||
| /** | |||||
| * 已删除 | |||||
| */ | |||||
| @SerializedName("7") | |||||
| DELETED(7), | |||||
| /** | |||||
| * 已支付 | |||||
| */ | |||||
| @SerializedName("10") | |||||
| ALREADY_PAY(10); | |||||
| private Integer status; | |||||
| private WxCpSpStatus(Integer status) { | |||||
| this.status = status; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,24 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.applydata; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class Content implements Serializable { | |||||
| private static final long serialVersionUID = 8456821731930526935L; | |||||
| private String control; | |||||
| private String id; | |||||
| @SerializedName("title") | |||||
| private List<ContentTitle> titles; | |||||
| private ContentValue value; | |||||
| } | |||||
| @@ -0,0 +1,18 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.applydata; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class ContentTitle implements Serializable { | |||||
| private static final long serialVersionUID = -4501999157383517007L; | |||||
| private String text; | |||||
| private String lang; | |||||
| } | |||||
| @@ -0,0 +1,103 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.applydata; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class ContentValue implements Serializable { | |||||
| private static final long serialVersionUID = -5607678965965065261L; | |||||
| private String text; | |||||
| @SerializedName("new_number") | |||||
| private Integer newNumber; | |||||
| @SerializedName("new_money") | |||||
| private Integer newMoney; | |||||
| private ContentValue.Date date; | |||||
| private ContentValue.Selector selector; | |||||
| private List<ContentValue.Member> members; | |||||
| private List<ContentValue.Department> departments; | |||||
| private List<ContentValue.File> files; | |||||
| private List<ContentValue.Child> children; | |||||
| @Data | |||||
| public static class Date implements Serializable { | |||||
| private static final long serialVersionUID = -6181554080062231138L; | |||||
| private String type; | |||||
| @SerializedName("s_timestamp") | |||||
| private Long timestamp; | |||||
| } | |||||
| @Data | |||||
| public static class Selector implements Serializable { | |||||
| private static final long serialVersionUID = 7305458759126951773L; | |||||
| private String type; | |||||
| private List<Option> options; | |||||
| @Data | |||||
| public static class Option implements Serializable { | |||||
| private static final long serialVersionUID = -3471071106328280252L; | |||||
| private String key; | |||||
| @SerializedName("value") | |||||
| private List<ContentTitle> values; | |||||
| } | |||||
| } | |||||
| @Data | |||||
| public static class Member implements Serializable { | |||||
| private static final long serialVersionUID = 1316551341955496067L; | |||||
| @SerializedName("userid") | |||||
| private String userId; | |||||
| private String name; | |||||
| } | |||||
| @Data | |||||
| public static class Department implements Serializable { | |||||
| private static final long serialVersionUID = -2513762192924826234L; | |||||
| @SerializedName("openapi_id") | |||||
| private String openApiId; | |||||
| private String name; | |||||
| } | |||||
| @Data | |||||
| public static class File implements Serializable { | |||||
| private static final long serialVersionUID = 3890971381800855142L; | |||||
| @SerializedName("file_id") | |||||
| private String fileId; | |||||
| } | |||||
| @Data | |||||
| public static class Child implements Serializable { | |||||
| private static final long serialVersionUID = -3500102073821161558L; | |||||
| private List<Content> list; | |||||
| } | |||||
| } | |||||
| @@ -64,8 +64,11 @@ public final class WxCpApiPathConsts { | |||||
| public static class Oa { | public static class Oa { | ||||
| public static final String GET_CHECKIN_DATA = "/cgi-bin/checkin/getcheckindata"; | public static final String GET_CHECKIN_DATA = "/cgi-bin/checkin/getcheckindata"; | ||||
| public static final String GET_CHECKIN_OPTION = "/cgi-bin/checkin/getcheckinoption"; | public static final String GET_CHECKIN_OPTION = "/cgi-bin/checkin/getcheckinoption"; | ||||
| public static final String GET_APPROVAL_DATA = "/cgi-bin/corp/getapprovaldata"; | |||||
| public static final String GET_APPROVAL_INFO = "/cgi-bin/oa/getapprovalinfo"; | |||||
| public static final String GET_APPROVAL_DETAIL = "/cgi-bin/oa/getapprovaldetail"; | |||||
| public static final String GET_DIAL_RECORD = "/cgi-bin/dial/get_dial_record"; | public static final String GET_DIAL_RECORD = "/cgi-bin/dial/get_dial_record"; | ||||
| @Deprecated | |||||
| public static final String GET_APPROVAL_DATA = "/cgi-bin/corp/getapprovaldata"; | |||||
| } | } | ||||
| public static class Tag { | public static class Tag { | ||||
| @@ -1,33 +1,40 @@ | |||||
| package me.chanjar.weixin.cp.api.impl; | package me.chanjar.weixin.cp.api.impl; | ||||
| import com.google.common.collect.Lists; | |||||
| import com.google.gson.Gson; | import com.google.gson.Gson; | ||||
| import com.google.inject.Inject; | import com.google.inject.Inject; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.cp.api.ApiTestModule; | import me.chanjar.weixin.cp.api.ApiTestModule; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.bean.WxCpCheckinData; | |||||
| import me.chanjar.weixin.cp.bean.WxCpCheckinOption; | |||||
| import me.chanjar.weixin.cp.bean.oa.WxCpApprovalDetailResult; | |||||
| import me.chanjar.weixin.cp.bean.oa.WxCpApprovalInfo; | |||||
| import me.chanjar.weixin.cp.bean.oa.WxCpCheckinData; | |||||
| import me.chanjar.weixin.cp.bean.oa.WxCpCheckinOption; | |||||
| import org.apache.commons.lang3.time.DateFormatUtils; | import org.apache.commons.lang3.time.DateFormatUtils; | ||||
| import org.testng.annotations.Guice; | import org.testng.annotations.Guice; | ||||
| import org.testng.annotations.Test; | import org.testng.annotations.Test; | ||||
| import org.testng.collections.Lists; | |||||
| import java.text.ParseException; | import java.text.ParseException; | ||||
| import java.util.ArrayList; | |||||
| import java.util.Date; | import java.util.Date; | ||||
| import java.util.List; | import java.util.List; | ||||
| import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||
| /** | /** | ||||
| * 企业微信 OA数据接口 测试用例 | |||||
| * | |||||
| * @author Element | * @author Element | ||||
| * @date 2019-04-20 13:46 | |||||
| */ | */ | ||||
| @Guice(modules = ApiTestModule.class) | @Guice(modules = ApiTestModule.class) | ||||
| public class WxCpOaServiceImplTest { | public class WxCpOaServiceImplTest { | ||||
| @Inject | @Inject | ||||
| protected WxCpService wxService; | protected WxCpService wxService; | ||||
| @Inject | |||||
| protected Gson gson; | |||||
| @Test | @Test | ||||
| public void testGetCheckinData() throws ParseException, WxErrorException { | public void testGetCheckinData() throws ParseException, WxErrorException { | ||||
| Date startTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-04-11"); | Date startTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-04-11"); | ||||
| @@ -37,13 +44,43 @@ public class WxCpOaServiceImplTest { | |||||
| .getCheckinData(1, startTime, endTime, Lists.newArrayList("binary")); | .getCheckinData(1, startTime, endTime, Lists.newArrayList("binary")); | ||||
| assertThat(results).isNotNull(); | assertThat(results).isNotNull(); | ||||
| System.out.println("results "); | |||||
| System.out.println(gson.toJson(results)); | |||||
| } | } | ||||
| @Test | @Test | ||||
| public void testGetCheckinOption() throws WxErrorException { | public void testGetCheckinOption() throws WxErrorException { | ||||
| Date now = new Date(); | Date now = new Date(); | ||||
| List<WxCpCheckinOption> results = wxService.getOAService() | |||||
| .getCheckinOption(now, Lists.newArrayList("binary")); | |||||
| List<WxCpCheckinOption> results = wxService.getOAService().getCheckinOption(now, Lists.newArrayList("binary")); | |||||
| assertThat(results).isNotNull(); | assertThat(results).isNotNull(); | ||||
| System.out.println("results "); | |||||
| System.out.println(gson.toJson(results)); | |||||
| } | |||||
| @Test | |||||
| public void testGetApprovalInfo() throws WxErrorException, ParseException { | |||||
| Date startTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-04-11"); | |||||
| Date endTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-05-10"); | |||||
| WxCpApprovalInfo result = wxService.getOAService().getApprovalInfo(startTime, endTime); | |||||
| assertThat(result).isNotNull(); | |||||
| System.out.println("result "); | |||||
| System.out.println(gson.toJson(result)); | |||||
| } | |||||
| @Test | |||||
| public void testGetApprovalDetail() throws WxErrorException { | |||||
| String spNo = "201909270001"; | |||||
| WxCpApprovalDetailResult result = wxService.getOAService().getApprovalDetail(spNo); | |||||
| assertThat(result).isNotNull(); | |||||
| System.out.println("result "); | |||||
| System.out.println(gson.toJson(result)); | |||||
| } | } | ||||
| } | } | ||||