package com.kingdee.eas.custom.beisen.syncperson.service; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.kingdee.bos.BOSException; import com.kingdee.bos.Context; import com.kingdee.bos.bsf.service.app.IHRMsfService; import com.kingdee.bos.metadata.entity.*; import com.kingdee.bos.metadata.query.util.CompareType; import com.kingdee.eas.base.permission.IUser; import com.kingdee.eas.base.permission.UserCollection; import com.kingdee.eas.base.permission.UserFactory; import com.kingdee.eas.base.permission.UserInfo; import com.kingdee.eas.basedata.org.AdminOrgUnitInfo; import com.kingdee.eas.basedata.org.PositionInfo; import com.kingdee.eas.basedata.person.IPerson; import com.kingdee.eas.basedata.person.PersonCollection; import com.kingdee.eas.basedata.person.PersonFactory; import com.kingdee.eas.basedata.person.PersonInfo; import com.kingdee.eas.common.EASBizException; import com.kingdee.eas.custom.beisen.utils.BeisenApiClient; import com.kingdee.eas.custom.beisen.utils.BeisenParamByPropertiesUtil; import com.kingdee.eas.hr.ats.AtsUtil; import com.kingdee.eas.hr.base.*; import com.kingdee.eas.hr.emp.*; import com.kingdee.eas.util.app.DbUtil; import com.kingdee.jdbc.rowset.IRowSet; import com.kingdee.util.DateTimeUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import java.io.IOException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.sql.SQLException; import java.util.*; /** * @ClassName SyncPersonToBeisenService * @Description 同步人员信息数据到北森 * @Author 青梧 * @Date 2025/7/17 10:50 * @Version 1.0 **/ public class SyncPersonToBeisenService implements IHRMsfService { private static Logger logger = Logger.getLogger(SyncPersonToBeisenService.class); private BeisenApiClient beisenApiClient = null; public SyncPersonToBeisenService() { beisenApiClient = BeisenApiClient.getInstance(); } @Override public Object process(Context ctx, Map map) throws EASBizException, BOSException { Integer day = (Integer) map.get("day"); String personId = (String) map.get("personId"); // 获取到所有需要的personid Set personSet = new HashSet(); // 获取当前日期 Date now = new Date(); // 获取指定天数前的日期 Date dayBefore = getDayBefore(now, day); FilterInfo filterInfo = new FilterInfo(); FilterItemCollection filterItems = filterInfo.getFilterItems(); filterItems.add(new FilterItemInfo("lastUpdateTime", dayBefore, CompareType.GREATER_EQUALS)); filterItems.add(new FilterItemInfo("lastUpdateTime", now, CompareType.LESS_EQUALS)); SelectorItemCollection sic = new SelectorItemCollection(); sic.add(new SelectorItemInfo("id")); IPerson iPerson = PersonFactory.getLocalInstance(ctx); EntityViewInfo entityViewInfo = EntityViewInfo.getInstance(filterInfo, sic, null); PersonCollection personCol = iPerson.getPersonCollection(entityViewInfo); // 循环获取所有人员id for (int i = 0; i < personCol.size(); i++) { PersonInfo personInfo = personCol.get(i); personSet.add(personInfo.getId().toString()); } sic = new SelectorItemCollection(); sic.add(new SelectorItemInfo("person.id")); entityViewInfo = EntityViewInfo.getInstance(filterInfo, sic, null); // 获取员工变动记录的personid IEmpPosOrgRelation empIns = EmpPosOrgRelationFactory.getLocalInstance(ctx); EmpPosOrgRelationCollection empCol = empIns.getEmpPosOrgRelationCollection(entityViewInfo); // 循环获取所有人员id for (int i = 0; i < empCol.size(); i++) { EmpPosOrgRelationInfo empPosOrgRelation = empCol.get(i); String personIdStr = empPosOrgRelation.getPerson().getId().toString(); personSet.add(personIdStr); } // 同步到beisen String s = convertSetToString(personSet); return _syncPerson(ctx, personId, day); } public static String convertSetToString(Set set) { if (set != null && set.size() > 0) { Iterator iter = set.iterator(); StringBuffer sql = new StringBuffer(); while (iter.hasNext()) { // sql.append("'"); sql.append(iter.next()); // sql.append("',"); sql.append(","); } sql.deleteCharAt(sql.length() - 1); return sql.toString(); } else { return "''"; } } /** * 同步人员信息 * * @param ctx * @param personId * @throws BOSException * @throws EASBizException */ protected JSONArray _syncPerson(Context ctx, String personId, int day) { JSONArray jsonArray = new JSONArray(); FilterInfo filterInfo = new FilterInfo(); FilterItemCollection filterItems = filterInfo.getFilterItems(); Set personIds = new HashSet(); SelectorItemCollection sic = getSelectorItemCollection(); // 如果为空查询所有数据 if (!StringUtils.isEmpty(personId)) { personIds = AtsUtil.toSet(personId); logger.error("syncPersonToIot---personIds---" + personIds); filterItems.add(new FilterItemInfo("person", personIds, CompareType.INCLUDE)); } try { BeisenParamByPropertiesUtil beisenParamByProperties = new BeisenParamByPropertiesUtil("/server/properties/beisen/BeiSenConfig.properties"); Map config = beisenParamByProperties.getConfig(); logger.error("config---" + config.size()); // 查询所有人的user用户 IUser iUser = UserFactory.getLocalInstance(ctx); UserCollection userCollection = iUser.getUserCollection(); Map userMap = new HashMap(); for (int i = 0; i < userCollection.size(); i++) { UserInfo userInfo = userCollection.get(i); PersonInfo person = userInfo.getPerson(); if (person != null) { String userName = userInfo.getName(); userMap.put(person.getId(), userName); } } // 查询所有人的直接上级 Map personParentMap = getPersonParent(ctx); IPersonPosition iPersonPosition = PersonPositionFactory.getLocalInstance(ctx); EntityViewInfo entityViewInfo = EntityViewInfo.getInstance(filterInfo, sic, null); PersonPositionCollection personPositionCollection = iPersonPosition.getPersonPositionCollection(entityViewInfo); if (personPositionCollection.isEmpty()) { jsonArray.add("[" + personId + "]未查询到人员信息数据,请检查参数是否url编码"); } for (int i = 0; i < personPositionCollection.size(); i++) { Map msgMap = new HashMap(); JSONObject personJson = new JSONObject(); PersonPositionInfo personPositionInfo = personPositionCollection.get(i); PersonInfo person = personPositionInfo.getPerson(); // 入职ID Object bsUserId = person.get("bsUserId"); Object beisenId = person.get("beisenId"); logger.error("bsUserId--" + bsUserId); logger.error("beisenId--" + beisenId); String originalId = URLEncoder.encode(person.getId().toString(), StandardCharsets.UTF_8.name()); String nCell = person.getNCell(); String name = person.getName(); msgMap.put("number", person.getNumber()); msgMap.put("name", name); msgMap.put("originalId", originalId); msgMap.put("bsUserId", bsUserId); msgMap.put("beisenId", beisenId); EmployeeTypeInfo employeeType = person.getEmployeeType(); EmployeeTypeEnum inServiceEnum = employeeType.getInService(); String email = person.getEmail(); if (StringUtils.isEmpty(email)) { // throw new BOSException(person.getName() + "同步失败:邮箱不能为空,请维护!!"); msgMap.put("message", person.getName() + "同步失败:邮箱不能为空,请维护!!"); jsonArray.add(msgMap); continue; } personJson.put("email", email);// 邮箱 personJson.put("userName", email);// 用户名 personJson.put("name", name);// 姓名 personJson.put("originalId", person.getId().toString());// 来源方用户ID // 来源(创建更新必填字段) 员工创建时的业务来源。0:其他;1:平台;2:测评;3:招聘;4:360;5:自由注册;6:Tita;7:Tita移动端;1001:PeopleSoft personJson.put("origin", 1); personJson.put("mobile", nCell);// 手机号 personJson.put(config.get("EMPLOYEETYPENUMBER"), employeeType.getNumber());// 用工关系状态 AdminOrgUnitInfo personDep = personPositionInfo.getPersonDep(); personJson.put("departmentOriginalId", personDep.getId());// 部门外部标识 personJson.put(config.get("HIREDATE"), DateTimeUtils.format(person.getHireDate()));// 入职日期 Object lineManagerOriginalId = personParentMap.get(personId) == null ? null : URLEncoder.encode(personParentMap.get(personId).toString(), StandardCharsets.UTF_8.name()); personJson.put(config.get("lineManagerOriginalId"), lineManagerOriginalId);// 直线上级外部标识 PositionInfo primaryPosition = personPositionInfo.getPrimaryPosition(); personJson.put(config.get("positionNumber"), primaryPosition.getNumber());// 岗位编码 personJson.put(config.get("positionName"), primaryPosition.getName());// 岗位名称 // 判断是否在北森存在 如果beisenId为空并且是在职状态需要再北森创建员工 if (beisenId == null) { // 判断是否在职 if (inServiceEnum.getValue() == 2) { msgMap.put("message", person.getName() + "已离职无需同步北森!!"); jsonArray.add(msgMap); continue; } // 创建员工信息 String staffsPost = config.get("STAFFSPOST"); logger.error("personJson--" + personJson); JSONObject staffs = beisenApiClient.callApi(staffsPost, personJson); if (!"200".equals(staffs.getString("code"))) { msgMap.put("message", "创建员工信息失败,原因:" + staffs.get("message")); jsonArray.add(msgMap); continue; } String data = staffs.getString("data"); // 更新bsUserId updatePersonBensenId(ctx, person, data); msgMap.put("bsUserId", data); msgMap.put("创建员工信息:", staffs.get("message")); } else { // 查询待入职人员信息 通过beisenId 入职员工ID获取入职记录guid和userId Map result = getGuid(config, beisenId); logger.error("result--" + result); if (result == null || result.isEmpty()) { msgMap.put("message", "入职ID[" + beisenId + "]未查询到入职信息!"); jsonArray.add(msgMap); continue; } String userId = result.get("userID"); // 判断userid是否等于shr员工信息维护的北森id,如果不等于通过bsUserId修改北森用户管理的外部Id logger.error("bsUserId == null" + bsUserId == null); if (bsUserId == null) { bsUserId = userId; } logger.error(person.getName() + ":" + userId + "--" + bsUserId); msgMap.put("userID", userId); if (userId != bsUserId) { updateBeisenOriginalIdByUserId(msgMap, config, bsUserId); // 更新bsUserId updatePersonBensenId(ctx, person, (String) bsUserId); } // 通过OriginalId更新员工信息 JSONObject udpatePersonJson = personJson; // 删除用户名,不修改用户名 udpatePersonJson.remove("userName"); String putbyuserid = config.get("PUTBYUSERID") + "?userId=" + userId; logger.error("putbyuserid--" + putbyuserid); logger.error("udpatePersonJson--" + udpatePersonJson); JSONObject updateStaffs = beisenApiClient.callPutApi(putbyuserid, udpatePersonJson); msgMap.put("通过userId更新员工信息:", updateStaffs.get("message")); // 更新bsUserId updatePersonBensenId(ctx, person, userId); // 更新待入职人员信息 if (beisenId != null) { JSONObject updateStaffInfo = new JSONObject(); JSONObject staffInfos = new JSONObject(); staffInfos.put("id", beisenId); staffInfos.put("name", name); // staffInfos.put("email", email); staffInfos.put("mobilePhone", nCell); staffInfos.put("staffStatus", 1); updateStaffInfo.put("staffInfos", staffInfos); logger.error("updateStaffInfo--" + updateStaffInfo); JSONObject updateStaffRet = beisenApiClient.callApi(config.get("UPDATESTAFFURL"), updateStaffInfo); msgMap.put("更新待入职人员信息:", updateStaffRet.get("code")); } // 通过userId更新员工信息 if (inServiceEnum.getValue() == 2 || inServiceEnum.getValue() == 0) { // 通过OriginalId设置员工离职 String putSetdimission = config.get("PUTSETDIMISSION") + "=" + originalId; logger.error("putSetdimission--" + putSetdimission); JSONObject setdimission = beisenApiClient.callPutApi(putSetdimission, new JSONObject()); msgMap.put("通过OriginalId设置员工离职:", setdimission.get("message")); // 入职管理设置离职 String recruitOnBoardingPost = config.get("RECRUITONBOARDINGPOST") + "?entryId=" + result.get("guid"); logger.error("recruitOnBoardingPost--" + recruitOnBoardingPost); JSONObject recruitOnBoarding = beisenApiClient.callApi(recruitOnBoardingPost, new JSONObject()); msgMap.put("入职单设置离职:", recruitOnBoarding.get("message")); } else if (inServiceEnum.getValue() == 1) { // 入职管理设置已入职 需求变更无需调用该接口 // 设置员工在职 String putSetinduction = config.get("PUTSETINDUCTION") + "?originalId=" + originalId + "&accountEnable=true"; logger.error("putSetinduction--" + putSetinduction); JSONObject setinduction = beisenApiClient.callPutApi(putSetinduction, new JSONObject()); msgMap.put("设置员工在职:", setinduction.get("message")); } } jsonArray.add(msgMap); } } catch (Exception e) { e.printStackTrace(); logger.error(e.getMessage()); jsonArray.add(e.getMessage()); // throw new RuntimeException(e); } logger.error("jsonArray--" + jsonArray); return jsonArray; } /** * 通过bsUserId修改北森用户管理的外部Id * * @param bsUserId */ public void updateBeisenOriginalIdByUserId(Map map, Map config, Object bsUserId) throws IOException { String putbyuserid = config.get("PUTBYUSERID") + "?userId=" + bsUserId; JSONObject udpatePersonJson = new JSONObject(); udpatePersonJson.put("originalId", ""); udpatePersonJson.put("email", ""); JSONObject json = beisenApiClient.callPutApi(putbyuserid, udpatePersonJson); map.put("修改北森用户管理的外部Id:", json.get("message")); } /** * @param person * @throws BOSException * @throws EASBizException */ private static void updatePersonBensenId(Context ctx, PersonInfo person, String bsUserId) throws BOSException, EASBizException { // 员工 IPerson iPerson = PersonFactory.getLocalInstance(ctx); person.put("bsUserId", bsUserId); SelectorItemCollection personUpdSic = new SelectorItemCollection(); personUpdSic.add("bsUserId"); iPerson.updatePartial(person, personUpdSic); } /** * 查询待入职人员信息 通过beisenId 入职员工ID获取入职记录guid * * @param config * @param beisenId * @return */ public Map getGuid(Map config, Object beisenId) { Map result = null; try { result = new HashMap<>(); String guid = null; JSONArray jsonArray = new JSONArray(); jsonArray.add(beisenId); JSONObject staffInfos = beisenApiClient.callApi(config.get("GETSTAFFINFOS"), jsonArray); logger.error("staffInfos--" + staffInfos); if (staffInfos.getInteger("code") == 200) { JSONArray data = staffInfos.getJSONArray("data"); for (int i = 0; i < data.size(); i++) { JSONObject dataJson = data.getJSONObject(i); logger.error("dataJson--" + dataJson); // entryRecord 入职记录 JSONArray entryRecord = dataJson.getJSONArray("entryRecord"); for (int j = 0; j < entryRecord.size(); j++) { JSONObject entry = entryRecord.getJSONObject(j); if (entry.getInteger("status") == 1 || entry.getInteger("status") == 0) { guid = entry.getString("id"); result.put("guid", guid); } } // 任职记录 Long dataTime = 0l; JSONArray employmentRecord = dataJson.getJSONArray("employmentRecord"); for (int q = 0; q < employmentRecord.size(); q++) { JSONObject employment = employmentRecord.getJSONObject(q); String entryDate = employment.getString("entryDate"); logger.debug("entryDate--" + entryDate); // 处理entryDate为空的数据必须要保存一条数据,如果不为空则保存最新的一条数据 result.put("userID", employment.getString("userID")); if (!StringUtils.isEmpty(entryDate) && DateTimeUtils.parseDate(entryDate).getTime() > dataTime) { result.put("userID", employment.getString("userID")); } } } } } catch (Exception e) { e.printStackTrace(); return null; } return result; } /** * 获取指定日期前 x 天的日期的方法。 * * @param specifiedDay 指定日期 * @param x 天数 * @return 指定日期前 x 天的日期 */ public Date getDayBefore(Date specifiedDay, int x) { // 获取 Calendar 实例 Calendar c = Calendar.getInstance(); // 设置 Calendar 的时间为指定日期 c.setTime(specifiedDay); // 将日期向前移动 x 天 c.add(Calendar.DATE, -x); // 返回移动后的日期 return c.getTime(); } /** * 获取所有人的直接上级 * * @return */ public Map getPersonParent(Context ctx) throws BOSException, SQLException { Map personParentMap = new HashMap(); StringBuffer sb = new StringBuffer(); sb.append("select person.fid as personId , personParent.fid as personParentId\n").append("\n"); sb.append("from T_ORG_PositionMember positioonMenber\n").append("\n"); sb.append("left join T_ORG_Position position on position.fid = positioonMenber.FPositionID\n").append("\n"); sb.append("left join T_ORG_Position positionParent on position.fid = positionParent.FPARENTID\n").append("\n"); sb.append("left join T_HR_EmpOrgRelation empOrgRelation on empOrgRelation.FPOSITIONID = positionParent.fid\n").append("\n"); sb.append("left join t_Bd_person person on person.fid = empOrgRelation.FPERSONID and empOrgRelation.FIsSystem='1'\n").append("\n"); sb.append("left join t_Bd_person personParent on personParent.fid = positioonMenber.FPERSONID").append("\n"); IRowSet iRowSet = DbUtil.executeQuery(ctx, sb.toString()); while (iRowSet.next()) { personParentMap.put(iRowSet.getString("personId"), iRowSet.getString("personParentId")); } return personParentMap; } /** * 查询字段 * * @return */ public SelectorItemCollection getSelectorItemCollection() { SelectorItemCollection sic = new SelectorItemCollection(); sic.add("*"); sic.add("person.number"); sic.add("person.name"); sic.add("person.beisenId"); sic.add("person.bsUserId"); sic.add("person.id"); sic.add("person.hireDate"); sic.add("person.nCell"); sic.add("person.gender"); sic.add("person.email"); sic.add("person.employeeType.name"); sic.add("person.employeeType.number"); sic.add("person.employeeType.inService"); sic.add("personDep.name"); sic.add("personDep.number"); sic.add("personDep.id"); sic.add("personDep.parent.id"); sic.add("primaryPosition.name"); sic.add("primaryPosition.number"); return sic; } }