| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- package com.malk.benteler.service;
- import com.alibaba.fastjson.JSON;
- import com.malk.benteler.config.BentelerYidaConf;
- import com.malk.benteler.dto.EiamBatchOperation;
- import com.malk.benteler.dto.EiamBatchResult;
- import com.malk.benteler.dto.EiamFormSyncResult;
- import com.malk.server.aliwork.YDAuth;
- import com.malk.server.aliwork.YDConf;
- import com.malk.server.aliwork.YDParam;
- import com.malk.server.common.McException;
- import com.malk.service.aliwork.YDClient_Form;
- import com.malk.service.aliwork.YDService;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.lang3.StringUtils;
- import org.springframework.stereotype.Service;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- /**
- * 基于一个宜搭实例 ID 完成查询、批量 EIAM 执行和全量回写。
- */
- @Slf4j
- @Service
- public class BentelerYidaSyncService {
- private final YDClient_Form ydClientForm;
- private final YDService ydService;
- private final YDConf ydConf;
- private final BentelerYidaConf conf;
- private final BentelerYidaFormMapper mapper;
- private final EiamLocalService eiamLocalService;
- public BentelerYidaSyncService(YDClient_Form ydClientForm, YDService ydService,
- YDConf ydConf, BentelerYidaConf conf,
- BentelerYidaFormMapper mapper,
- EiamLocalService eiamLocalService) {
- this.ydClientForm = ydClientForm;
- this.ydService = ydService;
- this.ydConf = ydConf;
- this.conf = conf;
- this.mapper = mapper;
- this.eiamLocalService = eiamLocalService;
- }
- /**
- * 查询入职实例并批量创建 EIAM 用户。
- *
- * @param formInstanceId 宜搭实例 ID
- * @return 执行及回写结果
- */
- public EiamFormSyncResult syncCreate(String formInstanceId) {
- return sync(formInstanceId, EiamBatchOperation.CREATE,
- conf.getOnboardingFormUuid(), conf.getOnboardingTableFieldId());
- }
- /**
- * 查询人员部门更新实例并批量更新 EIAM 用户。
- *
- * @param formInstanceId 宜搭实例 ID
- * @return 执行及回写结果
- */
- public EiamFormSyncResult syncUpdate(String formInstanceId) {
- return sync(formInstanceId, EiamBatchOperation.UPDATE,
- conf.getUpdateFormUuid(), conf.getUpdateTableFieldId());
- }
- /**
- * 查询离职实例并批量删除 EIAM 用户。
- *
- * @param formInstanceId 宜搭实例 ID
- * @return 执行及回写结果
- */
- public EiamFormSyncResult syncDelete(String formInstanceId) {
- return sync(formInstanceId, EiamBatchOperation.DELETE,
- conf.getOffboardingFormUuid(), conf.getOffboardingTableFieldId());
- }
- private EiamFormSyncResult sync(String formInstanceId, EiamBatchOperation operation,
- String expectedFormUuid, String tableFieldId) {
- validateRequest(formInstanceId, tableFieldId);
- Map<String, Object> instance = ydClientForm.getForm(auth(), formInstanceId, null);
- validateForm(instance, expectedFormUuid);
- Map<String, Object> formData = formData(instance);
- List<Map<String, Object>> rows = resolveDetailRows(formInstanceId, tableFieldId,
- formData.get(tableFieldId));
- if (rows.isEmpty()) {
- throw new McException("YIDA_FORM_EMPTY", "宜搭人员子表不能为空");
- }
- EiamBatchResult batchResult = execute(operation, formInstanceId, formData, rows);
- return writeback(formInstanceId, tableFieldId, rows, batchResult);
- }
- private EiamBatchResult execute(EiamBatchOperation operation, String formInstanceId,
- Map<String, Object> formData,
- List<Map<String, Object>> rows) {
- if (operation == EiamBatchOperation.CREATE) {
- String organizationalUnitId = text(formData.get(
- conf.getOnboardingOrganizationalUnitIdFieldId()));
- if (!StringUtils.startsWith(organizationalUnitId, "ou_")) {
- throw new McException("EIAM_ORG_INVALID", "iDaaS 部门 ID 无效");
- }
- return eiamLocalService.batchCreate(mapper.mapCreateItems(
- formInstanceId, formData, rows));
- }
- if (operation == EiamBatchOperation.UPDATE) {
- List<String> updateContents = texts(formData.get(conf.getUpdateContentFieldId()));
- if (updateContents.isEmpty()) {
- throw new McException("EIAM_UPDATE_CONTENT_EMPTY", "更新内容不能为空");
- }
- String organizationalUnitId = null;
- if (requiresOrganizationalUnit(updateContents)) {
- organizationalUnitId = firstText(formData.get(
- conf.getUpdateOrganizationalUnitIdFieldId()));
- if (!StringUtils.startsWith(organizationalUnitId, "ou_")) {
- throw new McException("EIAM_ORG_INVALID", "iDaaS 部门 ID 无效");
- }
- }
- return eiamLocalService.batchUpdate(mapper.mapUpdateItems(
- formInstanceId, rows, organizationalUnitId, updateContents));
- }
- return eiamLocalService.batchDelete(mapper.mapDeleteItems(formInstanceId, rows));
- }
- private EiamFormSyncResult writeback(String formInstanceId, String tableFieldId,
- List<Map<String, Object>> rows,
- EiamBatchResult batchResult) {
- Map<String, Object> update = new HashMap<>();
- update.put(tableFieldId, mapper.rebuildRows(tableFieldId, rows,
- batchResult.getItems()));
- update.put(conf.getFailureMessageFieldId(), mapper.buildFailureMessage(
- tableFieldId, rows, batchResult.getItems()));
- update.put(conf.getTotalFieldId(), batchResult.getTotal());
- update.put(conf.getSuccessFieldId(), batchResult.getSuccessCount());
- update.put(conf.getFailedFieldId(), batchResult.getFailedCount());
- Map<String, Object> bodyExt = new HashMap<>();
- bodyExt.put("useLatestVersion", true);
- bodyExt.put("ignoreEmpty", false);
- try {
- ydClientForm.updateForm(auth(), formInstanceId, JSON.toJSONString(update), bodyExt);
- return EiamFormSyncResult.of(formInstanceId, batchResult, true, "回写成功");
- } catch (RuntimeException ex) {
- log.error("宜搭实例执行结果回写失败, formInstanceId={}", formInstanceId, ex);
- return EiamFormSyncResult.of(formInstanceId, batchResult, false,
- StringUtils.defaultIfBlank(ex.getMessage(), "宜搭回写失败"));
- }
- }
- @SuppressWarnings("unchecked")
- private Map<String, Object> formData(Map<String, Object> instance) {
- if (instance == null || instance.get("formData") == null) {
- throw new McException("YIDA_FORM_DATA_EMPTY", "宜搭实例数据为空");
- }
- Object value = instance.get("formData");
- if (value instanceof Map) {
- return (Map<String, Object>) value;
- }
- Map<String, Object> parsed = JSON.parseObject(String.valueOf(value), Map.class);
- if (parsed == null) {
- throw new McException("YIDA_FORM_DATA_INVALID", "宜搭实例 formData 格式错误");
- }
- return parsed;
- }
- @SuppressWarnings("unchecked")
- private List<Map<String, Object>> resolveDetailRows(String formInstanceId,
- String tableFieldId,
- Object inlineValue) {
- List<Map<String, Object>> inlineRows = inlineValue instanceof List
- ? (List<Map<String, Object>>) inlineValue : new ArrayList<>();
- // fixme 详情接口最多内联 50 行;只有恰好 50 行时才可能被截断,必须单独分页查询子表。
- if (inlineRows.size() == YDConf.PAGE_SIZE_DETAILS) {
- try {
- List<Map> details = ydService.queryDetails(YDParam.builder()
- .appType(ydConf.getAppType())
- .systemToken(ydConf.getSystemToken())
- .formInstanceId(formInstanceId)
- .tableFieldId(tableFieldId)
- .pageNumber(1)
- .build());
- return details == null ? inlineRows : (List<Map<String, Object>>) (List<?>) details;
- } catch (NullPointerException ex) {
- log.warn("宜搭子表分页查询空数据,退回内联 50 行, formInstanceId={}, tableFieldId={}",
- formInstanceId, tableFieldId);
- }
- }
- return inlineRows;
- }
- private void validateRequest(String formInstanceId, String tableFieldId) {
- if (StringUtils.isBlank(formInstanceId)) {
- throw new McException("YIDA_FORM_INSTANCE_ID_EMPTY", "formInstanceId 不能为空");
- }
- if (StringUtils.isBlank(tableFieldId)) {
- throw new McException("YIDA_FIELD_CONFIG_EMPTY", "人员子表 fieldId 未配置");
- }
- }
- private void validateForm(Map<String, Object> instance, String expectedFormUuid) {
- if (instance == null) {
- throw new McException("YIDA_FORM_EMPTY", "宜搭实例查询结果为空");
- }
- String actualFormUuid = text(instance.get("modelUuid"));
- if (StringUtils.isNotBlank(expectedFormUuid) && StringUtils.isNotBlank(actualFormUuid)
- && !StringUtils.equals(expectedFormUuid, actualFormUuid)) {
- throw new McException("YIDA_FORM_MISMATCH", "宜搭实例与当前同步场景不匹配");
- }
- }
- private YDAuth auth() {
- return YDAuth.ofGlobal(ydConf);
- }
- private String firstText(Object value) {
- if (value instanceof Iterable) {
- for (Object item : (Iterable<?>) value) {
- return text(item);
- }
- return null;
- }
- return text(value);
- }
- private boolean requiresOrganizationalUnit(List<String> updateContents) {
- return updateContents.contains(BentelerYidaFormMapper.UPDATE_PRIMARY_ORG)
- || updateContents.contains(BentelerYidaFormMapper.ADD_ORG);
- }
- private List<String> texts(Object value) {
- List<String> values = new ArrayList<>();
- if (value instanceof Iterable) {
- for (Object item : (Iterable<?>) value) {
- String itemText = text(item);
- if (StringUtils.isNotBlank(itemText)) {
- values.add(itemText);
- }
- }
- return values;
- }
- String itemText = text(value);
- if (StringUtils.isNotBlank(itemText)) {
- values.add(itemText);
- }
- return values;
- }
- private String text(Object value) {
- return value == null ? null : StringUtils.trimToNull(String.valueOf(value));
- }
- }
|