构建用户树形结构
This commit is contained in:
@@ -120,4 +120,16 @@ public class LbDepartmentUserController {
|
||||
}
|
||||
return ResponseEntity.badRequest().body(result);
|
||||
}
|
||||
|
||||
@GetMapping("/tree")
|
||||
@Operation(summary = "部门用户树形结构")
|
||||
public ResponseEntity<Map<String, Object>> tree(
|
||||
@Parameter(description = "租户id", required = true) @RequestParam String tenantId) {
|
||||
Map<String, Object> result = lbDepartmentUserService.getDepartmentUserTree(tenantId);
|
||||
Boolean success = (Boolean) result.get("success");
|
||||
if (success != null && success) {
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
return ResponseEntity.badRequest().body(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,4 +35,9 @@ public interface ILbDepartmentUserService extends IService<LbDepartmentUser> {
|
||||
* 从 lb_user 同步到 lb_department_user,并按 pid 构建 org_chain 上级链条。
|
||||
*/
|
||||
Map<String, Object> syncFromLbUser(String tenantId);
|
||||
|
||||
/**
|
||||
* 按租户查询部门用户并构建父子树(parent_id 对应 lb_user.pid)。
|
||||
*/
|
||||
Map<String, Object> getDepartmentUserTree(String tenantId);
|
||||
}
|
||||
|
||||
@@ -433,7 +433,7 @@ public class LbAssessmentApplyServiceImpl
|
||||
String moderatorDateTimeText = formatModeratorConnectDateTime(record.getApplicationDatetime());
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(teacherName).append(" 老师,您好!\n");
|
||||
sb.append(teacherName).append(" ,您好!\n");
|
||||
if (!assessmentDateTimeText.isEmpty()) {
|
||||
sb.append(assessmentDateTimeText).append("由您主评\n");
|
||||
} else {
|
||||
@@ -442,7 +442,7 @@ public class LbAssessmentApplyServiceImpl
|
||||
sb.append("申评人: ").append(applicantName).append('\n');
|
||||
sb.append("同事: ").append(colleagueName).append('\n');
|
||||
sb.append("团队长: ").append(teamLeaderName).append('\n');
|
||||
sb.append("评估老师: ").append(teacherName).append("老师\n");
|
||||
sb.append("评估老师: ").append(teacherName).append("\n");
|
||||
sb.append("主持人: ").append(moderatorName);
|
||||
if (!moderatorDateTimeText.isEmpty()) {
|
||||
sb.append(" ").append(moderatorDateTimeText);
|
||||
|
||||
@@ -17,7 +17,9 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
@@ -582,4 +584,153 @@ public class LbDepartmentUserServiceImpl extends ServiceImpl<LbDepartmentUserMap
|
||||
}
|
||||
return user.getId() == null ? null : String.valueOf(user.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getDepartmentUserTree(String tenantId) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
if (tenantId == null || tenantId.trim().isEmpty()) {
|
||||
result.put("success", false);
|
||||
result.put("message", "租户id不能为空");
|
||||
return result;
|
||||
}
|
||||
String tenantIdTrim = tenantId.trim();
|
||||
|
||||
List<LbDepartmentUser> deptUsers = this.list(
|
||||
new LambdaQueryWrapper<LbDepartmentUser>()
|
||||
.eq(LbDepartmentUser::getTenantId, tenantIdTrim));
|
||||
if (deptUsers == null || deptUsers.isEmpty()) {
|
||||
result.put("success", true);
|
||||
result.put("message", "查询成功");
|
||||
result.put("data", new ArrayList<>());
|
||||
result.put("total", 0);
|
||||
result.put("tenantId", tenantIdTrim);
|
||||
return result;
|
||||
}
|
||||
|
||||
Map<String, LbDepartmentUser> userRecordMap = new LinkedHashMap<>();
|
||||
for (LbDepartmentUser row : deptUsers) {
|
||||
String uid = trimToNull(row.getUserId());
|
||||
if (uid == null) {
|
||||
continue;
|
||||
}
|
||||
LbDepartmentUser existing = userRecordMap.get(uid);
|
||||
if (existing == null || isNewerDepartmentUser(row, existing)) {
|
||||
userRecordMap.put(uid, row);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, String> userIdByRecordId = new HashMap<>();
|
||||
Set<String> allUserIds = new HashSet<>(userRecordMap.keySet());
|
||||
for (LbDepartmentUser row : deptUsers) {
|
||||
String rowId = trimToNull(row.getId());
|
||||
String uid = trimToNull(row.getUserId());
|
||||
if (rowId != null && uid != null) {
|
||||
userIdByRecordId.put(rowId, uid);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, String> parentByUserId = new HashMap<>();
|
||||
for (LbDepartmentUser row : userRecordMap.values()) {
|
||||
String uid = row.getUserId().trim();
|
||||
String parentUserId = resolveParentUserId(row, allUserIds, userIdByRecordId);
|
||||
if (parentUserId != null) {
|
||||
parentByUserId.put(uid, parentUserId);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Map<String, Object>> nodeByUserId = new LinkedHashMap<>();
|
||||
for (LbDepartmentUser row : userRecordMap.values()) {
|
||||
nodeByUserId.put(row.getUserId().trim(), toDepartmentUserTreeNode(row));
|
||||
}
|
||||
|
||||
List<Map<String, Object>> treeRoots = new ArrayList<>();
|
||||
for (Map.Entry<String, Map<String, Object>> entry : nodeByUserId.entrySet()) {
|
||||
String userId = entry.getKey();
|
||||
Map<String, Object> node = entry.getValue();
|
||||
String parentUserId = parentByUserId.get(userId);
|
||||
Map<String, Object> parentNode = parentUserId == null ? null : nodeByUserId.get(parentUserId);
|
||||
if (parentNode == null) {
|
||||
treeRoots.add(node);
|
||||
continue;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> children = (List<Map<String, Object>>) parentNode.get("children");
|
||||
children.add(node);
|
||||
}
|
||||
sortDepartmentUserTreeByName(treeRoots);
|
||||
|
||||
result.put("success", true);
|
||||
result.put("message", "查询成功");
|
||||
result.put("data", treeRoots);
|
||||
result.put("total", nodeByUserId.size());
|
||||
result.put("tenantId", tenantIdTrim);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
result.put("success", false);
|
||||
result.put("message", "查询树形结构异常:" + e.getMessage());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* parent_id 兼容两种存法:父 user_id,或父记录 id(UUID)。
|
||||
*/
|
||||
private static String resolveParentUserId(LbDepartmentUser row,
|
||||
Set<String> allUserIds,
|
||||
Map<String, String> userIdByRecordId) {
|
||||
String parentRef = trimToNull(row.getParentId());
|
||||
if (parentRef == null) {
|
||||
return null;
|
||||
}
|
||||
if (allUserIds.contains(parentRef)) {
|
||||
return parentRef;
|
||||
}
|
||||
return userIdByRecordId.get(parentRef);
|
||||
}
|
||||
|
||||
private static Map<String, Object> toDepartmentUserTreeNode(LbDepartmentUser row) {
|
||||
Map<String, Object> node = new LinkedHashMap<>();
|
||||
node.put("userId", trimToNull(row.getUserId()));
|
||||
node.put("name", trimToNull(row.getName()));
|
||||
node.put("phone", trimToNull(row.getPhone()));
|
||||
node.put("joinDate", row.getJoinDate());
|
||||
node.put("children", new ArrayList<Map<String, Object>>());
|
||||
return node;
|
||||
}
|
||||
|
||||
private static boolean isNewerDepartmentUser(LbDepartmentUser candidate, LbDepartmentUser existing) {
|
||||
LocalDateTime candidateTime = candidate.getUpdateTime() != null
|
||||
? candidate.getUpdateTime() : candidate.getCreateTime();
|
||||
LocalDateTime existingTime = existing.getUpdateTime() != null
|
||||
? existing.getUpdateTime() : existing.getCreateTime();
|
||||
if (candidateTime == null) {
|
||||
return false;
|
||||
}
|
||||
if (existingTime == null) {
|
||||
return true;
|
||||
}
|
||||
return candidateTime.isAfter(existingTime);
|
||||
}
|
||||
|
||||
private static void sortDepartmentUserTreeByName(List<Map<String, Object>> nodes) {
|
||||
nodes.sort(Comparator.comparing(
|
||||
(Map<String, Object> m) -> (String) m.get("name"),
|
||||
Comparator.nullsLast(String::compareTo)));
|
||||
for (Map<String, Object> node : nodes) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> children = (List<Map<String, Object>>) node.get("children");
|
||||
if (children != null && !children.isEmpty()) {
|
||||
sortDepartmentUserTreeByName(children);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String trimToNull(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
String trimmed = value.trim();
|
||||
return trimmed.isEmpty() ? null : trimmed;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user