提交 28209aec 编写于 作者: F fancy

华为WeLink同步组织用户功能

上级 7960233a
{
"enable": false,
"clientId": "",
"clientSecret": "",
"syncCron": "10 0/10 * * * ?",
"forceSyncCron": "10 45 8,12 * * ?",
"oapiAddress": "https://open.welink.huaweicloud.com/api"
}
\ No newline at end of file
...@@ -61,6 +61,7 @@ public class Config { ...@@ -61,6 +61,7 @@ public class Config {
public static final String PATH_CONFIG_PROCESSPLATFORM = "config/processPlatform.json"; public static final String PATH_CONFIG_PROCESSPLATFORM = "config/processPlatform.json";
public static final String PATH_CONFIG_QUERY = "config/query.json"; public static final String PATH_CONFIG_QUERY = "config/query.json";
public static final String PATH_CONFIG_DINGDING = "config/dingding.json"; public static final String PATH_CONFIG_DINGDING = "config/dingding.json";
public static final String PATH_CONFIG_WELINK = "config/welink.json";
public static final String PATH_CONFIG_ZHENGWUDINGDING = "config/zhengwuDingding.json"; public static final String PATH_CONFIG_ZHENGWUDINGDING = "config/zhengwuDingding.json";
public static final String PATH_CONFIG_QIYEWEIXIN = "config/qiyeweixin.json"; public static final String PATH_CONFIG_QIYEWEIXIN = "config/qiyeweixin.json";
public static final String PATH_CONFIG_LOGLEVEL = "config/logLevel.json"; public static final String PATH_CONFIG_LOGLEVEL = "config/logLevel.json";
...@@ -1041,6 +1042,23 @@ public class Config { ...@@ -1041,6 +1042,23 @@ public class Config {
return instance().dingding; return instance().dingding;
} }
private WeLink weLink;
public static WeLink weLink() throws Exception {
if (null == instance().weLink) {
synchronized (Config.class) {
if (null == instance().weLink) {
WeLink obj = BaseTools.readConfigObject(PATH_CONFIG_WELINK, WeLink.class);
if (null == obj) {
obj = WeLink.defaultInstance();
}
instance().weLink = obj;
}
}
}
return instance().weLink;
}
private Qiyeweixin qiyeweixin; private Qiyeweixin qiyeweixin;
public static Qiyeweixin qiyeweixin() throws Exception { public static Qiyeweixin qiyeweixin() throws Exception {
......
package com.x.base.core.project.config;
import com.x.base.core.project.exception.PromptException;
class ExceptionWeLinkAccessToken extends PromptException {
private static final long serialVersionUID = -3439770681867963457L;
ExceptionWeLinkAccessToken(String code, String message) {
super("获取WeLink access token 失败,错误代码:{}, 错误消息:{}.", code, message);
}
}
\ No newline at end of file
package com.x.base.core.project.config;
import com.x.base.core.project.annotation.FieldDescribe;
import com.x.base.core.project.connection.HttpConnection;
import com.x.base.core.project.gson.XGsonBuilder;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.Calendar;
import java.util.Date;
/**
* Created by fancyLou on 2020-07-24.
* Copyright © 2020 O2. All rights reserved.
*/
public class WeLink extends ConfigObject {
@FieldDescribe("是否启用")
private Boolean enable;
@FieldDescribe("WeLink应用的client_id")
private String clientId;
@FieldDescribe("WeLink应用的client_secret")
private String clientSecret;
@FieldDescribe("组织同步cron,默认每10分钟同步一次.")
private String syncCron;
@FieldDescribe("强制拉入同步cron,默认在每天的8点和12点强制进行同步.")
private String forceSyncCron;
@FieldDescribe("WeLink api服务器地址")
private String oapiAddress;
public static WeLink defaultInstance() {
return new WeLink();
}
public static final Boolean default_enable = false;
public static final String default_clientId = "";
public static final String default_clientSecret = "";
public static final String default_syncCron = "10 0/10 * * * ?";
public static final String default_forceSyncCron = "10 45 8,12 * * ?";
public static final String default_oapiAddress = "https://open.welink.huaweicloud.com/api";
public WeLink() {
this.enable = default_enable;
this.clientId = default_clientId;
this.clientSecret = default_clientSecret;
this.syncCron = default_syncCron;
this.forceSyncCron = default_forceSyncCron;
this.oapiAddress = default_oapiAddress;
}
private static String cachedAccessToken;
private static Date cachedAccessTokenDate;
public static class AccessTokenReq {
private String client_id;
private String client_secret;
public String getClient_id() {
return client_id;
}
public void setClient_id(String client_id) {
this.client_id = client_id;
}
public String getClient_secret() {
return client_secret;
}
public void setClient_secret(String client_secret) {
this.client_secret = client_secret;
}
}
public static class AccessTokenResp {
private String access_token;
private String code;
private String message;
private Integer expires_in;
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Integer getExpires_in() {
return expires_in;
}
public void setExpires_in(Integer expires_in) {
this.expires_in = expires_in;
}
}
/**
* 获取WeLink AccessToken
* @return
* @throws Exception
*/
public String accessToken() throws Exception {
if ((StringUtils.isNotEmpty(cachedAccessToken) && (null != cachedAccessTokenDate))
&& (cachedAccessTokenDate.after(new Date()))) {
return cachedAccessToken;
} else {
String address = this.getOapiAddress() + "/auth/v2/tickets";
AccessTokenReq req = new AccessTokenReq();
req.setClient_id(this.getClientId());
req.setClient_secret(this.getClientSecret());
AccessTokenResp resp = HttpConnection.postAsObject(address, null, XGsonBuilder.instance().toJson(req), AccessTokenResp.class);
if (!resp.getCode().equals("0")) {
throw new ExceptionWeLinkAccessToken(resp.getCode(), resp.getMessage());
}
cachedAccessToken = resp.getAccess_token();
Integer second = resp.expires_in;//过期时间 秒
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, (second - 300));
cachedAccessTokenDate = cal.getTime();
return cachedAccessToken;
}
}
public Boolean getEnable() {
return BooleanUtils.isTrue(this.enable);
}
public void setEnable(Boolean enable) {
this.enable = enable;
}
public String getClientId() {
return StringUtils.isEmpty(this.clientId) ? default_clientId : this.clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return StringUtils.isEmpty(this.clientSecret) ? default_clientSecret : this.clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getSyncCron() {
return StringUtils.isEmpty(this.syncCron) ? default_syncCron : this.syncCron;
}
public void setSyncCron(String syncCron) {
this.syncCron = syncCron;
}
public String getForceSyncCron() {
return StringUtils.isEmpty(this.forceSyncCron) ? default_forceSyncCron : this.forceSyncCron;
}
public void setForceSyncCron(String forceSyncCron) {
this.forceSyncCron = forceSyncCron;
}
public String getOapiAddress() {
return StringUtils.isEmpty(this.oapiAddress) ? default_oapiAddress : this.oapiAddress;
}
public void setOapiAddress(String oapiAddress) {
this.oapiAddress = oapiAddress;
}
}
...@@ -180,7 +180,7 @@ public class Person extends SliceJpaObject { ...@@ -180,7 +180,7 @@ public class Person extends SliceJpaObject {
@FieldDescribe("工号,不可重复.") @FieldDescribe("工号,不可重复.")
@Column(length = length_255B, name = ColumnNamePrefix + employee_FIELDNAME) @Column(length = length_255B, name = ColumnNamePrefix + employee_FIELDNAME)
@Index(name = TABLE + IndexNameMiddle + employee_FIELDNAME) @Index(name = TABLE + IndexNameMiddle + employee_FIELDNAME)
@CheckPersist(allowEmpty = true, simplyString = true, citationNotExists = @CitationNotExist(fields = employee_FIELDNAME, type = Person.class)) @CheckPersist(allowEmpty = true, simplyString = false, citationNotExists = @CitationNotExist(fields = employee_FIELDNAME, type = Person.class))
private String employee; private String employee;
public static final String unique_FIELDNAME = "unique"; public static final String unique_FIELDNAME = "unique";
...@@ -188,7 +188,7 @@ public class Person extends SliceJpaObject { ...@@ -188,7 +188,7 @@ public class Person extends SliceJpaObject {
@FieldDescribe("唯一标识,不可重复,为空则使用自动填充值") @FieldDescribe("唯一标识,不可重复,为空则使用自动填充值")
@Column(length = length_255B, name = ColumnNamePrefix + unique_FIELDNAME) @Column(length = length_255B, name = ColumnNamePrefix + unique_FIELDNAME)
@Index(name = TABLE + IndexNameMiddle + unique_FIELDNAME) @Index(name = TABLE + IndexNameMiddle + unique_FIELDNAME)
@CheckPersist(allowEmpty = true, simplyString = true, citationNotExists = @CitationNotExist(fields = unique_FIELDNAME, type = Person.class)) @CheckPersist(allowEmpty = true, simplyString = false, citationNotExists = @CitationNotExist(fields = unique_FIELDNAME, type = Person.class))
private String unique; private String unique;
public static final String distinguishedName_FIELDNAME = "distinguishedName"; public static final String distinguishedName_FIELDNAME = "distinguishedName";
...@@ -343,6 +343,21 @@ public class Person extends SliceJpaObject { ...@@ -343,6 +343,21 @@ public class Person extends SliceJpaObject {
@CheckPersist(allowEmpty = true) @CheckPersist(allowEmpty = true)
private String dingdingHash; private String dingdingHash;
public static final String weLinkId_FIELDNAME = "weLinkId";
@FieldDescribe("WeLikn人员ID.")
@Column(length = length_255B, name = ColumnNamePrefix + weLinkId_FIELDNAME)
@Index(name = TABLE + IndexNameMiddle + weLinkId_FIELDNAME)
@CheckPersist(allowEmpty = true)
private String weLinkId;
public static final String weLinkHash_FIELDNAME = "weLinkHash";
@FieldDescribe("WeLink人员哈希特征.")
@Column(length = length_255B, name = ColumnNamePrefix + weLinkHash_FIELDNAME)
@Index(name = TABLE + IndexNameMiddle + weLinkHash_FIELDNAME)
@CheckPersist(allowEmpty = true)
private String weLinkHash;
public static final String zhengwuDingdingId_FIELDNAME = "zhengwuDingdingId"; public static final String zhengwuDingdingId_FIELDNAME = "zhengwuDingdingId";
@FieldDescribe("政务钉钉人员ID.") @FieldDescribe("政务钉钉人员ID.")
@Column(length = length_255B, name = ColumnNamePrefix + zhengwuDingdingId_FIELDNAME) @Column(length = length_255B, name = ColumnNamePrefix + zhengwuDingdingId_FIELDNAME)
...@@ -788,4 +803,19 @@ public class Person extends SliceJpaObject { ...@@ -788,4 +803,19 @@ public class Person extends SliceJpaObject {
this.hiddenMobile = hiddenMobile; this.hiddenMobile = hiddenMobile;
} }
public String getWeLinkId() {
return weLinkId;
}
public void setWeLinkId(String weLinkId) {
this.weLinkId = weLinkId;
}
public String getWeLinkHash() {
return weLinkHash;
}
public void setWeLinkHash(String weLinkHash) {
this.weLinkHash = weLinkHash;
}
} }
\ No newline at end of file
...@@ -215,6 +215,20 @@ public class Unit extends SliceJpaObject { ...@@ -215,6 +215,20 @@ public class Unit extends SliceJpaObject {
@CheckPersist(allowEmpty = true) @CheckPersist(allowEmpty = true)
private String dingdingHash; private String dingdingHash;
public static final String weLinkId_FIELDNAME = "weLinkId";
@FieldDescribe("WeLink部门ID.")
@Column(length = length_255B, name = ColumnNamePrefix + weLinkId_FIELDNAME)
@Index(name = TABLE + IndexNameMiddle + weLinkId_FIELDNAME)
@CheckPersist(allowEmpty = true)
private String weLinkId;
public static final String weLinkHash_FIELDNAME = "weLinkHash";
@FieldDescribe("WeLink部门哈希特征.")
@Column(length = length_255B, name = ColumnNamePrefix + weLinkHash_FIELDNAME)
@Index(name = TABLE + IndexNameMiddle + weLinkHash_FIELDNAME)
@CheckPersist(allowEmpty = true)
private String weLinkHash;
public static final String qiyeweixinId_FIELDNAME = "qiyeweixinId"; public static final String qiyeweixinId_FIELDNAME = "qiyeweixinId";
@FieldDescribe("企业微信人员ID.") @FieldDescribe("企业微信人员ID.")
@Column(length = length_255B, name = ColumnNamePrefix + qiyeweixinId_FIELDNAME) @Column(length = length_255B, name = ColumnNamePrefix + qiyeweixinId_FIELDNAME)
...@@ -409,4 +423,19 @@ public class Unit extends SliceJpaObject { ...@@ -409,4 +423,19 @@ public class Unit extends SliceJpaObject {
this.zhengwuDingdingHash = zhengwuDingdingHash; this.zhengwuDingdingHash = zhengwuDingdingHash;
} }
public String getWeLinkId() {
return weLinkId;
}
public void setWeLinkId(String weLinkId) {
this.weLinkId = weLinkId;
}
public String getWeLinkHash() {
return weLinkHash;
}
public void setWeLinkHash(String weLinkHash) {
this.weLinkHash = weLinkHash;
}
} }
\ No newline at end of file
...@@ -24,6 +24,8 @@ public class ThisApplication { ...@@ -24,6 +24,8 @@ public class ThisApplication {
public static List<Object> dingdingSyncOrganizationCallbackRequest = new ArrayList<>(); public static List<Object> dingdingSyncOrganizationCallbackRequest = new ArrayList<>();
public static List<Object> weLinkSyncOrganizationCallbackRequest = new ArrayList<>();
public static List<Object> zhengwuDingdingSyncOrganizationCallbackRequest = new ArrayList<>(); public static List<Object> zhengwuDingdingSyncOrganizationCallbackRequest = new ArrayList<>();
public static List<Object> qiyeweixinSyncOrganizationCallbackRequest = new ArrayList<>(); public static List<Object> qiyeweixinSyncOrganizationCallbackRequest = new ArrayList<>();
...@@ -61,6 +63,14 @@ public class ThisApplication { ...@@ -61,6 +63,14 @@ public class ThisApplication {
/* 添加一个强制同步任务 */ /* 添加一个强制同步任务 */
context().scheduleLocal(DingdingSyncOrganizationTrigger.class, Config.dingding().getForceSyncCron()); context().scheduleLocal(DingdingSyncOrganizationTrigger.class, Config.dingding().getForceSyncCron());
} }
/* WeLink同步 */
if (Config.weLink().getEnable()) {
/* 启动同步任务 */
context().scheduleLocal(WeLinkSyncOrganization.class, Config.weLink().getSyncCron());
/* 添加一个强制同步任务 */
context().scheduleLocal(WeLinkSyncOrganizationTrigger.class, Config.weLink().getForceSyncCron());
}
context().scheduleLocal(RefreshApplications.class, CenterQueue.REFRESHAPPLICATIONSINTERVAL, context().scheduleLocal(RefreshApplications.class, CenterQueue.REFRESHAPPLICATIONSINTERVAL,
CenterQueue.REFRESHAPPLICATIONSINTERVAL); CenterQueue.REFRESHAPPLICATIONSINTERVAL);
// 运行间隔由300秒缩减到120秒 // 运行间隔由300秒缩减到120秒
......
...@@ -40,6 +40,20 @@ public class PersonFactory extends AbstractFactory { ...@@ -40,6 +40,20 @@ public class PersonFactory extends AbstractFactory {
} }
} }
public Person getWithWeLinkIdObject(String weLinkId) throws Exception {
EntityManager em = this.entityManagerContainer().get(Person.class);
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> cq = cb.createQuery(Person.class);
Root<Person> root = cq.from(Person.class);
Predicate p = cb.equal(root.get(Person_.weLinkId), weLinkId);
List<Person> os = em.createQuery(cq.select(root).where(p)).setMaxResults(1).getResultList();
if (os.isEmpty()) {
return null;
} else {
return os.get(0);
}
}
public Person getWithZhengwuDingdingIdObject(String zhengwuDingdingId) throws Exception { public Person getWithZhengwuDingdingIdObject(String zhengwuDingdingId) throws Exception {
EntityManager em = this.entityManagerContainer().get(Person.class); EntityManager em = this.entityManagerContainer().get(Person.class);
CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaBuilder cb = em.getCriteriaBuilder();
......
...@@ -41,6 +41,20 @@ public class UnitFactory extends AbstractFactory { ...@@ -41,6 +41,20 @@ public class UnitFactory extends AbstractFactory {
} }
} }
public Unit getWithWeLinkDeptCodeObject(String weLinkDeptCode) throws Exception {
EntityManager em = this.entityManagerContainer().get(Unit.class);
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Unit> cq = cb.createQuery(Unit.class);
Root<Unit> root = cq.from(Unit.class);
Predicate p = cb.equal(root.get(Unit_.weLinkId), weLinkDeptCode);
List<Unit> os = em.createQuery(cq.select(root).where(p)).setMaxResults(1).getResultList();
if (os.isEmpty()) {
return null;
} else {
return os.get(0);
}
}
public Unit getWithZhengwuDingdingIdObject(String zhengwuDingdingId) throws Exception { public Unit getWithZhengwuDingdingIdObject(String zhengwuDingdingId) throws Exception {
EntityManager em = this.entityManagerContainer().get(Unit.class); EntityManager em = this.entityManagerContainer().get(Unit.class);
CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaBuilder cb = em.getCriteriaBuilder();
......
...@@ -34,6 +34,7 @@ import com.x.program.center.jaxrs.test.TestAction; ...@@ -34,6 +34,7 @@ import com.x.program.center.jaxrs.test.TestAction;
import com.x.program.center.jaxrs.unexpectederrorlog.UnexpectedErrorLogAction; import com.x.program.center.jaxrs.unexpectederrorlog.UnexpectedErrorLogAction;
import com.x.program.center.jaxrs.validation.ValidationAction; import com.x.program.center.jaxrs.validation.ValidationAction;
import com.x.program.center.jaxrs.warnlog.WarnLogAction; import com.x.program.center.jaxrs.warnlog.WarnLogAction;
import com.x.program.center.jaxrs.welink.WeLinkAction;
import com.x.program.center.jaxrs.zhengwudingding.ZhengwuDingdingAction; import com.x.program.center.jaxrs.zhengwudingding.ZhengwuDingdingAction;
@ApplicationPath("jaxrs") @ApplicationPath("jaxrs")
...@@ -60,6 +61,7 @@ public class ActionApplication extends AbstractActionApplication { ...@@ -60,6 +61,7 @@ public class ActionApplication extends AbstractActionApplication {
classes.add(AppStyleAction.class); classes.add(AppStyleAction.class);
classes.add(ConfigAction.class); classes.add(ConfigAction.class);
classes.add(DingdingAction.class); classes.add(DingdingAction.class);
classes.add(WeLinkAction.class);
classes.add(ZhengwuDingdingAction.class); classes.add(ZhengwuDingdingAction.class);
classes.add(QiyeweixinAction.class); classes.add(QiyeweixinAction.class);
classes.add(ScheduleAction.class); classes.add(ScheduleAction.class);
......
package com.x.program.center.jaxrs;
import com.x.base.core.project.jaxrs.AnonymousCipherManagerUserJaxrsFilter;
import javax.servlet.annotation.WebFilter;
@WebFilter(urlPatterns = "/jaxrs/welink/*", asyncSupported = true)
public class WeLinkJaxrsFilter extends AnonymousCipherManagerUserJaxrsFilter {
}
package com.x.program.center.jaxrs.welink;
import com.x.base.core.container.EntityManagerContainer;
import com.x.base.core.container.factory.EntityManagerContainerFactory;
import com.x.base.core.project.config.Config;
import com.x.base.core.project.exception.ExceptionAccessDenied;
import com.x.base.core.project.gson.XGsonBuilder;
import com.x.base.core.project.http.ActionResult;
import com.x.base.core.project.http.EffectivePerson;
import com.x.program.center.Business;
import com.x.program.center.welink.SyncOrganization;
import org.apache.commons.lang3.BooleanUtils;
class ActionPullSync extends BaseAction {
ActionResult<Wo> execute(EffectivePerson effectivePerson) throws Exception {
try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
if (effectivePerson.isNotManager()) {
throw new ExceptionAccessDenied(effectivePerson);
}
ActionResult<Wo> result = new ActionResult<>();
Wo wo = null;
if (BooleanUtils.isTrue(Config.weLink().getEnable())) {
Business business = new Business(emc);
SyncOrganization o = new SyncOrganization();
SyncOrganization.PullResult pullResult = o.execute(business);
wo = XGsonBuilder.convert(pullResult, Wo.class);
}else{
throw new ExceptionNotPullSync();
}
result.setData(wo);
return result;
}
}
public static class Wo extends SyncOrganization.PullResult {
}
}
package com.x.program.center.jaxrs.welink;
import com.google.gson.JsonElement;
import com.x.base.core.project.config.Config;
import com.x.base.core.project.http.ActionResult;
import com.x.base.core.project.http.EffectivePerson;
import com.x.base.core.project.jaxrs.WrapBoolean;
import com.x.program.center.ThisApplication;
import org.apache.commons.lang3.BooleanUtils;
class ActionSyncOrgnaizationCallback extends BaseAction {
ActionResult<Wo> execute(EffectivePerson effectivePerson, JsonElement jsonElement) throws Exception {
ActionResult<Wo> result = new ActionResult<>();
if (BooleanUtils.isTrue(Config.weLink().getEnable())) {
ThisApplication.weLinkSyncOrganizationCallbackRequest.add(new Object());
} else {
throw new ExceptionNotPullSync();
}
Wo wo = new Wo();
wo.setValue(true);
result.setData(wo);
return result;
}
public static class Wo extends WrapBoolean {
}
}
package com.x.program.center.jaxrs.welink;
import com.x.base.core.project.jaxrs.StandardJaxrsAction;
abstract class BaseAction extends StandardJaxrsAction {
}
package com.x.program.center.jaxrs.welink;
import com.x.base.core.project.exception.PromptException;
class ExceptionNotPullSync extends PromptException {
private static final long serialVersionUID = -3439770681867963457L;
ExceptionNotPullSync() {
super("没有启用从WeLink的拉入同步.");
}
}
package com.x.program.center.jaxrs.welink;
import com.google.gson.JsonElement;
import com.x.base.core.project.annotation.JaxrsDescribe;
import com.x.base.core.project.annotation.JaxrsMethodDescribe;
import com.x.base.core.project.http.ActionResult;
import com.x.base.core.project.http.EffectivePerson;
import com.x.base.core.project.http.HttpMediaType;
import com.x.base.core.project.jaxrs.ResponseFactory;
import com.x.base.core.project.jaxrs.StandardJaxrsAction;
import com.x.base.core.project.logger.Logger;
import com.x.base.core.project.logger.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
/**
* Created by fancyLou on 2020-07-24.
* Copyright © 2020 O2. All rights reserved.
*/
@Path("welink")
@JaxrsDescribe("WeLink接口")
public class WeLinkAction extends StandardJaxrsAction {
private static Logger logger = LoggerFactory.getLogger(WeLinkAction.class);
@JaxrsMethodDescribe(value = "发送一个拉入同步请求.", action = ActionSyncOrgnaizationCallback.class)
@POST
@Path("request/pull/sync")
@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
@Consumes(MediaType.APPLICATION_JSON)
public void requestPullSync(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request,
JsonElement jsonElement) {
EffectivePerson effectivePerson = this.effectivePerson(request);
ActionResult<ActionSyncOrgnaizationCallback.Wo> result = new ActionResult<>();
try {
result = new ActionSyncOrgnaizationCallback().execute(effectivePerson, jsonElement);
} catch (Exception e) {
logger.error(e, effectivePerson, request, jsonElement);
result.error(e);
}
asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
}
@JaxrsMethodDescribe(value = "立即同步.", action = ActionPullSync.class)
@GET
@Path("pull/sync")
@Produces(HttpMediaType.APPLICATION_JSON_UTF_8)
@Consumes(MediaType.APPLICATION_JSON)
public void pullSync(@Suspended final AsyncResponse asyncResponse, @Context HttpServletRequest request) {
EffectivePerson effectivePerson = this.effectivePerson(request);
ActionResult<ActionPullSync.Wo> result = new ActionResult<>();
try {
result = new ActionPullSync().execute(effectivePerson);
} catch (Exception e) {
logger.error(e, effectivePerson, request, null);
result.error(e);
}
asyncResponse.resume(ResponseFactory.getEntityTagActionResultResponse(request, result));
}
}
package com.x.program.center.schedule;
import com.x.base.core.container.EntityManagerContainer;
import com.x.base.core.container.factory.EntityManagerContainerFactory;
import com.x.base.core.project.logger.Logger;
import com.x.base.core.project.logger.LoggerFactory;
import com.x.program.center.Business;
import com.x.program.center.ThisApplication;
import com.x.program.center.welink.SyncOrganization;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class WeLinkSyncOrganization implements Job {
private static Logger logger = LoggerFactory.getLogger(WeLinkSyncOrganization.class);
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
try (EntityManagerContainer emc = EntityManagerContainerFactory.instance().create()) {
if (!ThisApplication.weLinkSyncOrganizationCallbackRequest.isEmpty()) {
ThisApplication.weLinkSyncOrganizationCallbackRequest.clear();
Business business = new Business(emc);
SyncOrganization o = new SyncOrganization();
o.execute(business);
}
} catch (Exception e) {
logger.error(e);
throw new JobExecutionException(e);
}
}
}
package com.x.program.center.schedule;
import com.x.base.core.project.logger.Logger;
import com.x.base.core.project.logger.LoggerFactory;
import com.x.program.center.ThisApplication;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class WeLinkSyncOrganizationTrigger implements Job {
private static Logger logger = LoggerFactory.getLogger(WeLinkSyncOrganizationTrigger.class);
/* 向列表发送一个同步信号 */
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
ThisApplication.weLinkSyncOrganizationCallbackRequest.add(new Object());
}
}
package com.x.program.center.welink;
import com.x.base.core.project.gson.GsonPropertyObject;
public class Department extends GsonPropertyObject {
//{
// "deptCode": "1",
// "deptNameCn": "产品销售部",
// "deptNameEn": "Sales Dept",
// "fatherCode": "0",
// "deptLevel": "2",
// "orderNo": 1,
// "hasChildDept": 1,
// "corpDeptCode": ""
// }
private String deptCode;
private String deptNameCn;
private String deptNameEn;
private String fatherCode;
private String deptLevel;
private String corpDeptCode;
private Long orderNo;
private Long hasChildDept;
public String getDeptCode() {
return deptCode;
}
public void setDeptCode(String deptCode) {
this.deptCode = deptCode;
}
public String getDeptNameCn() {
return deptNameCn;
}
public void setDeptNameCn(String deptNameCn) {
this.deptNameCn = deptNameCn;
}
public String getDeptNameEn() {
return deptNameEn;
}
public void setDeptNameEn(String deptNameEn) {
this.deptNameEn = deptNameEn;
}
public String getFatherCode() {
return fatherCode;
}
public void setFatherCode(String fatherCode) {
this.fatherCode = fatherCode;
}
public String getDeptLevel() {
return deptLevel;
}
public void setDeptLevel(String deptLevel) {
this.deptLevel = deptLevel;
}
public String getCorpDeptCode() {
return corpDeptCode;
}
public void setCorpDeptCode(String corpDeptCode) {
this.corpDeptCode = corpDeptCode;
}
public Long getOrderNo() {
return orderNo;
}
public void setOrderNo(Long orderNo) {
this.orderNo = orderNo;
}
public Long getHasChildDept() {
return hasChildDept;
}
public void setHasChildDept(Long hasChildDept) {
this.hasChildDept = hasChildDept;
}
}
package com.x.program.center.welink;
import com.x.base.core.project.exception.PromptException;
class ExceptionListOrg extends PromptException {
private static final long serialVersionUID = 4132300948670472899L;
ExceptionListOrg(String retCode, String retMessage) {
super("WeLink获取下级组织失败,错误代码:{},错误消息:{}.", retCode, retMessage);
}
}
package com.x.program.center.welink;
import com.x.base.core.project.exception.PromptException;
class ExceptionListUser extends PromptException {
private static final long serialVersionUID = 4132300948670472899L;
ExceptionListUser(String retCode, String retMessage) {
super("WeLink获取组织成员失败,错误代码:{},错误消息:{}.", retCode, retMessage);
}
}
package com.x.program.center.welink;
import com.x.base.core.project.gson.GsonPropertyObject;
import java.util.LinkedHashMap;
import java.util.List;
public class User extends GsonPropertyObject {
//{
// "userStatus": "1", //状态, 1:未开户,2:开户中,3:已开户,4:已销户
// "userId": "zhangsan1@welink", //用户帐号, Key值
// "deptCode": "10001", //部门Id, Key值, 必填
// "deptNameCn": "72270测试部门",
// "deptNameEn": "72270Test Dept",
// "mobileNumber": "+86-15811847236", //绑定手机号码, 必填
// "phoneNumber": "+86-15811847236", //手机号码
// "landlineNumber": "0755-88888888", //电话号码(座机)
// "userNameCn": "张三", //用户中文名称, 必填
// "userNameEn": "zhangshan", //用户英文名称, 必填
// "sex": "M", //性别, 仅:M/F, M: 男, F: 女, 必填
// "corpUserId": "36188", //用户工号(集成用的字段,如果在开户时没有维护则为空)
// "userEmail": "zhangshan4@126.com", //用户邮箱, 必填
// "secretary": "zhangshan@welink", //秘书(用户帐号)
// "address": "广东省深圳", //地址
// "remark": "欢迎加入WeLink", //备注
// "creationTime": "2018-05-03 13:58:02", //创建时间
// "lastUpdatedTime": "2018-05-03 13:58:02" //最后更新时间
// }
private String userStatus;
private String userId;
private String deptCode;
private String deptNameCn;
private String deptNameEn;
private String mobileNumber;
private String phoneNumber;
private String landlineNumber;
private String userNameCn;
private String userNameEn;
private String sex;
private String corpUserId;
private String userEmail;
private String secretary;
private String address;
private String remark;
private String creationTime;
private String lastUpdatedTime;
public String getUserStatus() {
return userStatus;
}
public void setUserStatus(String userStatus) {
this.userStatus = userStatus;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getDeptCode() {
return deptCode;
}
public void setDeptCode(String deptCode) {
this.deptCode = deptCode;
}
public String getDeptNameCn() {
return deptNameCn;
}
public void setDeptNameCn(String deptNameCn) {
this.deptNameCn = deptNameCn;
}
public String getDeptNameEn() {
return deptNameEn;
}
public void setDeptNameEn(String deptNameEn) {
this.deptNameEn = deptNameEn;
}
public String getMobileNumber() {
return mobileNumber;
}
public void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getLandlineNumber() {
return landlineNumber;
}
public void setLandlineNumber(String landlineNumber) {
this.landlineNumber = landlineNumber;
}
public String getUserNameCn() {
return userNameCn;
}
public void setUserNameCn(String userNameCn) {
this.userNameCn = userNameCn;
}
public String getUserNameEn() {
return userNameEn;
}
public void setUserNameEn(String userNameEn) {
this.userNameEn = userNameEn;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getCorpUserId() {
return corpUserId;
}
public void setCorpUserId(String corpUserId) {
this.corpUserId = corpUserId;
}
public String getUserEmail() {
return userEmail;
}
public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}
public String getSecretary() {
return secretary;
}
public void setSecretary(String secretary) {
this.secretary = secretary;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getCreationTime() {
return creationTime;
}
public void setCreationTime(String creationTime) {
this.creationTime = creationTime;
}
public String getLastUpdatedTime() {
return lastUpdatedTime;
}
public void setLastUpdatedTime(String lastUpdatedTime) {
this.lastUpdatedTime = lastUpdatedTime;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((userId == null) ? 0 : userId.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (userId == null) {
if (other.userId != null)
return false;
} else if (!userId.equals(other.userId))
return false;
return true;
}
}
\ No newline at end of file
package com.x.program.center.welink;
import com.x.base.core.project.bean.NameValuePair;
import com.x.base.core.project.config.Config;
import com.x.base.core.project.connection.HttpConnection;
import com.x.base.core.project.gson.GsonPropertyObject;
import com.x.base.core.project.logger.Logger;
import com.x.base.core.project.logger.LoggerFactory;
import com.x.base.core.project.tools.ListTools;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Created by fancyLou on 2020-07-24.
* Copyright © 2020 O2. All rights reserved.
*/
public class WeLinkFactory {
private static Logger logger = LoggerFactory.getLogger(WeLinkFactory.class);
private String accessToken;
private List<Department> orgs = new ArrayList<>();
private List<User> users = new ArrayList<>();
public WeLinkFactory(String accessToken) throws Exception {
this.accessToken = accessToken;
this.orgs();
for (Department d: this.orgs) {
this.usersWithDept(d.getDeptCode());
}
users = ListTools.trim(users, true, true);
}
public List<Department> roots() {
return orgs.stream().filter(o -> "0".equals(o.getFatherCode())).collect(Collectors.toList());
}
public List<User> listUser(Department org) throws Exception {
return users.stream().filter(o -> o.getDeptCode().equals(org.getDeptCode()))
.collect(Collectors.toList());
}
public List<Department> listSub(Department org) throws Exception {
return orgs.stream().filter(o -> {
return Objects.equals(o.getFatherCode(), org.getDeptCode());
}).collect(Collectors.toList());
}
private void orgs() throws Exception {
OrgListResp root = this.orgs("0", "0", 1); //跟目录不能递归
if (root.getDepartmentInfo()!=null && !root.getDepartmentInfo().isEmpty()) {
for (int i = 0; i < root.getDepartmentInfo().size(); i++) {
Department department = root.getDepartmentInfo().get(i);
this.orgs.add(department);
int offset = 1;
int totalCount = 0;
this.recursiveOrgs(department.getDeptCode(), offset, totalCount); //递归查询有所的组织
}
}
}
private void recursiveOrgs(String deptCode, int offset, int totalCount) throws Exception {
logger.info("recursiveOrgs deptCode:"+deptCode+", offset:"+offset+" ,totalCount:"+totalCount);
OrgListResp subDepts = this.orgs(deptCode, "1", offset); //递归查询有所的组织
if (!subDepts.getCode().equals("0") && !subDepts.getCode().equals("47009") && !subDepts.getCode().equals("47012")) {
throw new ExceptionListOrg(subDepts.getCode(), subDepts.getMessage());
}
if (subDepts.getDepartmentInfo()!=null && !subDepts.getDepartmentInfo().isEmpty()) {
this.orgs.addAll(subDepts.getDepartmentInfo());
totalCount += subDepts.getDepartmentInfo().size();
if (totalCount < subDepts.getTotalCount()) {
offset++;
recursiveOrgs(deptCode, offset, totalCount);
}
}
}
/**
* 组织
* @param deptCode 父组织id 顶级的父是0
* @param recursiveflag 是否递归 0不递归 1递归
* @return
* @throws Exception
*/
private OrgListResp orgs(String deptCode, String recursiveflag, Integer offset) throws Exception {
String address = Config.weLink().getOapiAddress() + "/contact/v3/departments/list?recursiveflag="+recursiveflag+"&deptCode="+deptCode+"&offset="+offset;
//deptCode
//recursiveflag 0 :查询下级部门信息 1 :查询递归获取所有子部门
List<NameValuePair> heads = new ArrayList<>();
heads.add(new NameValuePair("x-wlk-Authorization", this.accessToken));
OrgListResp resp = HttpConnection.getAsObject(address, heads, OrgListResp.class);
logger.info("orgs response:{}.", resp);
if (!resp.getCode().equals("0") && !resp.getCode().equals("47009") && !resp.getCode().equals("47012")) {
throw new ExceptionListOrg(resp.getCode(), resp.getMessage());
}
return resp;
}
private void usersWithDept(String deptCode) throws Exception {
int pageNo = 1;
this.usersPages(deptCode, pageNo);
}
//分页查询
private void usersPages(String deptCode, int pageNo) throws Exception {
UserListResp resp = this.users(deptCode, pageNo);
if (resp.getData() != null && !resp.getData().isEmpty()) {
this.users.addAll(resp.data);
if (resp.getPages() > pageNo) {
pageNo ++;
usersPages(deptCode, pageNo);
}
}
}
/**
* 查询用户
* @param deptCode 所属组织id
* @param pageNo 页码
* @return
* @throws Exception
*/
private UserListResp users(String deptCode, int pageNo) throws Exception {
String address = Config.weLink().getOapiAddress() + "/contact/v1/user/users?deptCode="+deptCode+"&pageNo="+pageNo+"&pageSize=50";
List<NameValuePair> heads = new ArrayList<>();
heads.add(new NameValuePair("x-wlk-Authorization", this.accessToken));
UserListResp resp = HttpConnection.getAsObject(address, heads, UserListResp.class);
logger.info("users response:{}.", resp);
if (!resp.getCode().equals("0") && !resp.getCode().equals("47009") && !resp.getCode().equals("47012")) {
throw new ExceptionListUser(resp.getCode(), resp.getMessage());
}
return resp;
}
public static class OrgListResp extends GsonPropertyObject {
//{ "code": "0",
// "message": "OK",
// "offset": 100,
// "limit": 25,
// "totalCount": 327,
// "departmentInfo": []
//}
private String code; //数据正常返回“0”,如果发生错误,会返回对应的错误码。
private String message;
private Long offset;
private Long limit;
private Long totalCount; //当前部门下所有部门数,如果当前部门为0级,仅能获取下一级的所有部门。
private List<Department> departmentInfo;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Long getOffset() {
return offset;
}
public void setOffset(Long offset) {
this.offset = offset;
}
public Long getLimit() {
return limit;
}
public void setLimit(Long limit) {
this.limit = limit;
}
public Long getTotalCount() {
return totalCount;
}
public void setTotalCount(Long totalCount) {
this.totalCount = totalCount;
}
public List<Department> getDepartmentInfo() {
return departmentInfo;
}
public void setDepartmentInfo(List<Department> departmentInfo) {
this.departmentInfo = departmentInfo;
}
}
public static class UserListResp extends GsonPropertyObject {
//{
// "code": "0",
// "message": "OK",
// "pageNo": 1,
// "pages": 1,
// "pageSize": "10",
// "total": 2,
// "data": []
//}
private String code; //数据正常返回“0”,如果发生错误,会返回对应的错误码。
private String message;
private Long pageNo; //当前页码
private Long pages; //总共页数
private Long total; //总用户数
private List<User> data;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Long getPageNo() {
return pageNo;
}
public void setPageNo(Long pageNo) {
this.pageNo = pageNo;
}
public Long getPages() {
return pages;
}
public void setPages(Long pages) {
this.pages = pages;
}
public Long getTotal() {
return total;
}
public void setTotal(Long total) {
this.total = total;
}
public List<User> getData() {
return data;
}
public void setData(List<User> data) {
this.data = data;
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册