🐛 修复单据号取号忽略逻辑删除,并优化OA人员组织绑定
人员同步改为绑定已有组织并归并旁路存量;付款/开票/结算/对账等取号按最大流水含已删数据;运单导入数量单位改读计量单位主数据。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+2
-2
@@ -263,7 +263,7 @@ public class OASyncServiceImpl implements IOASyncService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 OA 人员列表同步组织与人员
|
||||
* 从 OA 人员列表同步人员并绑定已有组织(不维护组织树,须先同步组织架构)
|
||||
*
|
||||
* @param startTime 增量查询开始时间,为空则全量
|
||||
* @return 处理的人员数量
|
||||
@@ -284,7 +284,7 @@ public class OASyncServiceImpl implements IOASyncService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 按页从 OA 人员列表同步组织与人员
|
||||
* 按页从 OA 人员列表同步人员并绑定已有组织(不维护组织树,须先同步组织架构)
|
||||
*
|
||||
* @param current 当前页
|
||||
* @param size 每页条数
|
||||
|
||||
+324
-194
@@ -30,7 +30,6 @@ import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springblade.common.constant.DataStatusEnum;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
import org.springblade.core.tool.constant.BladeConstant;
|
||||
import org.springblade.core.tool.utils.DigestUtil;
|
||||
@@ -53,7 +52,6 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -66,10 +64,9 @@ import java.util.stream.Collectors;
|
||||
import static org.springblade.common.constant.CommonConstant.DEFAULT_PARAM_PASSWORD;
|
||||
import static org.springblade.common.constant.CommonConstant.DEFAULT_PARAM_ROLE;
|
||||
import static org.springblade.common.constant.CommonConstant.DEFAULT_ROLE;
|
||||
import static org.springblade.common.constant.CommonConstant.YES;
|
||||
|
||||
/**
|
||||
* 从 OA 人员列表提取组织并同步人员
|
||||
* OA 人员同步:绑定已有组织机构,不维护组织树
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@@ -86,104 +83,312 @@ public class OaUserListSyncHelper {
|
||||
private final IRoleService roleService;
|
||||
|
||||
/**
|
||||
* 从人员数据提取二级公司、三级部门,并挂到集团顶级(id=1/GWWL) 下
|
||||
* 加载已有组织索引,并将人员旁路产生的 OAC/OAD 存量归并到正式组织。
|
||||
* <p>人员同步不再新建/更新组织树,须先执行组织架构同步。</p>
|
||||
*
|
||||
* @param oaPersons OA人员
|
||||
* @return 组织索引
|
||||
* @return 组织索引(仅含已有组织)
|
||||
*/
|
||||
public OaOrgIndex syncOrgsFromPersons(List<OAPersonResponse> oaPersons) {
|
||||
OaOrgIndex orgIndex = new OaOrgIndex();
|
||||
if (CollectionUtil.isEmpty(oaPersons)) {
|
||||
return orgIndex;
|
||||
}
|
||||
Date orgSyncStart = new Date();
|
||||
Dept rootCompany = this.getOrCreateRootCompany();
|
||||
String tenantId = resolveTenantId();
|
||||
Map<String, OAPersonResponse> companyPersonMap = new LinkedHashMap<>();
|
||||
Map<String, OAPersonResponse> departmentPersonMap = new LinkedHashMap<>();
|
||||
for (OAPersonResponse oaPerson : oaPersons) {
|
||||
String companyKey = resolveCompanyKey(oaPerson);
|
||||
if (StringUtils.isNotBlank(companyKey) && StringUtils.isNotBlank(oaPerson.getSubcompanyname())) {
|
||||
companyPersonMap.putIfAbsent(companyKey, oaPerson);
|
||||
}
|
||||
String departmentKey = resolveDepartmentKey(oaPerson);
|
||||
if (StringUtils.isNotBlank(departmentKey) && StringUtils.isNotBlank(oaPerson.getDepartmentname())
|
||||
&& StringUtils.isNotBlank(oaPerson.getSubcompanyname())) {
|
||||
departmentPersonMap.putIfAbsent(departmentKey, oaPerson);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Dept> existingCompanyByCode = new HashMap<>();
|
||||
Map<String, Dept> existingCompanyByName = new HashMap<>();
|
||||
deptService.list(Wrappers.<Dept>lambdaQuery()
|
||||
.eq(Dept::getParentId, rootCompany.getId())
|
||||
.eq(Dept::getDeptCategory, DeptCategory.COMPANY.getCode())
|
||||
).forEach(dept -> {
|
||||
if (StringUtils.isNotBlank(dept.getDeptCode())) {
|
||||
existingCompanyByCode.put(dept.getDeptCode(), dept);
|
||||
}
|
||||
if (StringUtils.isNotBlank(dept.getDeptName())) {
|
||||
existingCompanyByName.put(dept.getDeptName(), dept);
|
||||
}
|
||||
});
|
||||
List<Dept> addCompanies = new ArrayList<>();
|
||||
List<Dept> updateCompanies = new ArrayList<>();
|
||||
companyPersonMap.forEach((companyKey, oaPerson) -> {
|
||||
String oaCode = buildCompanyCode(oaPerson, companyKey);
|
||||
Dept existing = existingCompanyByCode.get(oaCode);
|
||||
if (existing == null) {
|
||||
existing = existingCompanyByName.get(oaPerson.getSubcompanyname());
|
||||
}
|
||||
Dept company = this.upsertOrg(oaPerson.getSubcompanyname(), oaCode, existing, rootCompany, tenantId,
|
||||
DeptCategory.COMPANY, addCompanies, updateCompanies);
|
||||
orgIndex.companyByOaId.put(companyKey, company);
|
||||
});
|
||||
this.saveOrgs(addCompanies, updateCompanies, DeptCategory.COMPANY);
|
||||
|
||||
Map<String, Dept> existingDeptByCode = new HashMap<>();
|
||||
Map<String, Dept> existingDeptByParentAndName = new HashMap<>();
|
||||
List<Long> companyIds = orgIndex.companyByOaId.values().stream()
|
||||
.map(Dept::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.toList();
|
||||
if (CollectionUtil.isNotEmpty(companyIds)) {
|
||||
deptService.list(Wrappers.<Dept>lambdaQuery()
|
||||
.in(Dept::getParentId, companyIds)
|
||||
.eq(Dept::getDeptCategory, DeptCategory.DEPT.getCode())
|
||||
).forEach(dept -> {
|
||||
if (StringUtils.isNotBlank(dept.getDeptCode())) {
|
||||
existingDeptByCode.put(dept.getDeptCode(), dept);
|
||||
}
|
||||
if (dept.getParentId() != null && StringUtils.isNotBlank(dept.getDeptName())) {
|
||||
existingDeptByParentAndName.put(dept.getParentId() + "#" + dept.getDeptName(), dept);
|
||||
}
|
||||
});
|
||||
}
|
||||
List<Dept> addDepartments = new ArrayList<>();
|
||||
List<Dept> updateDepartments = new ArrayList<>();
|
||||
departmentPersonMap.forEach((departmentKey, oaPerson) -> {
|
||||
Dept parentCompany = orgIndex.findCompany(oaPerson);
|
||||
if (parentCompany == null || parentCompany.getId() == null) {
|
||||
return;
|
||||
}
|
||||
String oaCode = buildDepartmentCode(oaPerson, departmentKey);
|
||||
Dept existing = existingDeptByCode.get(oaCode);
|
||||
if (existing == null) {
|
||||
existing = existingDeptByParentAndName.get(parentCompany.getId() + "#" + oaPerson.getDepartmentname());
|
||||
}
|
||||
Dept department = this.upsertOrg(oaPerson.getDepartmentname(), oaCode, existing, parentCompany, tenantId,
|
||||
DeptCategory.DEPT, addDepartments, updateDepartments);
|
||||
orgIndex.deptByOaId.put(departmentKey, department);
|
||||
orgIndex.deptByCompanyAndName.put(resolveCompanyKey(oaPerson) + "#" + oaPerson.getDepartmentname(), department);
|
||||
});
|
||||
this.saveOrgs(addDepartments, updateDepartments, DeptCategory.DEPT);
|
||||
deptService.updateAncestors(orgSyncStart);
|
||||
ComposeLogUtil.getLastLog().info("同步人员提取组织完成,二级公司{}个,三级部门{}个",
|
||||
this.repairPersonBypassOrgs();
|
||||
this.loadExistingOrgIndex(orgIndex);
|
||||
ComposeLogUtil.getLastLog().info("人员同步绑定已有组织,二级公司{}个,三级部门{}个",
|
||||
orgIndex.companyByOaId.size(), orgIndex.deptByOaId.size());
|
||||
return orgIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 OAC/OAD 旁路节点上的人员关系迁移到同 oa_id 的正式组织,并逻辑删除旁路节点
|
||||
*/
|
||||
private void repairPersonBypassOrgs() {
|
||||
List<Dept> companyList = deptService.list(Wrappers.<Dept>lambdaQuery()
|
||||
.eq(Dept::getDeptCategory, DeptCategory.COMPANY.getCode()));
|
||||
List<Dept> departmentList = deptService.list(Wrappers.<Dept>lambdaQuery()
|
||||
.eq(Dept::getDeptCategory, DeptCategory.DEPT.getCode()));
|
||||
Map<String, Dept> officialCompanyByOaId = new HashMap<>();
|
||||
Map<String, Dept> officialDeptByOaId = new HashMap<>();
|
||||
Map<Long, Dept> companyById = new HashMap<>();
|
||||
for (Dept company : companyList) {
|
||||
if (company.getId() != null) {
|
||||
companyById.put(company.getId(), company);
|
||||
}
|
||||
if (!isPersonBypassCode(company.getDeptCode(), DeptCategory.COMPANY)) {
|
||||
this.putPreferredByOaId(officialCompanyByOaId, company, DeptCategory.COMPANY);
|
||||
}
|
||||
}
|
||||
for (Dept department : departmentList) {
|
||||
if (!isPersonBypassCode(department.getDeptCode(), DeptCategory.DEPT)) {
|
||||
this.putPreferredByOaId(officialDeptByOaId, department, DeptCategory.DEPT);
|
||||
}
|
||||
}
|
||||
|
||||
Set<Long> softDeleteIds = new HashSet<>();
|
||||
Set<Long> affectedUserIds = new HashSet<>();
|
||||
int migratedDeptBindingCount = 0;
|
||||
int migratedCompanyBindingCount = 0;
|
||||
|
||||
for (Dept bypass : departmentList) {
|
||||
if (!isPersonBypassCode(bypass.getDeptCode(), DeptCategory.DEPT) || bypass.getId() == null) {
|
||||
continue;
|
||||
}
|
||||
String oaId = StringUtils.trimToNull(bypass.getOaId());
|
||||
if (oaId == null) {
|
||||
oaId = extractOaIdFromBypassCode(bypass.getDeptCode(), DeptCategory.DEPT);
|
||||
}
|
||||
if (oaId == null) {
|
||||
continue;
|
||||
}
|
||||
Dept official = officialDeptByOaId.get(oaId);
|
||||
if (official == null || official.getId() == null || Objects.equals(official.getId(), bypass.getId())
|
||||
|| isPersonBypassCode(official.getDeptCode(), DeptCategory.DEPT)) {
|
||||
continue;
|
||||
}
|
||||
Dept officialCompany = resolveBelongCompany(official, companyById);
|
||||
migratedDeptBindingCount += this.migrateUserDeptBindings(bypass, official, officialCompany, affectedUserIds);
|
||||
softDeleteIds.add(bypass.getId());
|
||||
}
|
||||
|
||||
for (Dept bypass : companyList) {
|
||||
if (!isPersonBypassCode(bypass.getDeptCode(), DeptCategory.COMPANY) || bypass.getId() == null) {
|
||||
continue;
|
||||
}
|
||||
String oaId = StringUtils.trimToNull(bypass.getOaId());
|
||||
if (oaId == null) {
|
||||
oaId = extractOaIdFromBypassCode(bypass.getDeptCode(), DeptCategory.COMPANY);
|
||||
}
|
||||
if (oaId == null) {
|
||||
continue;
|
||||
}
|
||||
Dept official = officialCompanyByOaId.get(oaId);
|
||||
if (official == null || official.getId() == null || Objects.equals(official.getId(), bypass.getId())
|
||||
|| isPersonBypassCode(official.getDeptCode(), DeptCategory.COMPANY)) {
|
||||
continue;
|
||||
}
|
||||
migratedCompanyBindingCount += this.migrateUserCompanyBindings(bypass, official, affectedUserIds);
|
||||
long childCount = deptService.count(Wrappers.<Dept>lambdaQuery().eq(Dept::getParentId, bypass.getId()));
|
||||
if (childCount == 0) {
|
||||
softDeleteIds.add(bypass.getId());
|
||||
} else {
|
||||
ComposeLogUtil.getLastLog().warn("旁路公司仍有子节点,暂不删除 companyId={} deptCode={} childCount={}",
|
||||
bypass.getId(), bypass.getDeptCode(), childCount);
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtil.isNotEmpty(softDeleteIds)) {
|
||||
deptService.removeByIds(softDeleteIds);
|
||||
ComposeLogUtil.getLastLog().info("人员同步归并旁路组织完成,迁移部门关系{}条,迁移公司关系{}条,逻辑删除旁路节点{}个",
|
||||
migratedDeptBindingCount, migratedCompanyBindingCount, softDeleteIds.size());
|
||||
} else if (migratedDeptBindingCount > 0 || migratedCompanyBindingCount > 0) {
|
||||
ComposeLogUtil.getLastLog().info("人员同步归并旁路组织完成,迁移部门关系{}条,迁移公司关系{}条",
|
||||
migratedDeptBindingCount, migratedCompanyBindingCount);
|
||||
}
|
||||
this.refreshUserDeptFields(affectedUserIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅加载已有组织,按 oa_id / 名称建立索引供人员绑定
|
||||
*/
|
||||
private void loadExistingOrgIndex(OaOrgIndex orgIndex) {
|
||||
Map<String, Dept> companyByOaId = new HashMap<>();
|
||||
Map<String, Dept> companyByName = new HashMap<>();
|
||||
Map<Long, Dept> companyById = new HashMap<>();
|
||||
deptService.list(Wrappers.<Dept>lambdaQuery()
|
||||
.eq(Dept::getDeptCategory, DeptCategory.COMPANY.getCode())
|
||||
).forEach(dept -> {
|
||||
if (dept.getId() != null) {
|
||||
companyById.put(dept.getId(), dept);
|
||||
}
|
||||
this.putPreferredByOaKey(companyByOaId, resolveOrgOaKey(dept, DeptCategory.COMPANY), dept, DeptCategory.COMPANY);
|
||||
if (StringUtils.isNotBlank(dept.getDeptName())) {
|
||||
Dept previous = companyByName.get(dept.getDeptName());
|
||||
if (previous == null
|
||||
|| (isPersonBypassCode(previous.getDeptCode(), DeptCategory.COMPANY)
|
||||
&& !isPersonBypassCode(dept.getDeptCode(), DeptCategory.COMPANY))) {
|
||||
companyByName.put(dept.getDeptName(), dept);
|
||||
}
|
||||
}
|
||||
});
|
||||
companyByOaId.forEach((oaId, dept) -> orgIndex.companyByOaId.put(oaId, dept));
|
||||
companyByName.forEach((name, dept) -> orgIndex.companyByOaId.putIfAbsent("NAME:" + name, dept));
|
||||
|
||||
Map<String, Dept> deptByOaId = new HashMap<>();
|
||||
deptService.list(Wrappers.<Dept>lambdaQuery()
|
||||
.eq(Dept::getDeptCategory, DeptCategory.DEPT.getCode())
|
||||
).forEach(dept -> {
|
||||
this.putPreferredByOaKey(deptByOaId, resolveOrgOaKey(dept, DeptCategory.DEPT), dept, DeptCategory.DEPT);
|
||||
Dept parentCompany = resolveBelongCompany(dept, companyById);
|
||||
if (parentCompany == null || StringUtils.isBlank(dept.getDeptName())) {
|
||||
return;
|
||||
}
|
||||
String companyKey = resolveOrgOaKey(parentCompany, DeptCategory.COMPANY);
|
||||
if (companyKey == null && StringUtils.isNotBlank(parentCompany.getDeptName())) {
|
||||
companyKey = "NAME:" + parentCompany.getDeptName();
|
||||
}
|
||||
if (companyKey == null) {
|
||||
return;
|
||||
}
|
||||
String nameKey = companyKey + "#" + dept.getDeptName();
|
||||
Dept previous = orgIndex.deptByCompanyAndName.get(nameKey);
|
||||
if (previous == null
|
||||
|| (isPersonBypassCode(previous.getDeptCode(), DeptCategory.DEPT)
|
||||
&& !isPersonBypassCode(dept.getDeptCode(), DeptCategory.DEPT))) {
|
||||
orgIndex.deptByCompanyAndName.put(nameKey, dept);
|
||||
}
|
||||
});
|
||||
orgIndex.deptByOaId.putAll(deptByOaId);
|
||||
}
|
||||
|
||||
/** 优先取 oa_id;旁路空 oa_id 时从 OAC/OAD 编码后缀解析 */
|
||||
private String resolveOrgOaKey(Dept dept, DeptCategory deptCategory) {
|
||||
if (dept == null) {
|
||||
return null;
|
||||
}
|
||||
String oaId = StringUtils.trimToNull(dept.getOaId());
|
||||
if (oaId != null) {
|
||||
return oaId;
|
||||
}
|
||||
return extractOaIdFromBypassCode(dept.getDeptCode(), deptCategory);
|
||||
}
|
||||
|
||||
private int migrateUserDeptBindings(Dept bypass, Dept official, Dept officialCompany, Set<Long> affectedUserIds) {
|
||||
List<UserDept> bindingList = userDeptService.list(Wrappers.<UserDept>lambdaQuery()
|
||||
.and(wrapper -> wrapper.eq(UserDept::getDeptId, bypass.getId())
|
||||
.or().eq(UserDept::getDeptCode, bypass.getDeptCode())));
|
||||
if (CollectionUtil.isEmpty(bindingList)) {
|
||||
return 0;
|
||||
}
|
||||
Set<Long> userIds = bindingList.stream()
|
||||
.map(UserDept::getUserId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
Map<String, UserDept> existingByKey = userDeptService.list(Wrappers.<UserDept>lambdaQuery()
|
||||
.in(UserDept::getUserId, userIds)
|
||||
).stream()
|
||||
.collect(Collectors.toMap(this::getUserDeptKey, userDept -> userDept, (first, second) -> first));
|
||||
List<UserDept> updateList = new ArrayList<>();
|
||||
List<Long> removeIds = new ArrayList<>();
|
||||
for (UserDept binding : bindingList) {
|
||||
if (binding.getUserId() == null) {
|
||||
continue;
|
||||
}
|
||||
affectedUserIds.add(binding.getUserId());
|
||||
String companyCode = officialCompany != null ? officialCompany.getDeptCode() : binding.getCompanyCode();
|
||||
String companyName = officialCompany != null ? officialCompany.getDeptName() : binding.getCompanyName();
|
||||
String newKey = binding.getUserId() + StringUtils.defaultString(companyCode)
|
||||
+ StringUtils.defaultString(official.getDeptCode());
|
||||
UserDept alreadyOfficial = existingByKey.get(newKey);
|
||||
if (alreadyOfficial != null && !Objects.equals(alreadyOfficial.getId(), binding.getId())) {
|
||||
removeIds.add(binding.getId());
|
||||
continue;
|
||||
}
|
||||
binding.setDeptId(official.getId());
|
||||
binding.setDeptCode(official.getDeptCode());
|
||||
binding.setDeptName(official.getDeptName());
|
||||
if (officialCompany != null) {
|
||||
binding.setCompanyCode(companyCode);
|
||||
binding.setCompanyName(companyName);
|
||||
}
|
||||
updateList.add(binding);
|
||||
existingByKey.put(newKey, binding);
|
||||
}
|
||||
if (CollectionUtil.isNotEmpty(updateList)) {
|
||||
userDeptService.updateBatchById(updateList);
|
||||
}
|
||||
if (CollectionUtil.isNotEmpty(removeIds)) {
|
||||
userDeptService.removeByIds(removeIds);
|
||||
}
|
||||
return updateList.size() + removeIds.size();
|
||||
}
|
||||
|
||||
private int migrateUserCompanyBindings(Dept bypass, Dept official, Set<Long> affectedUserIds) {
|
||||
if (StringUtils.isBlank(bypass.getDeptCode())) {
|
||||
return 0;
|
||||
}
|
||||
List<UserDept> bindingList = userDeptService.list(Wrappers.<UserDept>lambdaQuery()
|
||||
.eq(UserDept::getCompanyCode, bypass.getDeptCode()));
|
||||
if (CollectionUtil.isEmpty(bindingList)) {
|
||||
return 0;
|
||||
}
|
||||
List<UserDept> updateList = new ArrayList<>();
|
||||
for (UserDept binding : bindingList) {
|
||||
if (binding.getUserId() != null) {
|
||||
affectedUserIds.add(binding.getUserId());
|
||||
}
|
||||
binding.setCompanyCode(official.getDeptCode());
|
||||
binding.setCompanyName(official.getDeptName());
|
||||
updateList.add(binding);
|
||||
}
|
||||
userDeptService.updateBatchById(updateList);
|
||||
return updateList.size();
|
||||
}
|
||||
|
||||
private void refreshUserDeptFields(Set<Long> userIds) {
|
||||
if (CollectionUtil.isEmpty(userIds)) {
|
||||
return;
|
||||
}
|
||||
List<UserDeptIdsVO> userDeptIdsList = userDeptService.queryUserDeptIds(userIds);
|
||||
List<User> updateUserParams = userDeptIdsList.stream()
|
||||
.filter(userDeptIds -> StringUtils.isNotBlank(userDeptIds.getDeptIds()))
|
||||
.filter(userDeptIds -> {
|
||||
int deptIdLength = userDeptIds.getDeptIds().length();
|
||||
int deptCodesLength = StringUtils.length(userDeptIds.getDeptCodes());
|
||||
return deptIdLength <= MAX_DEPT_ID_LENGTH && deptCodesLength <= MAX_DEPT_ID_LENGTH;
|
||||
})
|
||||
.map(userDeptIds -> {
|
||||
User user = new User();
|
||||
user.setId(userDeptIds.getUserId());
|
||||
user.setDeptId(userDeptIds.getDeptIds());
|
||||
user.setDeptCodes(userDeptIds.getDeptCodes());
|
||||
return user;
|
||||
}).toList();
|
||||
if (CollectionUtil.isNotEmpty(updateUserParams)) {
|
||||
userService.updateBatchById(updateUserParams);
|
||||
}
|
||||
}
|
||||
|
||||
private Dept resolveBelongCompany(Dept department, Map<Long, Dept> companyById) {
|
||||
if (department == null) {
|
||||
return null;
|
||||
}
|
||||
if (department.getParentId() != null) {
|
||||
Dept parent = companyById.get(department.getParentId());
|
||||
if (parent != null) {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotBlank(department.getBelongCompanyCode())) {
|
||||
return companyById.values().stream()
|
||||
.filter(company -> department.getBelongCompanyCode().equals(company.getDeptCode()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 OAC37 / OAD37 旁路编码解析 OA 主键;哈希旁路(OACNxxx)返回 null
|
||||
*/
|
||||
private String extractOaIdFromBypassCode(String deptCode, DeptCategory deptCategory) {
|
||||
if (StringUtils.isBlank(deptCode) || !isPersonBypassCode(deptCode, deptCategory)) {
|
||||
return null;
|
||||
}
|
||||
String prefix = DeptCategory.COMPANY.equals(deptCategory)
|
||||
? OAConvertConstant.COMPANY_OA_PREFIX
|
||||
: OAConvertConstant.DEPARTMENT_OA_PREFIX;
|
||||
if (deptCode.length() <= prefix.length()) {
|
||||
return null;
|
||||
}
|
||||
String suffix = deptCode.substring(prefix.length());
|
||||
if (suffix.isEmpty() || suffix.startsWith("N")) {
|
||||
return null;
|
||||
}
|
||||
return suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步人员并绑定到三级部门
|
||||
*
|
||||
@@ -395,73 +600,47 @@ public class OaUserListSyncHelper {
|
||||
return localModified.equals(remoteModified);
|
||||
}
|
||||
|
||||
private Dept getOrCreateRootCompany() {
|
||||
return deptService.ensureOaSyncRootDept();
|
||||
private boolean isPersonBypassCode(String deptCode, DeptCategory deptCategory) {
|
||||
if (StringUtils.isBlank(deptCode)) {
|
||||
return true;
|
||||
}
|
||||
if (DeptCategory.COMPANY.equals(deptCategory)) {
|
||||
return deptCode.startsWith(OAConvertConstant.COMPANY_OA_PREFIX);
|
||||
}
|
||||
return deptCode.startsWith(OAConvertConstant.DEPARTMENT_OA_PREFIX);
|
||||
}
|
||||
|
||||
private Dept upsertOrg(String name, String oaCode, Dept existing, Dept parent, String tenantId,
|
||||
DeptCategory deptCategory, List<Dept> addList, List<Dept> updateList) {
|
||||
if (existing != null) {
|
||||
Dept updateParam = new Dept();
|
||||
updateParam.setId(existing.getId());
|
||||
updateParam.setDeptName(name);
|
||||
updateParam.setFullName(name);
|
||||
updateParam.setShortName(name);
|
||||
updateParam.setParentId(parent.getId());
|
||||
updateParam.setParentCode(parent.getDeptCode());
|
||||
updateParam.setAncestors(buildAncestors(parent));
|
||||
updateParam.setIsOa(YES);
|
||||
updateParam.setSyncTime(new Date());
|
||||
updateList.add(updateParam);
|
||||
existing.setDeptName(name);
|
||||
existing.setFullName(name);
|
||||
existing.setShortName(name);
|
||||
existing.setParentId(parent.getId());
|
||||
existing.setParentCode(parent.getDeptCode());
|
||||
existing.setAncestors(updateParam.getAncestors());
|
||||
return existing;
|
||||
/** 同一 oa_id 多条时优先正式编码,避免人员挂到 OAC/OAD 旁路重复节点。 */
|
||||
private void putPreferredByOaId(Map<String, Dept> byOaId, Dept dept, DeptCategory deptCategory) {
|
||||
if (dept == null || StringUtils.isBlank(dept.getOaId())) {
|
||||
return;
|
||||
}
|
||||
Dept dept = this.buildOrgDept(name, oaCode, parent, tenantId, deptCategory);
|
||||
dept.setId(DefaultIdentifierGenerator.getInstance().nextId(null));
|
||||
addList.add(dept);
|
||||
return dept;
|
||||
this.putPreferredByOaKey(byOaId, dept.getOaId().trim(), dept, deptCategory);
|
||||
}
|
||||
|
||||
private void saveOrgs(List<Dept> addList, List<Dept> updateList, DeptCategory deptCategory) {
|
||||
if (CollectionUtil.isNotEmpty(addList)) {
|
||||
ComposeLogUtil.getLastLog().info("批量新增{}:{}", deptCategory.getName(), addList.size());
|
||||
deptService.saveBatch(addList);
|
||||
private void putPreferredByOaKey(Map<String, Dept> byOaId, String oaKey, Dept dept, DeptCategory deptCategory) {
|
||||
if (dept == null || StringUtils.isBlank(oaKey)) {
|
||||
return;
|
||||
}
|
||||
if (CollectionUtil.isNotEmpty(updateList)) {
|
||||
ComposeLogUtil.getLastLog().info("批量修改{}:{}", deptCategory.getName(), updateList.size());
|
||||
deptService.updateBatchById(updateList);
|
||||
Dept previous = byOaId.get(oaKey);
|
||||
if (previous == null) {
|
||||
byOaId.put(oaKey, dept);
|
||||
return;
|
||||
}
|
||||
boolean previousBypass = isPersonBypassCode(previous.getDeptCode(), deptCategory);
|
||||
boolean currentBypass = isPersonBypassCode(dept.getDeptCode(), deptCategory);
|
||||
if (previousBypass && !currentBypass) {
|
||||
byOaId.put(oaKey, dept);
|
||||
}
|
||||
}
|
||||
|
||||
private Dept buildOrgDept(String name, String deptCode, Dept parent, String tenantId, DeptCategory deptCategory) {
|
||||
Dept dept = new Dept();
|
||||
dept.setTenantId(tenantId);
|
||||
dept.setParentId(parent.getId());
|
||||
dept.setParentCode(parent.getDeptCode());
|
||||
dept.setAncestors(this.buildAncestors(parent));
|
||||
dept.setDeptName(name);
|
||||
dept.setFullName(name);
|
||||
dept.setShortName(name);
|
||||
dept.setDeptCode(deptCode);
|
||||
dept.setBelongCompanyCode(DeptCategory.COMPANY.equals(deptCategory) ? deptCode : parent.getBelongCompanyCode());
|
||||
dept.setDeptCategory(deptCategory.getCode());
|
||||
dept.setSort(0);
|
||||
dept.setStatus(DataStatusEnum.ENABLE.getCode());
|
||||
dept.setIsDeleted(BladeConstant.DB_NOT_DELETED);
|
||||
dept.setIsOa(YES);
|
||||
dept.setIsPlatformCompany(0);
|
||||
dept.setSyncTime(new Date());
|
||||
return dept;
|
||||
}
|
||||
|
||||
private UserDept buildUserDept(OAPersonResponse oaPerson, Map<String, Long> userMap, OaOrgIndex orgIndex) {
|
||||
Dept department = orgIndex.findDept(oaPerson);
|
||||
if (department == null || department.getId() == null) {
|
||||
ComposeLogUtil.getLastLog().warn(
|
||||
"人员未匹配到已有部门,请先同步组织架构 account={} departmentid={} departmentname={} subcompanyid1={}",
|
||||
userConvert.resolveAccount(oaPerson), oaPerson.getDepartmentid(), oaPerson.getDepartmentname(),
|
||||
oaPerson.getSubcompanyid1());
|
||||
return null;
|
||||
}
|
||||
UserDept userDept = userConvert.person2userDept(oaPerson, userMap);
|
||||
@@ -493,55 +672,6 @@ public class OaUserListSyncHelper {
|
||||
return roleList.get(0).getId().toString();
|
||||
}
|
||||
|
||||
private String resolveCompanyKey(OAPersonResponse oaPerson) {
|
||||
if (oaPerson == null) {
|
||||
return null;
|
||||
}
|
||||
if (StringUtils.isNotBlank(oaPerson.getSubcompanyid1())) {
|
||||
return oaPerson.getSubcompanyid1().trim();
|
||||
}
|
||||
if (StringUtils.isNotBlank(oaPerson.getSubcompanyname())) {
|
||||
return "NAME:" + oaPerson.getSubcompanyname().trim();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String resolveDepartmentKey(OAPersonResponse oaPerson) {
|
||||
if (oaPerson == null) {
|
||||
return null;
|
||||
}
|
||||
if (StringUtils.isNotBlank(oaPerson.getDepartmentid())) {
|
||||
return oaPerson.getDepartmentid().trim();
|
||||
}
|
||||
String companyKey = resolveCompanyKey(oaPerson);
|
||||
if (StringUtils.isNotBlank(companyKey) && StringUtils.isNotBlank(oaPerson.getDepartmentname())) {
|
||||
return companyKey + ":" + oaPerson.getDepartmentname().trim();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String buildCompanyCode(OAPersonResponse oaPerson, String companyKey) {
|
||||
if (StringUtils.isNotBlank(oaPerson.getSubcompanyid1())) {
|
||||
return OAConvertConstant.COMPANY_OA_PREFIX + oaPerson.getSubcompanyid1().trim();
|
||||
}
|
||||
return OAConvertConstant.COMPANY_OA_PREFIX + "N" + Math.abs(companyKey.hashCode());
|
||||
}
|
||||
|
||||
private String buildDepartmentCode(OAPersonResponse oaPerson, String departmentKey) {
|
||||
if (StringUtils.isNotBlank(oaPerson.getDepartmentid())) {
|
||||
return OAConvertConstant.DEPARTMENT_OA_PREFIX + oaPerson.getDepartmentid().trim();
|
||||
}
|
||||
return OAConvertConstant.DEPARTMENT_OA_PREFIX + "N" + Math.abs(departmentKey.hashCode());
|
||||
}
|
||||
|
||||
private String buildAncestors(Dept parent) {
|
||||
String ancestors = parent.getAncestors();
|
||||
if (StringUtils.isBlank(ancestors)) {
|
||||
ancestors = String.valueOf(BladeConstant.TOP_PARENT_ID);
|
||||
}
|
||||
return ancestors + "," + parent.getId();
|
||||
}
|
||||
|
||||
private String resolveTenantId() {
|
||||
String tenantId = AuthUtil.getTenantId();
|
||||
if (StringUtils.isBlank(tenantId)) {
|
||||
|
||||
Reference in New Issue
Block a user