diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpHrService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpHrService.java
new file mode 100644
index 000000000..fdfe536d1
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpHrService.java
@@ -0,0 +1,60 @@
+package me.chanjar.weixin.cp.api;
+
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.bean.hr.WxCpHrEmployeeFieldData;
+import me.chanjar.weixin.cp.bean.hr.WxCpHrEmployeeFieldDataResp;
+import me.chanjar.weixin.cp.bean.hr.WxCpHrEmployeeFieldInfoResp;
+
+import java.util.List;
+
+/**
+ * 人事助手相关接口.
+ * 官方文档:https://developer.work.weixin.qq.com/document/path/99132
+ *
+ * @author leejoker created on 2024-01-01
+ */
+public interface WxCpHrService {
+
+ /**
+ * 获取员工档案字段信息.
+ *
+ * 请求方式:POST(HTTPS)
+ * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/hr/employee/get_field_info?access_token=ACCESS_TOKEN
+ * 权限说明:
+ * 需要配置人事助手的secret,调用接口前需给对应成员赋予人事小助手应用的权限。
+ *
+ * @param fields 指定字段key列表,不填则返回全部字段
+ * @return 字段信息响应 wx cp hr employee field info resp
+ * @throws WxErrorException the wx error exception
+ */
+ WxCpHrEmployeeFieldInfoResp getFieldInfo(List fields) throws WxErrorException;
+
+ /**
+ * 获取员工档案数据.
+ *
+ * 请求方式:POST(HTTPS)
+ * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/hr/employee/get_employee_field_info?access_token=ACCESS_TOKEN
+ * 权限说明:
+ * 需要配置人事助手的secret,调用接口前需给对应成员赋予人事小助手应用的权限。
+ *
+ * @param userids 员工userid列表,不超过20个
+ * @param fields 指定字段key列表,不填则返回全部字段
+ * @return 员工档案数据响应 wx cp hr employee field data resp
+ * @throws WxErrorException the wx error exception
+ */
+ WxCpHrEmployeeFieldDataResp getEmployeeFieldInfo(List userids, List fields) throws WxErrorException;
+
+ /**
+ * 更新员工档案数据.
+ *
+ * 请求方式:POST(HTTPS)
+ * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/hr/employee/update_employee_field_info?access_token=ACCESS_TOKEN
+ * 权限说明:
+ * 需要配置人事助手的secret,调用接口前需给对应成员赋予人事小助手应用的权限。
+ *
+ * @param userid 员工userid
+ * @param fieldList 字段数据列表
+ * @throws WxErrorException the wx error exception
+ */
+ void updateEmployeeFieldInfo(String userid, List fieldList) 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 76012a281..3427d656e 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
@@ -594,4 +594,11 @@ public interface WxCpService extends WxService {
* @return 智能机器人服务 intelligent robot service
*/
WxCpIntelligentRobotService getIntelligentRobotService();
+
+ /**
+ * 获取人事助手服务
+ *
+ * @return 人事助手服务 hr service
+ */
+ WxCpHrService getHrService();
}
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 bc18c9bc7..9c6932930 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
@@ -75,6 +75,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
private final WxCpMeetingService meetingService = new WxCpMeetingServiceImpl(this);
private final WxCpCorpGroupService corpGroupService = new WxCpCorpGroupServiceImpl(this);
private final WxCpIntelligentRobotService intelligentRobotService = new WxCpIntelligentRobotServiceImpl(this);
+ private final WxCpHrService hrService = new WxCpHrServiceImpl(this);
/**
* 全局的是否正在刷新access token的锁.
@@ -708,4 +709,9 @@ public WxCpCorpGroupService getCorpGroupService() {
public WxCpIntelligentRobotService getIntelligentRobotService() {
return this.intelligentRobotService;
}
+
+ @Override
+ public WxCpHrService getHrService() {
+ return this.hrService;
+ }
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpHrServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpHrServiceImpl.java
new file mode 100644
index 000000000..7c48b0bd5
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpHrServiceImpl.java
@@ -0,0 +1,77 @@
+package me.chanjar.weixin.cp.api.impl;
+
+import com.google.gson.JsonObject;
+import lombok.RequiredArgsConstructor;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.api.WxCpHrService;
+import me.chanjar.weixin.cp.api.WxCpService;
+import me.chanjar.weixin.cp.bean.hr.WxCpHrEmployeeFieldData;
+import me.chanjar.weixin.cp.bean.hr.WxCpHrEmployeeFieldDataResp;
+import me.chanjar.weixin.cp.bean.hr.WxCpHrEmployeeFieldInfoResp;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+import java.util.List;
+
+import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Hr.*;
+
+/**
+ * 人事助手相关接口实现类.
+ * 官方文档:https://developer.work.weixin.qq.com/document/path/99132
+ *
+ * @author leejoker created on 2024-01-01
+ */
+@RequiredArgsConstructor
+public class WxCpHrServiceImpl implements WxCpHrService {
+
+ private final WxCpService cpService;
+
+ @Override
+ public WxCpHrEmployeeFieldInfoResp getFieldInfo(List fields) throws WxErrorException {
+ JsonObject jsonObject = new JsonObject();
+ if (fields != null && !fields.isEmpty()) {
+ jsonObject.add("fields", WxCpGsonBuilder.create().toJsonTree(fields));
+ }
+ String response = this.cpService.post(
+ this.cpService.getWxCpConfigStorage().getApiUrl(GET_FIELD_INFO),
+ jsonObject.toString()
+ );
+ return WxCpHrEmployeeFieldInfoResp.fromJson(response);
+ }
+
+ @Override
+ public WxCpHrEmployeeFieldDataResp getEmployeeFieldInfo(List userids, List fields) throws WxErrorException {
+ if (userids == null || userids.isEmpty()) {
+ throw new IllegalArgumentException("userids 不能为空");
+ }
+ if (userids.size() > 20) {
+ throw new IllegalArgumentException("userids 每次最多传入20个");
+ }
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.add("userids", WxCpGsonBuilder.create().toJsonTree(userids));
+ if (fields != null && !fields.isEmpty()) {
+ jsonObject.add("fields", WxCpGsonBuilder.create().toJsonTree(fields));
+ }
+ String response = this.cpService.post(
+ this.cpService.getWxCpConfigStorage().getApiUrl(GET_EMPLOYEE_FIELD_INFO),
+ jsonObject.toString()
+ );
+ return WxCpHrEmployeeFieldDataResp.fromJson(response);
+ }
+
+ @Override
+ public void updateEmployeeFieldInfo(String userid, List fieldList) throws WxErrorException {
+ if (userid == null || userid.trim().isEmpty()) {
+ throw new IllegalArgumentException("userid 不能为空");
+ }
+ if (fieldList == null || fieldList.isEmpty()) {
+ throw new IllegalArgumentException("fieldList 不能为空");
+ }
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.addProperty("userid", userid);
+ jsonObject.add("field_list", WxCpGsonBuilder.create().toJsonTree(fieldList));
+ this.cpService.post(
+ this.cpService.getWxCpConfigStorage().getApiUrl(UPDATE_EMPLOYEE_FIELD_INFO),
+ jsonObject.toString()
+ );
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/hr/WxCpHrEmployeeFieldData.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/hr/WxCpHrEmployeeFieldData.java
new file mode 100644
index 000000000..971e5958d
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/hr/WxCpHrEmployeeFieldData.java
@@ -0,0 +1,52 @@
+package me.chanjar.weixin.cp.bean.hr;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 人事助手-员工档案数据(单个员工).
+ *
+ * @author leejoker created on 2024-01-01
+ */
+@Data
+@NoArgsConstructor
+public class WxCpHrEmployeeFieldData implements Serializable {
+ private static final long serialVersionUID = 4593693598671765396L;
+
+ /**
+ * 员工userid.
+ */
+ @SerializedName("userid")
+ private String userid;
+
+ /**
+ * 字段数据列表.
+ */
+ @SerializedName("field_list")
+ private List fieldList;
+
+ /**
+ * 字段数据项.
+ */
+ @Data
+ @NoArgsConstructor
+ public static class FieldItem implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 字段key.
+ */
+ @SerializedName("field_key")
+ private String fieldKey;
+
+ /**
+ * 字段值.
+ */
+ @SerializedName("field_value")
+ private WxCpHrEmployeeFieldValue fieldValue;
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/hr/WxCpHrEmployeeFieldDataResp.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/hr/WxCpHrEmployeeFieldDataResp.java
new file mode 100644
index 000000000..07e286c2e
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/hr/WxCpHrEmployeeFieldDataResp.java
@@ -0,0 +1,38 @@
+package me.chanjar.weixin.cp.bean.hr;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.cp.bean.WxCpBaseResp;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+import java.util.List;
+
+/**
+ * 人事助手-获取员工档案数据响应.
+ *
+ * @author leejoker created on 2024-01-01
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class WxCpHrEmployeeFieldDataResp extends WxCpBaseResp {
+ private static final long serialVersionUID = 6593693598671765396L;
+
+ /**
+ * 员工档案数据列表.
+ */
+ @SerializedName("employee_field_list")
+ private List employeeFieldList;
+
+ /**
+ * From json wx cp hr employee field data resp.
+ *
+ * @param json the json
+ * @return the wx cp hr employee field data resp
+ */
+ public static WxCpHrEmployeeFieldDataResp fromJson(String json) {
+ return WxCpGsonBuilder.create().fromJson(json, WxCpHrEmployeeFieldDataResp.class);
+ }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/hr/WxCpHrEmployeeFieldInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/hr/WxCpHrEmployeeFieldInfo.java
new file mode 100644
index 000000000..e355d8cc6
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/hr/WxCpHrEmployeeFieldInfo.java
@@ -0,0 +1,103 @@
+package me.chanjar.weixin.cp.bean.hr;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 人事助手-员工档案字段信息.
+ *
+ * @author leejoker created on 2024-01-01
+ */
+@Data
+@NoArgsConstructor
+public class WxCpHrEmployeeFieldInfo implements Serializable {
+ private static final long serialVersionUID = 2593693598671765396L;
+
+ /**
+ * 字段key.
+ */
+ @SerializedName("field_key")
+ private String fieldKey;
+
+ /**
+ * 字段英文名称.
+ */
+ @SerializedName("field_en_name")
+ private String fieldEnName;
+
+ /**
+ * 字段中文名称.
+ */
+ @SerializedName("field_zh_name")
+ private String fieldZhName;
+
+ /**
+ * 字段类型.
+ * 具体取值参见 {@link WxCpHrFieldType}
+ */
+ @SerializedName("field_type")
+ private Integer fieldType;
+
+ /**
+ * 获取字段类型枚举.
+ *
+ * @return 字段类型枚举,未匹配时返回 null
+ */
+ public WxCpHrFieldType getFieldTypeEnum() {
+ return fieldType == null ? null : WxCpHrFieldType.fromCode(fieldType);
+ }
+
+ /**
+ * 是否系统字段.
+ * 0: 否
+ * 1: 是
+ */
+ @SerializedName("is_sys")
+ private Integer isSys;
+
+ /**
+ * 字段详情.
+ */
+ @SerializedName("field_detail")
+ private FieldDetail fieldDetail;
+
+ /**
+ * 字段详情.
+ */
+ @Data
+ @NoArgsConstructor
+ public static class FieldDetail implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 选项列表(单选/多选字段专用).
+ */
+ @SerializedName("option_list")
+ private List