|
@@ -36,6 +36,7 @@ import java.util.Set;
|
|
|
/**
|
|
/**
|
|
|
* 同步北森应聘者(ApplicantBeisen)招聘负责人 OSF 服务。
|
|
* 同步北森应聘者(ApplicantBeisen)招聘负责人 OSF 服务。
|
|
|
* 业务链路:申请ID → 北森申请(jobId) → 北森职位(hrDutyUser) → 北森员工(staffCode) → sHR人员(recruitOwner)。
|
|
* 业务链路:申请ID → 北森申请(jobId) → 北森职位(hrDutyUser) → 北森员工(staffCode) → sHR人员(recruitOwner)。
|
|
|
|
|
+ * 待同步判定:recruitOwner(招聘负责人)为空才同步;已有负责人则跳过。
|
|
|
* 同步结果写入 syncRecruit,成功为「同步成功」,失败为具体原因。
|
|
* 同步结果写入 syncRecruit,成功为「同步成功」,失败为具体原因。
|
|
|
* OSF 服务名:syncRecruitOwnerService;入参 billIds 为空时走定时扫描。
|
|
* OSF 服务名:syncRecruitOwnerService;入参 billIds 为空时走定时扫描。
|
|
|
*
|
|
*
|
|
@@ -45,7 +46,7 @@ public class SyncRecruitOwnerService implements IHRMsfService {
|
|
|
|
|
|
|
|
/** 日志记录器 */
|
|
/** 日志记录器 */
|
|
|
private static final Logger logger = Logger.getLogger(SyncRecruitOwnerService.class);
|
|
private static final Logger logger = Logger.getLogger(SyncRecruitOwnerService.class);
|
|
|
- /** 同步成功固定文案,定时扫描与 shouldSkip 均以此判断,禁止随意修改 */
|
|
|
|
|
|
|
+ /** 同步成功固定文案,写入 syncRecruit 字段,禁止随意修改 */
|
|
|
private static final String SYNC_SUCCESS = "同步成功";
|
|
private static final String SYNC_SUCCESS = "同步成功";
|
|
|
/** 北森批量接口每批条数,避免单次请求过多超时或限流 */
|
|
/** 北森批量接口每批条数,避免单次请求过多超时或限流 */
|
|
|
private static final int BATCH_SIZE = 70;
|
|
private static final int BATCH_SIZE = 70;
|
|
@@ -72,7 +73,7 @@ public class SyncRecruitOwnerService implements IHRMsfService {
|
|
|
|
|
|
|
|
IApplicantBeisen applicantBeisen = ApplicantBeisenFactory.getLocalInstance(ctx);
|
|
IApplicantBeisen applicantBeisen = ApplicantBeisenFactory.getLocalInstance(ctx);
|
|
|
ApplicantBeisenCollection collection = loadCollection(applicantBeisen, billIds);
|
|
ApplicantBeisenCollection collection = loadCollection(applicantBeisen, billIds);
|
|
|
- // 排除已成功及历史数据,避免重复调北森
|
|
|
|
|
|
|
+ // 排除已有招聘负责人及历史数据,避免重复调北森
|
|
|
List<ApplicantBeisenInfo> todoList = new ArrayList<ApplicantBeisenInfo>();
|
|
List<ApplicantBeisenInfo> todoList = new ArrayList<ApplicantBeisenInfo>();
|
|
|
for (int i = 0; i < collection.size(); i++) {
|
|
for (int i = 0; i < collection.size(); i++) {
|
|
|
ApplicantBeisenInfo info = collection.get(i);
|
|
ApplicantBeisenInfo info = collection.get(i);
|
|
@@ -329,7 +330,7 @@ public class SyncRecruitOwnerService implements IHRMsfService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 构建查询条件:指定 billIds 时按 id 过滤;为空时扫 syncRecruit 未成功且非历史数据。
|
|
|
|
|
|
|
+ * 构建查询条件:指定 billIds 时按 id 过滤;为空时扫 recruitOwner 为空且非历史数据。
|
|
|
*/
|
|
*/
|
|
|
private FilterInfo buildFilterInfo(String billIds) throws BOSException {
|
|
private FilterInfo buildFilterInfo(String billIds) throws BOSException {
|
|
|
FilterInfo filterInfo = new FilterInfo();
|
|
FilterInfo filterInfo = new FilterInfo();
|
|
@@ -342,19 +343,14 @@ public class SyncRecruitOwnerService implements IHRMsfService {
|
|
|
return filterInfo;
|
|
return filterInfo;
|
|
|
}
|
|
}
|
|
|
try {
|
|
try {
|
|
|
- // syncRecruit 为空或非「同步成功」
|
|
|
|
|
- FilterInfo syncOrFilter = new FilterInfo();
|
|
|
|
|
- syncOrFilter.getFilterItems().add(new FilterItemInfo("syncRecruit", null, CompareType.EQUALS));
|
|
|
|
|
- FilterInfo syncNotSuccess = new FilterInfo();
|
|
|
|
|
- syncNotSuccess.getFilterItems().add(new FilterItemInfo("syncRecruit", SYNC_SUCCESS, CompareType.NOTEQUALS));
|
|
|
|
|
- syncOrFilter.mergeFilter(syncNotSuccess, "OR");
|
|
|
|
|
- // isHistoricalData 为空或 0
|
|
|
|
|
|
|
+ // recruitOwner IS NULL:招聘负责人为空才纳入定时同步
|
|
|
|
|
+ filterItems.add(new FilterItemInfo("recruitOwner", null, CompareType.EQUALS));
|
|
|
|
|
+ // isHistoricalData IS NULL OR = 0:排除历史归档数据
|
|
|
FilterInfo histOrFilter = new FilterInfo();
|
|
FilterInfo histOrFilter = new FilterInfo();
|
|
|
histOrFilter.getFilterItems().add(new FilterItemInfo("isHistoricalData", null, CompareType.EQUALS));
|
|
histOrFilter.getFilterItems().add(new FilterItemInfo("isHistoricalData", null, CompareType.EQUALS));
|
|
|
FilterInfo histZero = new FilterInfo();
|
|
FilterInfo histZero = new FilterInfo();
|
|
|
histZero.getFilterItems().add(new FilterItemInfo("isHistoricalData", Integer.valueOf(0), CompareType.EQUALS));
|
|
histZero.getFilterItems().add(new FilterItemInfo("isHistoricalData", Integer.valueOf(0), CompareType.EQUALS));
|
|
|
histOrFilter.mergeFilter(histZero, "OR");
|
|
histOrFilter.mergeFilter(histZero, "OR");
|
|
|
- filterInfo.mergeFilter(syncOrFilter, "AND");
|
|
|
|
|
filterInfo.mergeFilter(histOrFilter, "AND");
|
|
filterInfo.mergeFilter(histOrFilter, "AND");
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
throw new BOSException(e);
|
|
throw new BOSException(e);
|
|
@@ -362,14 +358,19 @@ public class SyncRecruitOwnerService implements IHRMsfService {
|
|
|
return filterInfo;
|
|
return filterInfo;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /** 已成功或历史数据则跳过,避免重复同步 */
|
|
|
|
|
|
|
+ /** 已有招聘负责人或历史数据则跳过,避免重复同步 */
|
|
|
private boolean shouldSkip(ApplicantBeisenInfo info) {
|
|
private boolean shouldSkip(ApplicantBeisenInfo info) {
|
|
|
- if (SYNC_SUCCESS.equals(info.getString("syncRecruit"))) {
|
|
|
|
|
|
|
+ if (!isRecruitOwnerEmpty(info)) {
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
return isHistoricalData(info.get("isHistoricalData"));
|
|
return isHistoricalData(info.get("isHistoricalData"));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /** 判断招聘负责人是否为空,为空表示待同步 */
|
|
|
|
|
+ private boolean isRecruitOwnerEmpty(ApplicantBeisenInfo info) {
|
|
|
|
|
+ return info.get("recruitOwner") == null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/** 兼容 Boolean true 与 "1" 两种历史数据存储 */
|
|
/** 兼容 Boolean true 与 "1" 两种历史数据存储 */
|
|
|
private boolean isHistoricalData(Object value) {
|
|
private boolean isHistoricalData(Object value) {
|
|
|
if (value == null) {
|
|
if (value == null) {
|