构建用户树形结构

This commit is contained in:
2026-05-19 21:25:07 +08:00
parent 28c57666d7
commit e84ef0f244
4 changed files with 170 additions and 2 deletions

View File

@@ -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);

View File

@@ -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;
}
}