feat:关系图谱优化

This commit is contained in:
dzc committed 2026-07-20 17:51:01 +08:00
1 parent 2cf4ef4d10
commit 0149da2823
6 files changed
+354 -48

No files matched your search

@@ -0,0 +1,49 @@
package com.bsd.pjcloud.admin.api.dto.user;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 修改用户关系
*/
@Data
@Schema(description = "修改用户关系")
public class SysUserRelationUpdateDto {
@NotNull(message = "关系ID不能为空")
@Schema(description = "关系ID")
private Long relationId;
@NotNull(message = "关系主语用户不能为空")
@Schema(description = "关系主语用户ID")
private Long subjectUserId;
@NotNull(message = "关系对象用户不能为空")
@Schema(description = "关系对象用户ID")
private Long objectUserId;
@NotNull(message = "关系类型不能为空")
@Schema(description = "关系类型ID")
private Long relationTypeId;
@Schema(description = "关系生效时间")
private LocalDateTime effectiveTime;
@Schema(description = "关系失效时间")
private LocalDateTime expireTime;
@Size(max = 500, message = "关系备注不能超过500个字符")
@Schema(description = "关系备注")
private String remark;
@AssertTrue(message = "关系失效时间不能早于生效时间")
@Schema(hidden = true)
public boolean isRelationTimeValid() {
return effectiveTime == null || expireTime == null || !expireTime.isBefore(effectiveTime);
}
}
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsd.pjcloud.admin.api.dto.user.SysUserRelationCreateUserDto;
import com.bsd.pjcloud.admin.api.dto.user.SysUserRelationCreateDto;
import com.bsd.pjcloud.admin.api.dto.user.SysUserRelationUpdateDto;
import com.bsd.pjcloud.admin.api.entity.user.SysUserRelationEntity;
import com.bsd.pjcloud.admin.api.vo.user.SysUserRelationGraphVo;
import com.bsd.pjcloud.admin.service.SysUserRelationService;
@@ -35,7 +36,7 @@ public class SysUserRelationController {
/**
* 查询用户关系图谱
*/
@Operation(summary = "关系图谱", description = "以指定用户为根节点查询用户关系树")
@Operation(summary = "关系图谱", description = "查询指定用户所在的完整关系图谱,并按关系方向生成业务树")
@GetMapping("/graph/{userId}")
// @PreAuthorize("@pms.hasPermission('dzc_sysUserRelation_view')")
public R<SysUserRelationGraphVo> getRelationGraph(@PathVariable Long userId) {
@@ -64,4 +65,15 @@ public class SysUserRelationController {
return R.ok(sysUserRelationService.createRelation(dto));
}
/**
* 修改已有用户关系
*/
@Operation(summary = "修改用户关系", description = "修改关系类型、方向、生效时间及备注")
@SysLog("修改用户关系")
@PutMapping("/update")
// @PreAuthorize("@pms.hasPermission('dzc_sysUserRelation_edit')")
public R<Long> updateRelation(@Valid @RequestBody SysUserRelationUpdateDto dto) {
return R.ok(sysUserRelationService.updateRelation(dto));
}
}
@@ -15,7 +15,10 @@ public interface SysUserRelationTypeMapper extends PjcloudBaseMapper<SysUserRela
default Page<SysUserRelationTypeEntity> scopePageList(Page page, SysUserRelationTypeDto dto, DataScope dataScope) {
LambdaQueryWrapper<SysUserRelationTypeEntity> wrapper = new LambdaQueryWrapper<SysUserRelationTypeEntity>()
.eq(ObjectUtil.isNotEmpty(dto.getRelationTypeId()), SysUserRelationTypeEntity::getRelationTypeId, dto.getRelationTypeId())
.like(ObjectUtil.isNotEmpty(dto.getRelationName()), SysUserRelationTypeEntity::getRelationName, dto.getRelationName());
.eq(ObjectUtil.isNotEmpty(dto.getCategory()), SysUserRelationTypeEntity::getCategory, dto.getCategory())
.like(ObjectUtil.isNotEmpty(dto.getRelationName()), SysUserRelationTypeEntity::getRelationName, dto.getRelationName())
.orderByDesc(SysUserRelationTypeEntity::getSortOrder)
.orderByDesc(SysUserRelationTypeEntity::getCreateTime);
return selectPageByScope(page, wrapper, dataScope);
}
}
@@ -3,6 +3,7 @@ package com.bsd.pjcloud.admin.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bsd.pjcloud.admin.api.dto.user.SysUserRelationCreateUserDto;
import com.bsd.pjcloud.admin.api.dto.user.SysUserRelationCreateDto;
import com.bsd.pjcloud.admin.api.dto.user.SysUserRelationUpdateDto;
import com.bsd.pjcloud.admin.api.entity.user.SysUserRelationEntity;
import com.bsd.pjcloud.admin.api.vo.user.SysUserRelationGraphVo;
@@ -11,7 +12,7 @@ public interface SysUserRelationService extends IService<SysUserRelationEntity>
/**
* 查询用户关系图谱
*
* @param userId 根用户ID
* @param userId 图谱入口用户ID
* @return 用户关系图谱
*/
SysUserRelationGraphVo getRelationGraph(Long userId);
@@ -31,4 +32,12 @@ public interface SysUserRelationService extends IService<SysUserRelationEntity>
* @return 关系ID
*/
Long createRelation(SysUserRelationCreateDto dto);
/**
* 修改已有用户关系
*
* @param dto 关系信息
* @return 关系ID
*/
Long updateRelation(SysUserRelationUpdateDto dto);
}
@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bsd.pjcloud.admin.api.dto.UserDTO;
import com.bsd.pjcloud.admin.api.dto.user.SysUserRelationCreateUserDto;
import com.bsd.pjcloud.admin.api.dto.user.SysUserRelationCreateDto;
import com.bsd.pjcloud.admin.api.dto.user.SysUserRelationUpdateDto;
import com.bsd.pjcloud.admin.api.entity.SysUser;
import com.bsd.pjcloud.admin.api.entity.user.SysUserRelationEntity;
import com.bsd.pjcloud.admin.api.entity.user.SysUserRelationTypeEntity;
@@ -22,7 +23,11 @@ import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
@@ -48,10 +53,15 @@ public class SysUserRelationServiceImpl extends ServiceImpl<SysUserRelationMappe
private final SysUserRelationTypeService sysUserRelationTypeService;
/**
* 查询入口用户所在的完整关系图谱,并按有向关系选择业务根节点生成树。
*
* @param userId 图谱入口用户ID
* @return 用户关系树
*/
@Override
public SysUserRelationGraphVo getRelationGraph(Long userId) {
SysUser rootUser = sysUserService.getById(userId);
if (rootUser == null) {
if (sysUserService.getById(userId) == null) {
throw new RuntimeException("用户不存在");
}
RelationGraphData graphData = collectRelationGraph(userId);
@@ -62,12 +72,14 @@ public class SysUserRelationServiceImpl extends ServiceImpl<SysUserRelationMappe
: sysUserRelationTypeService.listByIds(graphData.relationTypeIds).stream()
.collect(Collectors.toMap(SysUserRelationTypeEntity::getRelationTypeId,
Function.identity(), (first, second) -> first));
Long rootUserId = selectRootUserId(userId, graphData, relationTypeMap);
List<RelationGraphNode> graphNodes = buildRelationTree(rootUserId, graphData);
Map<Long, SysUserRelationGraphVo> nodeMap = graphData.nodes.stream()
Map<Long, SysUserRelationGraphVo> nodeMap = graphNodes.stream()
.map(node -> buildGraphNode(node, userMap, relationTypeMap))
.collect(Collectors.toMap(SysUserRelationGraphVo::getNodeId, Function.identity()));
SysUserRelationGraphVo rootNode = nodeMap.get(TREE_ROOT_NODE_ID);
graphData.nodes.stream()
graphNodes.stream()
.filter(node -> !Objects.equals(node.nodeId, TREE_ROOT_NODE_ID))
.forEach(node -> {
SysUserRelationGraphVo parentNode = nodeMap.get(node.parentNodeId);
@@ -93,7 +105,7 @@ public class SysUserRelationServiceImpl extends ServiceImpl<SysUserRelationMappe
Long objectUserId = dto.getObjectUserId() == null ? newUserId : dto.getObjectUserId();
SysUserRelationTypeEntity relationType = validateRelation(
subjectUserId, objectUserId, dto.getRelationTypeId());
validateRelationNotExists(subjectUserId, objectUserId, relationType);
validateRelationNotExists(subjectUserId, objectUserId, relationType, null);
SysUserRelationEntity relation = new SysUserRelationEntity();
relation.setSubjectUserId(subjectUserId);
@@ -111,7 +123,7 @@ public class SysUserRelationServiceImpl extends ServiceImpl<SysUserRelationMappe
public Long createRelation(SysUserRelationCreateDto dto) {
SysUserRelationTypeEntity relationType = validateRelation(
dto.getSubjectUserId(), dto.getObjectUserId(), dto.getRelationTypeId());
validateRelationNotExists(dto.getSubjectUserId(), dto.getObjectUserId(), relationType);
validateRelationNotExists(dto.getSubjectUserId(), dto.getObjectUserId(), relationType, null);
SysUserRelationEntity relation = new SysUserRelationEntity();
BeanUtils.copyProperties(dto, relation);
@@ -119,6 +131,29 @@ public class SysUserRelationServiceImpl extends ServiceImpl<SysUserRelationMappe
return relation.getRelationId();
}
/**
* 修改已有用户关系,并排除当前关系后校验是否存在重复绑定。
*
* @param dto 关系修改信息
* @return 关系ID
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Long updateRelation(SysUserRelationUpdateDto dto) {
SysUserRelationEntity relation = getById(dto.getRelationId());
if (relation == null) {
throw new RuntimeException("用户关系不存在");
}
SysUserRelationTypeEntity relationType = validateRelation(
dto.getSubjectUserId(), dto.getObjectUserId(), dto.getRelationTypeId());
validateRelationNotExists(
dto.getSubjectUserId(), dto.getObjectUserId(), relationType, dto.getRelationId());
BeanUtils.copyProperties(dto, relation);
updateById(relation);
return relation.getRelationId();
}
private void validateCreateUserAndRelation(SysUserRelationCreateUserDto dto) {
Long existingUserId = dto.getSubjectUserId() == null ? dto.getObjectUserId() : dto.getSubjectUserId();
validateExistingUserAndRelationType(existingUserId, dto.getRelationTypeId());
@@ -163,9 +198,10 @@ public class SysUserRelationServiceImpl extends ServiceImpl<SysUserRelationMappe
}
private void validateRelationNotExists(Long subjectUserId, Long objectUserId,
SysUserRelationTypeEntity relationType) {
SysUserRelationTypeEntity relationType, Long excludeRelationId) {
boolean directed = "1".equals(relationType.getDirectedFlag());
boolean exists = exists(Wrappers.<SysUserRelationEntity>lambdaQuery()
.ne(excludeRelationId != null, SysUserRelationEntity::getRelationId, excludeRelationId)
.eq(SysUserRelationEntity::getRelationTypeId, relationType.getRelationTypeId())
.and(wrapper -> wrapper
.nested(current -> current.eq(SysUserRelationEntity::getSubjectUserId, subjectUserId)
@@ -178,60 +214,162 @@ public class SysUserRelationServiceImpl extends ServiceImpl<SysUserRelationMappe
}
}
private RelationGraphData collectRelationGraph(Long rootUserId) {
/**
* 从入口用户开始按无向邻接方式遍历,收集同一连通图中的全部用户和关系。
*
* @param entryUserId 图谱入口用户ID
* @return 完整连通关系数据
*/
private RelationGraphData collectRelationGraph(Long entryUserId) {
RelationGraphData graphData = new RelationGraphData();
graphData.userIds.add(rootUserId);
graphData.nodes.add(RelationGraphNode.root(rootUserId));
graphData.userIds.add(entryUserId);
Set<Long> expandedUserIds = new HashSet<>();
List<RelationNodeContext> currentLevel = List.of(new RelationNodeContext(TREE_ROOT_NODE_ID, rootUserId));
Set<Long> currentLevel = Set.of(entryUserId);
while (!currentLevel.isEmpty()) {
List<RelationNodeContext> expandableNodes = new ArrayList<>();
Set<Long> expandableUserIds = new LinkedHashSet<>();
for (RelationNodeContext context : currentLevel) {
if (expandedUserIds.add(context.userId)) {
expandableNodes.add(context);
expandableUserIds.add(context.userId);
for (Long currentUserId : currentLevel) {
if (expandedUserIds.add(currentUserId)) {
expandableUserIds.add(currentUserId);
}
}
if (expandableNodes.isEmpty()) {
if (expandableUserIds.isEmpty()) {
break;
}
Map<Long, List<SysUserRelationEntity>> relationMap = listRelations(expandableUserIds).stream()
.flatMap(relation -> Stream.of(relation.getSubjectUserId(), relation.getObjectUserId())
.filter(Objects::nonNull)
.map(relationUserId -> Map.entry(relationUserId, relation)))
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
List<RelationNodeContext> nextLevel = new ArrayList<>();
for (RelationNodeContext context : expandableNodes) {
for (SysUserRelationEntity relation : relationMap.getOrDefault(context.userId, List.of())) {
boolean parentIsSubject = Objects.equals(context.userId, relation.getSubjectUserId());
Long childUserId = parentIsSubject ? relation.getObjectUserId() : relation.getSubjectUserId();
if (childUserId == null || Objects.equals(childUserId, context.userId)) {
continue;
}
if (!graphData.relationIds.add(relation.getRelationId())) {
continue;
}
boolean repeated = !graphData.userIds.add(childUserId);
if (relation.getRelationTypeId() != null) {
graphData.relationTypeIds.add(relation.getRelationTypeId());
}
graphData.nodes.add(RelationGraphNode.child(
relation.getRelationId(), context.nodeId, context.userId, childUserId,
relation, parentIsSubject, repeated));
nextLevel.add(new RelationNodeContext(relation.getRelationId(), childUserId));
Set<Long> nextLevel = new LinkedHashSet<>();
for (SysUserRelationEntity relation : listRelations(expandableUserIds)) {
if (!graphData.relationIds.add(relation.getRelationId())) {
continue;
}
graphData.relations.add(relation);
if (relation.getRelationTypeId() != null) {
graphData.relationTypeIds.add(relation.getRelationTypeId());
}
Stream.of(relation.getSubjectUserId(), relation.getObjectUserId())
.filter(Objects::nonNull)
.filter(graphData.userIds::add)
.forEach(nextLevel::add);
}
currentLevel = nextLevel;
}
return graphData;
}
/**
* 根据有向关系的主语到对象方向选择业务根节点,优先选择可覆盖用户最多的顶层用户。
*
* @param entryUserId 入口用户ID
* @param graphData 完整连通关系数据
* @param relationTypeMap 关系类型映射
* @return 业务根用户ID
*/
private Long selectRootUserId(Long entryUserId, RelationGraphData graphData,
Map<Long, SysUserRelationTypeEntity> relationTypeMap) {
Map<Long, Set<Long>> directedChildren = new HashMap<>();
Set<Long> directedChildUserIds = new HashSet<>();
for (SysUserRelationEntity relation : graphData.relations) {
SysUserRelationTypeEntity relationType = relationTypeMap.get(relation.getRelationTypeId());
if (relationType == null || !"1".equals(relationType.getDirectedFlag())) {
continue;
}
directedChildren.computeIfAbsent(relation.getSubjectUserId(), key -> new LinkedHashSet<>())
.add(relation.getObjectUserId());
directedChildUserIds.add(relation.getObjectUserId());
}
if (directedChildren.isEmpty()) {
return entryUserId;
}
return graphData.userIds.stream()
.filter(candidateUserId -> !directedChildUserIds.contains(candidateUserId))
.sorted(Comparator
.comparingInt((Long candidateUserId) -> countDirectedDescendants(
candidateUserId, directedChildren)).reversed()
.thenComparing(candidateUserId -> !Objects.equals(candidateUserId, entryUserId))
.thenComparing(Comparator.naturalOrder()))
.findFirst()
.orElse(entryUserId);
}
/**
* 统计指定用户沿有向关系可覆盖的用户数量,用于选择最合适的业务根节点。
*
* @param rootUserId 候选根用户ID
* @param directedChildren 有向关系的下级用户映射
* @return 可覆盖的用户数量,包含候选根用户自身
*/
private int countDirectedDescendants(Long rootUserId, Map<Long, Set<Long>> directedChildren) {
Set<Long> visitedUserIds = new HashSet<>();
Deque<Long> pendingUserIds = new ArrayDeque<>();
pendingUserIds.add(rootUserId);
while (!pendingUserIds.isEmpty()) {
Long currentUserId = pendingUserIds.removeFirst();
if (!visitedUserIds.add(currentUserId)) {
continue;
}
pendingUserIds.addAll(directedChildren.getOrDefault(currentUserId, Set.of()));
}
return visitedUserIds.size();
}
/**
* 从业务根节点开始生成树形结构,交叉关系或环中的重复用户只保留引用节点,不再继续展开。
*
* @param rootUserId 业务根用户ID
* @param graphData 完整连通关系数据
* @return 树形关系节点列表
*/
private List<RelationGraphNode> buildRelationTree(Long rootUserId, RelationGraphData graphData) {
Map<Long, List<SysUserRelationEntity>> relationMap = graphData.relations.stream()
.flatMap(relation -> Stream.of(relation.getSubjectUserId(), relation.getObjectUserId())
.filter(Objects::nonNull)
.map(relationUserId -> Map.entry(relationUserId, relation)))
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
relationMap.values().forEach(relations -> relations.sort(
Comparator.comparing(SysUserRelationEntity::getRelationId)));
List<RelationGraphNode> nodes = new ArrayList<>();
nodes.add(RelationGraphNode.root(rootUserId));
Set<Long> relationIds = new HashSet<>();
Set<Long> discoveredUserIds = new HashSet<>();
discoveredUserIds.add(rootUserId);
List<RelationNodeContext> currentLevel = List.of(
new RelationNodeContext(TREE_ROOT_NODE_ID, rootUserId));
while (!currentLevel.isEmpty()) {
List<RelationNodeContext> nextLevel = new ArrayList<>();
for (RelationNodeContext context : currentLevel) {
for (SysUserRelationEntity relation : relationMap.getOrDefault(context.userId, List.of())) {
if (!relationIds.add(relation.getRelationId())) {
continue;
}
boolean parentIsSubject = Objects.equals(context.userId, relation.getSubjectUserId());
Long childUserId = parentIsSubject ? relation.getObjectUserId() : relation.getSubjectUserId();
if (childUserId == null || Objects.equals(childUserId, context.userId)) {
continue;
}
boolean repeated = !discoveredUserIds.add(childUserId);
nodes.add(RelationGraphNode.child(
relation.getRelationId(), context.nodeId, context.userId, childUserId,
relation, parentIsSubject, repeated));
if (!repeated) {
nextLevel.add(new RelationNodeContext(relation.getRelationId(), childUserId));
}
}
}
currentLevel = nextLevel;
}
return nodes;
}
/**
* 查询与指定用户集合任意一端关联的全部有效关系。
*
* @param userIds 用户ID集合
* @return 用户关系列表
*/
private List<SysUserRelationEntity> listRelations(Set<Long> userIds) {
return list(Wrappers.<SysUserRelationEntity>lambdaQuery()
.and(wrapper -> wrapper.in(SysUserRelationEntity::getSubjectUserId, userIds)
@@ -323,7 +461,7 @@ public class SysUserRelationServiceImpl extends ServiceImpl<SysUserRelationMappe
private static class RelationGraphData {
private final List<RelationGraphNode> nodes = new ArrayList<>();
private final List<SysUserRelationEntity> relations = new ArrayList<>();
private final Set<Long> userIds = new LinkedHashSet<>();
@@ -0,0 +1,95 @@
package com.bsd.pjcloud.admin.service.impl.user;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.bsd.pjcloud.admin.api.entity.SysUser;
import com.bsd.pjcloud.admin.api.entity.user.SysUserRelationEntity;
import com.bsd.pjcloud.admin.api.entity.user.SysUserRelationTypeEntity;
import com.bsd.pjcloud.admin.api.vo.user.SysUserRelationGraphVo;
import com.bsd.pjcloud.admin.service.SysUserRelationTypeService;
import com.bsd.pjcloud.admin.service.SysUserService;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
class SysUserRelationServiceImplTest {
private static final Long GUARDIAN_USER_ID = 2034824566572941314L;
private static final Long FIRST_WARD_USER_ID = 2079103470488576001L;
private static final Long SECOND_WARD_USER_ID = 2079129427022737410L;
private static final Long RELATION_TYPE_ID = 2079044735024029698L;
/**
* 验证从被监护人进入图谱时,仍以监护人为根节点并展示两个同级被监护人。
*/
@Test
void shouldUseGuardianAsRootWhenGraphIsOpenedFromWard() {
SysUserRelationEntity firstRelation = createRelation(
2079104982669385730L, FIRST_WARD_USER_ID);
SysUserRelationEntity secondRelation = createRelation(
2079129636280758273L, SECOND_WARD_USER_ID);
SysUserService sysUserService = mock(SysUserService.class);
SysUserRelationTypeService relationTypeService = mock(SysUserRelationTypeService.class);
SysUserRelationServiceImpl service = spy(
new SysUserRelationServiceImpl(sysUserService, relationTypeService));
when(sysUserService.getById(SECOND_WARD_USER_ID)).thenReturn(createUser(SECOND_WARD_USER_ID, "被监护人二"));
when(sysUserService.listByIds(any())).thenReturn(List.of(
createUser(GUARDIAN_USER_ID, "监护人"),
createUser(FIRST_WARD_USER_ID, "被监护人一"),
createUser(SECOND_WARD_USER_ID, "被监护人二")));
when(relationTypeService.listByIds(any())).thenReturn(List.of(createGuardianRelationType()));
doReturn(List.of(secondRelation), List.of(firstRelation, secondRelation), List.of(firstRelation))
.when(service).list(org.mockito.ArgumentMatchers.<Wrapper<SysUserRelationEntity>>any());
SysUserRelationGraphVo graph = service.getRelationGraph(SECOND_WARD_USER_ID);
assertEquals(GUARDIAN_USER_ID, graph.getUserId());
assertEquals(3, graph.getUserCount());
assertEquals(2, graph.getRelationCount());
assertEquals(Set.of(FIRST_WARD_USER_ID, SECOND_WARD_USER_ID), graph.getChildren().stream()
.map(SysUserRelationGraphVo::getUserId)
.collect(Collectors.toSet()));
assertFalse(graph.getChildren().stream().anyMatch(child -> !child.getChildren().isEmpty()));
}
private SysUserRelationEntity createRelation(Long relationId, Long wardUserId) {
SysUserRelationEntity relation = new SysUserRelationEntity();
relation.setRelationId(relationId);
relation.setSubjectUserId(GUARDIAN_USER_ID);
relation.setObjectUserId(wardUserId);
relation.setRelationTypeId(RELATION_TYPE_ID);
return relation;
}
private SysUser createUser(Long userId, String name) {
SysUser user = new SysUser();
user.setUserId(userId);
user.setName(name);
return user;
}
private SysUserRelationTypeEntity createGuardianRelationType() {
SysUserRelationTypeEntity relationType = new SysUserRelationTypeEntity();
relationType.setRelationTypeId(RELATION_TYPE_ID);
relationType.setRelationCode("GUARDIAN_WARD");
relationType.setRelationName("监护关系");
relationType.setSubjectRoleName("监护人");
relationType.setObjectRoleName("被监护对象");
relationType.setDirectedFlag("1");
return relationType;
}
}