feat:后台用户关系绑定
This commit is contained in:
1 parent
abb9e124f6
commit
c2ab16c1fc
33 files changed
+1794
-3
No files matched your search
+31
@@ -0,0 +1,31 @@
|
||||
package com.bsd.pjcloud.admin.api.constant.user;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 用户身份
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum UserIdentityTypeEnum {
|
||||
|
||||
DEFAULT("DEFAULT", "默认"),
|
||||
STUDENT("STUDENT", "学生"),
|
||||
;
|
||||
|
||||
private final String type;
|
||||
|
||||
private final String description;
|
||||
|
||||
public static UserIdentityTypeEnum valueOfByType(String type) {
|
||||
if (ObjectUtil.isEmpty(type)) return null;
|
||||
return Arrays.stream(values())
|
||||
.filter(value -> ObjectUtil.equals(type, value.getType()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.bsd.pjcloud.admin.api.constant.user;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 用户关系类型分类
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum UserRelationCategoryEnum {
|
||||
|
||||
FAMILY("family", "家庭关系"),
|
||||
BUSINESS("business", "业务关系"),
|
||||
SOCIAL("social", "社交关系");
|
||||
|
||||
/**
|
||||
* 分类编码
|
||||
*/
|
||||
private final String category;
|
||||
|
||||
/**
|
||||
* 分类名称
|
||||
*/
|
||||
private final String description;
|
||||
|
||||
public static UserRelationCategoryEnum valueOfByCategory(String category) {
|
||||
if (ObjectUtil.isEmpty(category)) return null;
|
||||
return Arrays.stream(values())
|
||||
.filter(value -> ObjectUtil.equals(category, value.getCategory()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.bsd.pjcloud.admin.api.constant.user;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 用户关系类型
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum UserRelationTypeEnum {
|
||||
|
||||
// 家庭关系
|
||||
CHILD_PARENT("CHILD_PARENT", "亲子关系"),
|
||||
SPOUSE("SPOUSE", "夫妻关系"),
|
||||
SIBLING("SIBLING", "兄弟姐妹关系"),
|
||||
GRANDCHILD_GRANDPARENT("GRANDCHILD_GRANDPARENT", "祖孙关系"),
|
||||
GUARDIAN_WARD("GUARDIAN_WARD", "监护关系"),
|
||||
RELATIVE("RELATIVE", "亲属关系"),
|
||||
|
||||
// 社交关系
|
||||
FRIEND("FRIEND", "朋友关系"),
|
||||
CLASSMATE("CLASSMATE", "同学关系"),
|
||||
COLLEAGUE("COLLEAGUE", "同事关系"),
|
||||
NEIGHBOR("NEIGHBOR", "邻里关系"),
|
||||
|
||||
// 教育关系
|
||||
STUDENT_TEACHER("STUDENT_TEACHER", "师生关系"),
|
||||
|
||||
// 工作关系
|
||||
SUBORDINATE_LEADER("SUBORDINATE_LEADER", "上下级关系"),
|
||||
EMPLOYEE_EMPLOYER("EMPLOYEE_EMPLOYER", "雇佣关系"),
|
||||
|
||||
// 客户关系
|
||||
CUSTOMER_MANAGER("CUSTOMER_MANAGER", "客户关系"),
|
||||
CUSTOMER_SERVICE("CUSTOMER_SERVICE", "客服关系"),
|
||||
|
||||
// 其他业务关系
|
||||
REFEREE_REFERRER("REFEREE_REFERRER", "推荐关系"),
|
||||
CONTACT("CONTACT", "联系人关系"),
|
||||
OTHER("OTHER", "其他关系");
|
||||
|
||||
/**
|
||||
* 关系编码
|
||||
*/
|
||||
private final String relationCode;
|
||||
|
||||
/**
|
||||
* 关系名称
|
||||
*/
|
||||
private final String relationName;
|
||||
|
||||
|
||||
public static UserRelationTypeEnum valueOfByType(String relationCode) {
|
||||
if (ObjectUtil.isEmpty(relationCode)) return null;
|
||||
return Arrays.stream(values()).filter(v -> ObjectUtil.equals(relationCode, v.getRelationCode())).findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
+13
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.bsd.pjcloud.admin.api.dto;
|
||||
|
||||
import com.bsd.pjcloud.admin.api.dto.user.SysUserStudentDto;
|
||||
import com.bsd.pjcloud.admin.api.entity.SysUser;
|
||||
import com.bsd.pjcloud.admin.api.vo.base.BaseIsIncludeTreeInterface;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
@@ -54,6 +55,18 @@ public class UserDTO extends SysUser implements BaseIsIncludeTreeInterface {
|
||||
*/
|
||||
private List<Long> post;
|
||||
|
||||
/**
|
||||
* 用户身份类型
|
||||
*/
|
||||
@Schema(description = "用户身份类型集合")
|
||||
private List<String> identityTypes;
|
||||
|
||||
/**
|
||||
* 学生身份扩展信息
|
||||
*/
|
||||
@Schema(description = "学生身份扩展信息")
|
||||
private SysUserStudentDto studentInfo;
|
||||
|
||||
/**
|
||||
* 新密码
|
||||
*/
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
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 SysUserRelationCreateDto {
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
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.Email;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 创建用户并建立用户关系
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "创建用户并建立用户关系")
|
||||
public class SysUserRelationCreateUserDto {
|
||||
|
||||
@Schema(description = "关系主语用户ID;为空时由新建用户作为关系主语")
|
||||
private Long subjectUserId;
|
||||
|
||||
@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;
|
||||
|
||||
@NotBlank(message = "用户名不能为空")
|
||||
@Size(min = 5, max = 60, message = "用户名长度必须介于5到60个字符之间")
|
||||
@Pattern(regexp = "^[^\\u4e00-\\u9fa5]+$", message = "用户名不能包含中文")
|
||||
@Schema(description = "用户名")
|
||||
private String username;
|
||||
|
||||
@NotBlank(message = "密码不能为空")
|
||||
@Size(min = 6, max = 20, message = "密码长度必须介于6到20个字符之间")
|
||||
@Schema(description = "密码")
|
||||
private String password;
|
||||
|
||||
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
|
||||
@Schema(description = "手机号")
|
||||
private String phone;
|
||||
|
||||
@NotBlank(message = "姓名不能为空")
|
||||
@Size(max = 64, message = "姓名不能超过64个字符")
|
||||
@Schema(description = "姓名")
|
||||
private String name;
|
||||
|
||||
@Size(max = 64, message = "昵称不能超过64个字符")
|
||||
@Schema(description = "昵称")
|
||||
private String nickname;
|
||||
|
||||
@Email(message = "邮箱格式不正确")
|
||||
@Size(max = 128, message = "邮箱不能超过128个字符")
|
||||
@Schema(description = "邮箱")
|
||||
private String email;
|
||||
|
||||
@Size(max = 255, message = "头像地址不能超过255个字符")
|
||||
@Schema(description = "头像")
|
||||
private String avatar;
|
||||
|
||||
@Schema(description = "所属部门ID")
|
||||
private Long deptId;
|
||||
|
||||
@Schema(description = "角色ID集合,为空时使用默认角色")
|
||||
private List<Long> role;
|
||||
|
||||
@Schema(description = "岗位ID集合")
|
||||
private List<Long> post;
|
||||
|
||||
@Min(value = 0, message = "性别值不正确")
|
||||
@Max(value = 2, message = "性别值不正确")
|
||||
@Schema(description = "性别:0未知,1男,2女")
|
||||
private Integer gender;
|
||||
|
||||
@Size(max = 32, message = "编制类型不能超过32个字符")
|
||||
@Schema(description = "编制类型")
|
||||
private String staffingType;
|
||||
|
||||
@Schema(description = "用户状态:0正常,9锁定")
|
||||
private String lockFlag;
|
||||
|
||||
@Schema(description = "用户身份类型集合")
|
||||
private List<String> identityTypes;
|
||||
|
||||
@Schema(description = "学生身份扩展信息")
|
||||
private SysUserStudentDto studentInfo;
|
||||
|
||||
@AssertTrue(message = "关系主语用户和关系对象用户必须且只能填写一个")
|
||||
@Schema(hidden = true)
|
||||
public boolean isRelationEndpointValid() {
|
||||
return (subjectUserId == null) != (objectUserId == null);
|
||||
}
|
||||
|
||||
@AssertTrue(message = "关系失效时间不能早于生效时间")
|
||||
@Schema(hidden = true)
|
||||
public boolean isRelationTimeValid() {
|
||||
return effectiveTime == null || expireTime == null || !expireTime.isBefore(effectiveTime);
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.bsd.pjcloud.admin.api.dto.user;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 学生身份扩展信息
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "学生身份扩展信息")
|
||||
public class SysUserStudentDto {
|
||||
|
||||
@Schema(description = "学号")
|
||||
private String studentNo;
|
||||
|
||||
@Schema(description = "学校名称")
|
||||
private String schoolName;
|
||||
|
||||
@Schema(description = "班级名称")
|
||||
private String className;
|
||||
|
||||
@Schema(description = "其他非核心扩展信息")
|
||||
private String extJson;
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.bsd.pjcloud.admin.api.entity.user;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 用户身份表
|
||||
*/
|
||||
@Data
|
||||
@TableName("sys_user_identity")
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(description = "用户身份表")
|
||||
public class SysUserIdentityEntity extends Model<SysUserIdentityEntity> {
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description = "用户ID")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 身份类型:STUDENT学生、TEACHER教师等
|
||||
*/
|
||||
@Schema(description = "身份类型:STUDENT学生、TEACHER教师等")
|
||||
private String identityType;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package com.bsd.pjcloud.admin.api.entity.user;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import com.bsd.pjcloud.common.core.util.TenantTable;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 用户多对多关系表
|
||||
*/
|
||||
@Data
|
||||
@TenantTable
|
||||
@TableName("sys_user_relation")
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(description = "用户多对多关系表")
|
||||
public class SysUserRelationEntity extends Model<SysUserRelationEntity> {
|
||||
|
||||
/**
|
||||
* 关系ID
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description = "关系ID")
|
||||
private Long relationId;
|
||||
|
||||
/**
|
||||
* 主语用户ID
|
||||
*/
|
||||
@Schema(description = "主语用户ID")
|
||||
private Long subjectUserId;
|
||||
|
||||
/**
|
||||
* 对象用户ID
|
||||
*/
|
||||
@Schema(description = "对象用户ID")
|
||||
private Long objectUserId;
|
||||
|
||||
/**
|
||||
* 关系类型ID
|
||||
*/
|
||||
@Schema(description = "关系类型ID")
|
||||
private Long relationTypeId;
|
||||
|
||||
/**
|
||||
* 关系生效时间
|
||||
*/
|
||||
@Schema(description = "关系生效时间")
|
||||
private LocalDateTime effectiveTime;
|
||||
|
||||
/**
|
||||
* 关系失效时间
|
||||
*/
|
||||
@Schema(description = "关系失效时间")
|
||||
private LocalDateTime expireTime;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@Schema(description = "创建人")
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 修改人
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
@Schema(description = "修改人")
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
@Schema(description = "修改时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 删除标记,0未删除,1已删除
|
||||
*/
|
||||
@TableLogic
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@Schema(description = "删除标记,0未删除,1已删除")
|
||||
private String delFlag;
|
||||
|
||||
/**
|
||||
* 所属租户ID
|
||||
*/
|
||||
@Schema(description = "所属租户ID")
|
||||
private Long tenantId;
|
||||
}
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
package com.bsd.pjcloud.admin.api.entity.user;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import com.bsd.pjcloud.common.core.util.TenantTable;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 用户关系类型表
|
||||
*/
|
||||
@Data
|
||||
@TenantTable
|
||||
@TableName("sys_user_relation_type")
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(description = "用户关系类型表")
|
||||
public class SysUserRelationTypeEntity extends Model<SysUserRelationTypeEntity> {
|
||||
|
||||
/**
|
||||
* 关系类型
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description = "关系类型")
|
||||
private Long relationTypeId;
|
||||
|
||||
/**
|
||||
* 关系编码
|
||||
*/
|
||||
@Schema(description = "关系编码")
|
||||
private String relationCode;
|
||||
|
||||
/**
|
||||
* 关系名称
|
||||
*/
|
||||
@Schema(description = "关系名称")
|
||||
private String relationName;
|
||||
|
||||
/**
|
||||
* 主语一方称呼
|
||||
*/
|
||||
@Schema(description = "主语一方称呼")
|
||||
private String subjectRoleName;
|
||||
|
||||
/**
|
||||
* 对象一方称呼
|
||||
*/
|
||||
@Schema(description = "对象一方称呼")
|
||||
private String objectRoleName;
|
||||
|
||||
/**
|
||||
* 分类:family、business、social
|
||||
*/
|
||||
@Schema(description = "分类:family、business、social")
|
||||
private String category;
|
||||
|
||||
/**
|
||||
* 是否有方向:0否,1是
|
||||
*/
|
||||
@Schema(description = "是否有方向:0否,1是")
|
||||
private String directedFlag;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@Schema(description = "排序")
|
||||
private Integer sortOrder;
|
||||
|
||||
/**
|
||||
* 状态:0正常,1停用
|
||||
*/
|
||||
@Schema(description = "状态:0正常,1停用")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@Schema(description = "创建人")
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 修改人
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
@Schema(description = "修改人")
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
@Schema(description = "修改时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 删除标记
|
||||
*/
|
||||
@TableLogic
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@Schema(description = "删除标记")
|
||||
private String delFlag;
|
||||
|
||||
/**
|
||||
* 所属租户ID
|
||||
*/
|
||||
@Schema(description = "所属租户ID")
|
||||
private Long tenantId;
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
package com.bsd.pjcloud.admin.api.entity.user;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.extension.activerecord.Model;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import com.bsd.pjcloud.common.core.util.TenantTable;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 学生用户扩展信息表
|
||||
*/
|
||||
@Data
|
||||
@TenantTable
|
||||
@TableName("sys_user_student")
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(description = "学生用户扩展信息表")
|
||||
public class SysUserStudentEntity extends Model<SysUserStudentEntity> {
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@Schema(description = "用户ID")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 学号
|
||||
*/
|
||||
@Schema(description = "学号")
|
||||
private String studentNo;
|
||||
|
||||
/**
|
||||
* 学校名称
|
||||
*/
|
||||
@Schema(description = "学校名称")
|
||||
private String schoolName;
|
||||
|
||||
/**
|
||||
* 班级名称
|
||||
*/
|
||||
@Schema(description = "班级名称")
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* 其他非核心扩展信息
|
||||
*/
|
||||
@Schema(description = "其他非核心扩展信息")
|
||||
private String extJson;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 修改时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
@Schema(description = "修改时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 所属租户ID
|
||||
*/
|
||||
@Schema(description = "所属租户ID")
|
||||
private Long tenantId;
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.bsd.pjcloud.admin.api.vo;
|
||||
|
||||
import com.bsd.pjcloud.admin.api.dto.user.SysUserStudentDto;
|
||||
import com.bsd.pjcloud.admin.api.vo.base.BaseFacesInterface;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.bsd.pjcloud.admin.api.entity.SysPost;
|
||||
@@ -211,6 +212,18 @@ public class UserVO implements BaseFacesInterface, Serializable {
|
||||
*/
|
||||
private List<SysPost> postList;
|
||||
|
||||
/**
|
||||
* 用户身份类型
|
||||
*/
|
||||
@Schema(description = "用户身份类型集合")
|
||||
private List<String> identityTypes;
|
||||
|
||||
/**
|
||||
* 学生身份扩展信息
|
||||
*/
|
||||
@Schema(description = "学生身份扩展信息")
|
||||
private SysUserStudentDto studentInfo;
|
||||
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package com.bsd.pjcloud.admin.api.vo.user;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户关系图谱
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "用户关系图谱")
|
||||
public class SysUserRelationGraphVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "图谱节点ID,根节点为0,其他节点使用关系ID")
|
||||
private Long nodeId;
|
||||
|
||||
@Schema(description = "父节点ID")
|
||||
private Long parentNodeId;
|
||||
|
||||
@Schema(description = "是否根节点")
|
||||
private Boolean root;
|
||||
|
||||
@Schema(description = "是否为已出现用户的重复引用节点,重复节点不再继续展开")
|
||||
private Boolean repeated;
|
||||
|
||||
@Schema(description = "用户ID")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "用户名")
|
||||
private String username;
|
||||
|
||||
@Schema(description = "姓名")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "昵称")
|
||||
private String nickname;
|
||||
|
||||
@Schema(description = "图谱展示名称")
|
||||
private String displayName;
|
||||
|
||||
@Schema(description = "头像")
|
||||
private String avatar;
|
||||
|
||||
@Schema(description = "性别:0未知,1男,2女")
|
||||
private Integer gender;
|
||||
|
||||
@Schema(description = "图谱中的用户数量,仅根节点返回,重复用户不重复计数")
|
||||
private Integer userCount;
|
||||
|
||||
@Schema(description = "图谱中的关系数量,仅根节点返回")
|
||||
private Integer relationCount;
|
||||
|
||||
@Schema(description = "关系ID,根节点为空")
|
||||
private Long relationId;
|
||||
|
||||
@Schema(description = "关系主语用户ID")
|
||||
private Long subjectUserId;
|
||||
|
||||
@Schema(description = "关系对象用户ID")
|
||||
private Long objectUserId;
|
||||
|
||||
@Schema(description = "关系类型ID")
|
||||
private Long relationTypeId;
|
||||
|
||||
@Schema(description = "关系编码")
|
||||
private String relationCode;
|
||||
|
||||
@Schema(description = "关系名称")
|
||||
private String relationName;
|
||||
|
||||
@Schema(description = "关系分类")
|
||||
private String category;
|
||||
|
||||
@Schema(description = "是否有方向:0否,1是")
|
||||
private String directedFlag;
|
||||
|
||||
@Schema(description = "当前树边方向:subject-to-object或object-to-subject")
|
||||
private String relationDirection;
|
||||
|
||||
@Schema(description = "当前用户相对于父节点用户的角色,例如老师、监护人、学生")
|
||||
private String userRoleName;
|
||||
|
||||
@Schema(description = "父节点用户相对于当前用户的角色")
|
||||
private String parentRoleName;
|
||||
|
||||
@Schema(description = "完整关系描述,例如张老师是李同学的老师")
|
||||
private String relationDescription;
|
||||
|
||||
@Schema(description = "关系生效时间")
|
||||
private LocalDateTime effectiveTime;
|
||||
|
||||
@Schema(description = "关系失效时间")
|
||||
private LocalDateTime expireTime;
|
||||
|
||||
@Schema(description = "关系备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "下级关系节点")
|
||||
private List<SysUserRelationGraphVo> children = new ArrayList<>();
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
package com.bsd.pjcloud.admin.controller.user;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
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.entity.user.SysUserRelationEntity;
|
||||
import com.bsd.pjcloud.admin.api.vo.user.SysUserRelationGraphVo;
|
||||
import com.bsd.pjcloud.admin.service.SysUserRelationService;
|
||||
import com.bsd.pjcloud.common.core.util.R;
|
||||
import com.bsd.pjcloud.common.log.annotation.SysLog;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
import org.springdoc.core.annotations.ParameterObject;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 用户多对多关系表
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/sysUserRelation")
|
||||
@Tag(description = "sysUserRelation", name = "用户多对多关系表管理")
|
||||
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
|
||||
public class SysUserRelationController {
|
||||
|
||||
private final SysUserRelationService sysUserRelationService;
|
||||
|
||||
/**
|
||||
* 查询用户关系图谱
|
||||
*/
|
||||
@Operation(summary = "关系图谱", description = "以指定用户为根节点查询用户关系树")
|
||||
@GetMapping("/graph/{userId}")
|
||||
// @PreAuthorize("@pms.hasPermission('dzc_sysUserRelation_view')")
|
||||
public R<SysUserRelationGraphVo> getRelationGraph(@PathVariable Long userId) {
|
||||
return R.ok(sysUserRelationService.getRelationGraph(userId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建用户并建立关系,新用户可作为关系主语或关系对象
|
||||
*/
|
||||
@Operation(summary = "创建用户并建立关系", description = "创建用户且直接审核通过,再建立用户关系")
|
||||
@SysLog("创建用户并建立关系")
|
||||
@PostMapping("/create-user")
|
||||
// @PreAuthorize("@pms.hasPermission('dzc_sysUserRelation_add')")
|
||||
public R<Long> createUserAndRelation(@Valid @RequestBody SysUserRelationCreateUserDto dto) {
|
||||
return R.ok(sysUserRelationService.createUserAndRelation(dto));
|
||||
}
|
||||
|
||||
/**
|
||||
* 为两个已有用户建立关系
|
||||
*/
|
||||
@Operation(summary = "建立用户关系", description = "为两个已经存在的用户建立关系")
|
||||
@SysLog("建立用户关系")
|
||||
@PostMapping("/create")
|
||||
// @PreAuthorize("@pms.hasPermission('dzc_sysUserRelation_add')")
|
||||
public R<Long> createRelation(@Valid @RequestBody SysUserRelationCreateDto dto) {
|
||||
return R.ok(sysUserRelationService.createRelation(dto));
|
||||
}
|
||||
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
package com.bsd.pjcloud.admin.controller.user;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.bsd.pjcloud.admin.api.entity.user.SysUserRelationTypeEntity;
|
||||
import com.bsd.pjcloud.admin.service.SysUserRelationTypeService;
|
||||
import com.bsd.pjcloud.common.core.util.R;
|
||||
import com.bsd.pjcloud.common.log.annotation.SysLog;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
import org.springdoc.core.annotations.ParameterObject;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
||||
/**
|
||||
* 用户关系类型表
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/sysUserRelationType")
|
||||
@Tag(description = "sysUserRelationType", name = "用户关系类型表管理")
|
||||
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
|
||||
public class SysUserRelationTypeController {
|
||||
|
||||
private final SysUserRelationTypeService sysUserRelationTypeService;
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*/
|
||||
@Operation(summary = "分页查询", description = "分页查询")
|
||||
@GetMapping("/page")
|
||||
@PreAuthorize("@pms.hasPermission('dzc_sysUserRelationType_view')")
|
||||
public R getSysUserRelationTypePage(@ParameterObject Page page, @ParameterObject SysUserRelationTypeEntity sysUserRelationType) {
|
||||
LambdaQueryWrapper<SysUserRelationTypeEntity> wrapper = Wrappers.lambdaQuery();
|
||||
return R.ok(sysUserRelationTypeService.page(page, wrapper));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询用户关系类型表
|
||||
*/
|
||||
@Operation(summary = "通过id查询", description = "通过id查询")
|
||||
@GetMapping("/{relationTypeId}")
|
||||
@PreAuthorize("@pms.hasPermission('dzc_sysUserRelationType_view')")
|
||||
public R getById(@PathVariable("relationTypeId") Long relationTypeId) {
|
||||
return R.ok(sysUserRelationTypeService.getById(relationTypeId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增用户关系类型表
|
||||
*/
|
||||
@Operation(summary = "新增用户关系类型表", description = "新增用户关系类型表")
|
||||
@SysLog("新增用户关系类型表")
|
||||
@PostMapping
|
||||
@PreAuthorize("@pms.hasPermission('dzc_sysUserRelationType_add')")
|
||||
public R save(@RequestBody SysUserRelationTypeEntity dto) {
|
||||
return R.ok(sysUserRelationTypeService.create(dto));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户关系类型表
|
||||
*/
|
||||
@Operation(summary = "修改用户关系类型表", description = "修改用户关系类型表")
|
||||
@SysLog("修改用户关系类型表")
|
||||
@PutMapping
|
||||
@PreAuthorize("@pms.hasPermission('dzc_sysUserRelationType_edit')")
|
||||
public R updateById(@RequestBody SysUserRelationTypeEntity dto) {
|
||||
return R.ok(sysUserRelationTypeService.edit(dto));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除用户关系类型表
|
||||
*/
|
||||
@Operation(summary = "通过id删除用户关系类型表", description = "通过id删除用户关系类型表")
|
||||
@SysLog("通过id删除用户关系类型表")
|
||||
@DeleteMapping
|
||||
@PreAuthorize("@pms.hasPermission('dzc_sysUserRelationType_del')")
|
||||
public R removeById(@RequestBody Long[] ids) {
|
||||
sysUserRelationTypeService.delById(CollUtil.toList(ids));
|
||||
return R.ok();
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.bsd.pjcloud.admin.mapper.user;
|
||||
|
||||
import com.bsd.pjcloud.admin.api.entity.user.SysUserIdentityEntity;
|
||||
import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface SysUserIdentityMapper extends PjcloudBaseMapper<SysUserIdentityEntity> {
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.bsd.pjcloud.admin.mapper.user;
|
||||
|
||||
import com.bsd.pjcloud.admin.api.entity.user.SysUserRelationEntity;
|
||||
import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface SysUserRelationMapper extends PjcloudBaseMapper<SysUserRelationEntity> {
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.bsd.pjcloud.admin.mapper.user;
|
||||
|
||||
import com.bsd.pjcloud.admin.api.entity.user.SysUserRelationTypeEntity;
|
||||
import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface SysUserRelationTypeMapper extends PjcloudBaseMapper<SysUserRelationTypeEntity> {
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.bsd.pjcloud.admin.mapper.user;
|
||||
|
||||
import com.bsd.pjcloud.admin.api.entity.user.SysUserStudentEntity;
|
||||
import com.bsd.pjcloud.common.data.datascope.PjcloudBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@Mapper
|
||||
public interface SysUserStudentMapper extends PjcloudBaseMapper<SysUserStudentEntity> {
|
||||
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.bsd.pjcloud.admin.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.bsd.pjcloud.admin.api.dto.UserDTO;
|
||||
import com.bsd.pjcloud.admin.api.entity.user.SysUserIdentityEntity;
|
||||
import com.bsd.pjcloud.admin.api.vo.UserVO;
|
||||
|
||||
public interface SysUserIdentityService extends IService<SysUserIdentityEntity> {
|
||||
|
||||
/**
|
||||
* 校验并规范化用户身份请求参数
|
||||
*/
|
||||
void validateDto(UserDTO userDto);
|
||||
|
||||
/**
|
||||
* 保存用户身份及对应扩展信息
|
||||
*/
|
||||
void saveUserIdentity(Long userId, UserDTO userDto);
|
||||
|
||||
/**
|
||||
* 填充用户身份及对应扩展信息
|
||||
*/
|
||||
void fillUserIdentity(UserVO userVo);
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
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.entity.user.SysUserRelationEntity;
|
||||
import com.bsd.pjcloud.admin.api.vo.user.SysUserRelationGraphVo;
|
||||
|
||||
public interface SysUserRelationService extends IService<SysUserRelationEntity> {
|
||||
|
||||
/**
|
||||
* 查询用户关系图谱
|
||||
*
|
||||
* @param userId 根用户ID
|
||||
* @return 用户关系图谱
|
||||
*/
|
||||
SysUserRelationGraphVo getRelationGraph(Long userId);
|
||||
|
||||
/**
|
||||
* 创建用户并建立关系,新用户作为关系主语
|
||||
*
|
||||
* @param dto 用户及关系信息
|
||||
* @return 新用户ID
|
||||
*/
|
||||
Long createUserAndRelation(SysUserRelationCreateUserDto dto);
|
||||
|
||||
/**
|
||||
* 为两个已有用户建立关系
|
||||
*
|
||||
* @param dto 关系信息
|
||||
* @return 关系ID
|
||||
*/
|
||||
Long createRelation(SysUserRelationCreateDto dto);
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.bsd.pjcloud.admin.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.bsd.pjcloud.admin.api.entity.user.SysUserRelationTypeEntity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public interface SysUserRelationTypeService extends IService<SysUserRelationTypeEntity> {
|
||||
|
||||
/**
|
||||
* 新增用户关系类型表
|
||||
*/
|
||||
Long create(SysUserRelationTypeEntity dto);
|
||||
|
||||
/**
|
||||
* 修改用户关系类型表
|
||||
*/
|
||||
Long edit(SysUserRelationTypeEntity dto);
|
||||
|
||||
/**
|
||||
* 通过id删除用户关系类型表
|
||||
*/
|
||||
void delById(ArrayList<Long> ids);
|
||||
}
|
||||
+8
@@ -111,6 +111,14 @@ public interface SysUserService extends IService<SysUser> {
|
||||
*/
|
||||
Long saveUser(UserDTO userDto);
|
||||
|
||||
/**
|
||||
* 保存用户信息并直接审核通过
|
||||
*
|
||||
* @param userDto DTO 对象
|
||||
* @return 用户ID
|
||||
*/
|
||||
Long saveUserWithoutAudit(UserDTO userDto);
|
||||
|
||||
/**
|
||||
* 查询全部的用户
|
||||
*
|
||||
|
||||
pjcloud-upms/pjcloud-upms-biz/src/main/java/com/bsd/pjcloud/admin/service/SysUserStudentService.java
Executable
+12
@@ -0,0 +1,12 @@
|
||||
package com.bsd.pjcloud.admin.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.bsd.pjcloud.admin.api.entity.user.SysUserStudentEntity;
|
||||
|
||||
public interface SysUserStudentService extends IService<SysUserStudentEntity> {
|
||||
|
||||
/**
|
||||
* 判断学号是否已被其他用户使用
|
||||
*/
|
||||
boolean existsStudentNo(Long userId, String studentNo);
|
||||
}
|
||||
+32
-3
@@ -37,6 +37,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.bsd.pjcloud.admin.api.constant.UserExpireEnum;
|
||||
import com.bsd.pjcloud.admin.api.constant.UserStaffingTypeEnum;
|
||||
import com.bsd.pjcloud.admin.api.constant.UserStateEnum;
|
||||
import com.bsd.pjcloud.admin.api.constant.user.UserIdentityTypeEnum;
|
||||
import com.bsd.pjcloud.admin.api.dto.ForgotPasswordDTO;
|
||||
import com.bsd.pjcloud.admin.api.dto.SysUserFaceDto;
|
||||
import com.bsd.pjcloud.admin.api.dto.UserDTO;
|
||||
@@ -123,6 +124,8 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
|
||||
private final SysUserTagService sysUserTagService;
|
||||
|
||||
private final SysUserIdentityService sysUserIdentityService;
|
||||
|
||||
@Lazy
|
||||
private final SysUserFaceService sysUserFaceService;
|
||||
private final SysUserFaceMapper sysUserFaceMapper;
|
||||
@@ -165,12 +168,26 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long saveUser(UserDTO userDto) {
|
||||
return saveUser(userDto, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long saveUserWithoutAudit(UserDTO userDto) {
|
||||
return saveUser(userDto, true);
|
||||
}
|
||||
|
||||
private Long saveUser(UserDTO userDto, boolean skipAudit) {
|
||||
sysUserIdentityService.validateDto(userDto);
|
||||
SysUser sysUser = new SysUser();
|
||||
BeanUtils.copyProperties(userDto, sysUser);
|
||||
// 判断是否为部门管理员
|
||||
PjcloudUser applyUser = SecurityUtils.getUser();
|
||||
boolean isDeptAdmin = false;
|
||||
if (null != applyUser) {
|
||||
if (skipAudit) {
|
||||
sysUser.setProcessStatus(TaskCheckStatusEnum.RESULT.getCode());
|
||||
sysUser.setProcessTime(LocalDateTime.now());
|
||||
} else if (null != applyUser) {
|
||||
isDeptAdmin = sysRoleService.isDeptAdmin(applyUser.getId());
|
||||
if (isDeptAdmin) {
|
||||
List<SysRole> defaultRoles = sysRoleService.findRolesByCodes(List.of(CommonRoleConstant.DEFAULT_USER, CommonRoleConstant.AUTO_CREATE_WALLET));
|
||||
@@ -194,6 +211,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
sysUser.setPasswordModifyTime(LocalDateTime.now());
|
||||
sysUser.setPasswordExpireFlag(UserExpireEnum.EXPIRE.getCode());
|
||||
baseMapper.insert(sysUser);
|
||||
sysUserIdentityService.saveUserIdentity(sysUser.getUserId(), userDto);
|
||||
// 保存用户岗位信息
|
||||
Optional.ofNullable(userDto.getPost()).ifPresent(posts -> {
|
||||
posts.stream().map(postId -> {
|
||||
@@ -221,7 +239,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
return userRole;
|
||||
}).forEach(sysUserRoleMapper::insert);
|
||||
|
||||
if (isDeptAdmin) {
|
||||
if (isDeptAdmin && !skipAudit) {
|
||||
getSelf().applyFlow(sysUser);
|
||||
} else {
|
||||
// 创建用户默认钱包、保证线程header
|
||||
@@ -345,7 +363,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
*/
|
||||
@Override
|
||||
public UserVO selectUserVoById(Long id) {
|
||||
return baseMapper.getUserVoById(id);
|
||||
UserVO userVo = baseMapper.getUserVoById(id);
|
||||
sysUserIdentityService.fillUserIdentity(userVo);
|
||||
return userVo;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -405,6 +425,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
@Audit(name = "用户更新", spel = "@sysUserMapper.selectById(#userDto.userId)")
|
||||
@CacheEvict(value = CacheConstants.USER_DETAILS, key = "#userDto.username")
|
||||
public Boolean updateUser(UserDTO userDto) {
|
||||
sysUserIdentityService.validateDto(userDto);
|
||||
// 更新用户表信息
|
||||
SysUser sysUser = new SysUser();
|
||||
BeanUtils.copyProperties(userDto, sysUser);
|
||||
@@ -423,6 +444,14 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
|
||||
this.updateById(sysUser);
|
||||
|
||||
if (userDto.getIdentityTypes() != null
|
||||
&& !userDto.getIdentityTypes().contains(UserIdentityTypeEnum.DEFAULT.getType())) {
|
||||
baseMapper.update(null, Wrappers.<SysUser>lambdaUpdate()
|
||||
.eq(SysUser::getUserId, userDto.getUserId())
|
||||
.set(SysUser::getPhone, null));
|
||||
}
|
||||
sysUserIdentityService.saveUserIdentity(userDto.getUserId(), userDto);
|
||||
|
||||
// 更新用户角色表
|
||||
if (userDto.getRole() != null) {
|
||||
sysUserRoleMapper.delete(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getUserId, userDto.getUserId()));
|
||||
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
package com.bsd.pjcloud.admin.service.impl.user;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.bsd.pjcloud.admin.api.constant.user.UserIdentityTypeEnum;
|
||||
import com.bsd.pjcloud.admin.api.dto.UserDTO;
|
||||
import com.bsd.pjcloud.admin.api.dto.user.SysUserStudentDto;
|
||||
import com.bsd.pjcloud.admin.api.entity.SysUser;
|
||||
import com.bsd.pjcloud.admin.api.entity.user.SysUserIdentityEntity;
|
||||
import com.bsd.pjcloud.admin.api.entity.user.SysUserStudentEntity;
|
||||
import com.bsd.pjcloud.admin.api.vo.UserVO;
|
||||
import com.bsd.pjcloud.admin.mapper.SysUserMapper;
|
||||
import com.bsd.pjcloud.admin.mapper.user.SysUserIdentityMapper;
|
||||
import com.bsd.pjcloud.admin.service.SysUserIdentityService;
|
||||
import com.bsd.pjcloud.admin.service.SysUserStudentService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 用户身份表
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SysUserIdentityServiceImpl extends ServiceImpl<SysUserIdentityMapper, SysUserIdentityEntity> implements SysUserIdentityService {
|
||||
|
||||
private static final int STUDENT_NO_MAX_LENGTH = 255;
|
||||
|
||||
private static final String PHONE_PATTERN = "^1[3-9]\\d{9}$";
|
||||
|
||||
private final SysUserStudentService sysUserStudentService;
|
||||
|
||||
private final SysUserMapper sysUserMapper;
|
||||
|
||||
@Override
|
||||
public void validateDto(UserDTO userDto) {
|
||||
if (userDto.getIdentityTypes() == null) {
|
||||
return;
|
||||
}
|
||||
if (CollUtil.isEmpty(userDto.getIdentityTypes())) {
|
||||
throw new IllegalArgumentException("用户身份不能为空");
|
||||
}
|
||||
|
||||
Set<String> identityTypes = new LinkedHashSet<>();
|
||||
for (String identityType : userDto.getIdentityTypes()) {
|
||||
String normalizedType = StrUtil.trim(identityType);
|
||||
if (UserIdentityTypeEnum.valueOfByType(normalizedType) == null) {
|
||||
throw new IllegalArgumentException("用户身份类型不正确");
|
||||
}
|
||||
if (!identityTypes.add(normalizedType)) {
|
||||
throw new IllegalArgumentException("用户身份不能重复");
|
||||
}
|
||||
}
|
||||
userDto.setIdentityTypes(List.copyOf(identityTypes));
|
||||
|
||||
if (identityTypes.contains(UserIdentityTypeEnum.DEFAULT.getType())) {
|
||||
validateDefaultIdentity(userDto);
|
||||
} else {
|
||||
userDto.setPhone(null);
|
||||
}
|
||||
|
||||
if (!identityTypes.contains(UserIdentityTypeEnum.STUDENT.getType())) {
|
||||
userDto.setStudentInfo(null);
|
||||
return;
|
||||
}
|
||||
validateStudentInfo(userDto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveUserIdentity(Long userId, UserDTO userDto) {
|
||||
if (userDto.getIdentityTypes() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
remove(Wrappers.<SysUserIdentityEntity>lambdaQuery()
|
||||
.eq(SysUserIdentityEntity::getUserId, userId));
|
||||
List<SysUserIdentityEntity> identities = userDto.getIdentityTypes().stream()
|
||||
.map(identityType -> {
|
||||
SysUserIdentityEntity identity = new SysUserIdentityEntity();
|
||||
identity.setUserId(userId);
|
||||
identity.setIdentityType(identityType);
|
||||
return identity;
|
||||
})
|
||||
.toList();
|
||||
saveBatch(identities);
|
||||
|
||||
if (!userDto.getIdentityTypes().contains(UserIdentityTypeEnum.STUDENT.getType())) {
|
||||
sysUserStudentService.removeById(userId);
|
||||
return;
|
||||
}
|
||||
SysUserStudentEntity student = new SysUserStudentEntity();
|
||||
BeanUtils.copyProperties(userDto.getStudentInfo(), student);
|
||||
student.setUserId(userId);
|
||||
sysUserStudentService.saveOrUpdate(student);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillUserIdentity(UserVO userVo) {
|
||||
if (userVo == null || userVo.getUserId() == null) {
|
||||
return;
|
||||
}
|
||||
List<String> identityTypes = list(Wrappers.<SysUserIdentityEntity>lambdaQuery()
|
||||
.eq(SysUserIdentityEntity::getUserId, userVo.getUserId()))
|
||||
.stream()
|
||||
.map(SysUserIdentityEntity::getIdentityType)
|
||||
.toList();
|
||||
userVo.setIdentityTypes(identityTypes);
|
||||
|
||||
if (!identityTypes.contains(UserIdentityTypeEnum.STUDENT.getType())) {
|
||||
return;
|
||||
}
|
||||
SysUserStudentEntity student = sysUserStudentService.getById(userVo.getUserId());
|
||||
if (student != null) {
|
||||
SysUserStudentDto studentInfo = new SysUserStudentDto();
|
||||
BeanUtils.copyProperties(student, studentInfo);
|
||||
userVo.setStudentInfo(studentInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private void validateStudentInfo(UserDTO userDto) {
|
||||
SysUserStudentDto studentInfo = userDto.getStudentInfo();
|
||||
if (studentInfo == null || StrUtil.isBlank(studentInfo.getStudentNo())) {
|
||||
throw new IllegalArgumentException("学号不能为空");
|
||||
}
|
||||
String studentNo = studentInfo.getStudentNo().trim();
|
||||
if (studentNo.length() > STUDENT_NO_MAX_LENGTH) {
|
||||
throw new IllegalArgumentException("学号不能超过255个字符");
|
||||
}
|
||||
if (sysUserStudentService.existsStudentNo(userDto.getUserId(), studentNo)) {
|
||||
throw new IllegalArgumentException("学号已存在");
|
||||
}
|
||||
studentInfo.setStudentNo(studentNo);
|
||||
}
|
||||
|
||||
private void validateDefaultIdentity(UserDTO userDto) {
|
||||
if (StrUtil.isBlank(userDto.getPhone())) {
|
||||
SysUser currentUser = userDto.getUserId() == null ? null : sysUserMapper.selectById(userDto.getUserId());
|
||||
if (currentUser == null || StrUtil.isBlank(currentUser.getPhone())) {
|
||||
throw new IllegalArgumentException("手机号不能为空");
|
||||
}
|
||||
return;
|
||||
}
|
||||
String phone = userDto.getPhone().trim();
|
||||
if (!phone.matches(PHONE_PATTERN)) {
|
||||
throw new IllegalArgumentException("手机号格式不正确");
|
||||
}
|
||||
userDto.setPhone(phone);
|
||||
}
|
||||
|
||||
}
|
||||
+386
@@ -0,0 +1,386 @@
|
||||
package com.bsd.pjcloud.admin.service.impl.user;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
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.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.mapper.user.SysUserRelationMapper;
|
||||
import com.bsd.pjcloud.admin.service.SysUserRelationService;
|
||||
import com.bsd.pjcloud.admin.service.SysUserRelationTypeService;
|
||||
import com.bsd.pjcloud.admin.service.SysUserService;
|
||||
import com.bsd.pjcloud.common.core.constant.CommonConstants;
|
||||
import com.bsd.pjcloud.common.core.exception.ErrorCodes;
|
||||
import com.bsd.pjcloud.common.core.util.MsgUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 用户多对多关系表
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SysUserRelationServiceImpl extends ServiceImpl<SysUserRelationMapper, SysUserRelationEntity> implements SysUserRelationService {
|
||||
|
||||
private static final Long TREE_ROOT_PARENT_ID = -1L;
|
||||
|
||||
private static final Long TREE_ROOT_NODE_ID = 0L;
|
||||
|
||||
private final SysUserService sysUserService;
|
||||
|
||||
private final SysUserRelationTypeService sysUserRelationTypeService;
|
||||
|
||||
@Override
|
||||
public SysUserRelationGraphVo getRelationGraph(Long userId) {
|
||||
SysUser rootUser = sysUserService.getById(userId);
|
||||
if (rootUser == null) {
|
||||
throw new RuntimeException("用户不存在");
|
||||
}
|
||||
RelationGraphData graphData = collectRelationGraph(userId);
|
||||
Map<Long, SysUser> userMap = sysUserService.listByIds(graphData.userIds).stream()
|
||||
.collect(Collectors.toMap(SysUser::getUserId, Function.identity(), (first, second) -> first));
|
||||
Map<Long, SysUserRelationTypeEntity> relationTypeMap = graphData.relationTypeIds.isEmpty()
|
||||
? Map.of()
|
||||
: sysUserRelationTypeService.listByIds(graphData.relationTypeIds).stream()
|
||||
.collect(Collectors.toMap(SysUserRelationTypeEntity::getRelationTypeId,
|
||||
Function.identity(), (first, second) -> first));
|
||||
|
||||
Map<Long, SysUserRelationGraphVo> nodeMap = graphData.nodes.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()
|
||||
.filter(node -> !Objects.equals(node.nodeId, TREE_ROOT_NODE_ID))
|
||||
.forEach(node -> {
|
||||
SysUserRelationGraphVo parentNode = nodeMap.get(node.parentNodeId);
|
||||
SysUserRelationGraphVo currentNode = nodeMap.get(node.nodeId);
|
||||
if (parentNode != null && currentNode != null) {
|
||||
parentNode.getChildren().add(currentNode);
|
||||
}
|
||||
});
|
||||
rootNode.setUserCount(graphData.userIds.size());
|
||||
rootNode.setRelationCount(graphData.relationIds.size());
|
||||
return rootNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createUserAndRelation(SysUserRelationCreateUserDto dto) {
|
||||
validateCreateUserAndRelation(dto);
|
||||
|
||||
UserDTO userDto = new UserDTO();
|
||||
BeanUtils.copyProperties(dto, userDto);
|
||||
Long newUserId = sysUserService.saveUserWithoutAudit(userDto);
|
||||
Long subjectUserId = dto.getSubjectUserId() == null ? newUserId : dto.getSubjectUserId();
|
||||
Long objectUserId = dto.getObjectUserId() == null ? newUserId : dto.getObjectUserId();
|
||||
SysUserRelationTypeEntity relationType = validateRelation(
|
||||
subjectUserId, objectUserId, dto.getRelationTypeId());
|
||||
validateRelationNotExists(subjectUserId, objectUserId, relationType);
|
||||
|
||||
SysUserRelationEntity relation = new SysUserRelationEntity();
|
||||
relation.setSubjectUserId(subjectUserId);
|
||||
relation.setObjectUserId(objectUserId);
|
||||
relation.setRelationTypeId(dto.getRelationTypeId());
|
||||
relation.setEffectiveTime(dto.getEffectiveTime());
|
||||
relation.setExpireTime(dto.getExpireTime());
|
||||
relation.setRemark(dto.getRemark());
|
||||
save(relation);
|
||||
return newUserId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createRelation(SysUserRelationCreateDto dto) {
|
||||
SysUserRelationTypeEntity relationType = validateRelation(
|
||||
dto.getSubjectUserId(), dto.getObjectUserId(), dto.getRelationTypeId());
|
||||
validateRelationNotExists(dto.getSubjectUserId(), dto.getObjectUserId(), relationType);
|
||||
|
||||
SysUserRelationEntity relation = new SysUserRelationEntity();
|
||||
BeanUtils.copyProperties(dto, relation);
|
||||
save(relation);
|
||||
return relation.getRelationId();
|
||||
}
|
||||
|
||||
private void validateCreateUserAndRelation(SysUserRelationCreateUserDto dto) {
|
||||
Long existingUserId = dto.getSubjectUserId() == null ? dto.getObjectUserId() : dto.getSubjectUserId();
|
||||
validateExistingUserAndRelationType(existingUserId, dto.getRelationTypeId());
|
||||
boolean usernameExists = sysUserService.exists(Wrappers.<SysUser>lambdaQuery()
|
||||
.eq(SysUser::getUsername, dto.getUsername()));
|
||||
if (usernameExists) {
|
||||
throw new RuntimeException(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, dto.getUsername()));
|
||||
}
|
||||
if (StrUtil.isNotBlank(dto.getPhone())) {
|
||||
boolean phoneExists = sysUserService.exists(Wrappers.<SysUser>lambdaQuery()
|
||||
.eq(SysUser::getPhone, dto.getPhone()));
|
||||
if (phoneExists) {
|
||||
throw new RuntimeException(MsgUtils.getMessage(ErrorCodes.SYS_USER_PHONE_EXISTING, dto.getPhone()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private SysUserRelationTypeEntity validateRelation(Long subjectUserId, Long objectUserId, Long relationTypeId) {
|
||||
if (Objects.equals(subjectUserId, objectUserId)) {
|
||||
throw new RuntimeException("不能与自己建立用户关系");
|
||||
}
|
||||
if (sysUserService.getById(subjectUserId) == null) {
|
||||
throw new RuntimeException("关系主语用户不存在");
|
||||
}
|
||||
return validateObjectUserAndRelationType(objectUserId, relationTypeId);
|
||||
}
|
||||
|
||||
private SysUserRelationTypeEntity validateObjectUserAndRelationType(Long objectUserId, Long relationTypeId) {
|
||||
SysUserRelationTypeEntity relationType = validateExistingUserAndRelationType(objectUserId, relationTypeId);
|
||||
return relationType;
|
||||
}
|
||||
|
||||
private SysUserRelationTypeEntity validateExistingUserAndRelationType(Long userId, Long relationTypeId) {
|
||||
if (sysUserService.getById(userId) == null) {
|
||||
throw new RuntimeException("关联用户不存在");
|
||||
}
|
||||
SysUserRelationTypeEntity relationType = sysUserRelationTypeService.getById(relationTypeId);
|
||||
if (relationType == null || !CommonConstants.STATUS_NORMAL.equals(relationType.getStatus())) {
|
||||
throw new RuntimeException("关系类型不存在或已停用");
|
||||
}
|
||||
return relationType;
|
||||
}
|
||||
|
||||
private void validateRelationNotExists(Long subjectUserId, Long objectUserId,
|
||||
SysUserRelationTypeEntity relationType) {
|
||||
boolean directed = "1".equals(relationType.getDirectedFlag());
|
||||
boolean exists = exists(Wrappers.<SysUserRelationEntity>lambdaQuery()
|
||||
.eq(SysUserRelationEntity::getRelationTypeId, relationType.getRelationTypeId())
|
||||
.and(wrapper -> wrapper
|
||||
.nested(current -> current.eq(SysUserRelationEntity::getSubjectUserId, subjectUserId)
|
||||
.eq(SysUserRelationEntity::getObjectUserId, objectUserId))
|
||||
.or(!directed, reverse -> reverse
|
||||
.eq(SysUserRelationEntity::getSubjectUserId, objectUserId)
|
||||
.eq(SysUserRelationEntity::getObjectUserId, subjectUserId))));
|
||||
if (exists) {
|
||||
throw new RuntimeException("所选用户之间已存在该类型的关系");
|
||||
}
|
||||
}
|
||||
|
||||
private RelationGraphData collectRelationGraph(Long rootUserId) {
|
||||
RelationGraphData graphData = new RelationGraphData();
|
||||
graphData.userIds.add(rootUserId);
|
||||
graphData.nodes.add(RelationGraphNode.root(rootUserId));
|
||||
|
||||
Set<Long> expandedUserIds = new HashSet<>();
|
||||
List<RelationNodeContext> currentLevel = List.of(new RelationNodeContext(TREE_ROOT_NODE_ID, rootUserId));
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (expandableNodes.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));
|
||||
}
|
||||
}
|
||||
currentLevel = nextLevel;
|
||||
}
|
||||
return graphData;
|
||||
}
|
||||
|
||||
private List<SysUserRelationEntity> listRelations(Set<Long> userIds) {
|
||||
return list(Wrappers.<SysUserRelationEntity>lambdaQuery()
|
||||
.and(wrapper -> wrapper.in(SysUserRelationEntity::getSubjectUserId, userIds)
|
||||
.or()
|
||||
.in(SysUserRelationEntity::getObjectUserId, userIds)));
|
||||
}
|
||||
|
||||
private SysUserRelationGraphVo buildGraphNode(RelationGraphNode node, Map<Long, SysUser> userMap,
|
||||
Map<Long, SysUserRelationTypeEntity> relationTypeMap) {
|
||||
SysUser user = userMap.get(node.userId);
|
||||
SysUserRelationEntity relation = node.relation;
|
||||
SysUserRelationTypeEntity relationType = relation == null
|
||||
? null : relationTypeMap.get(relation.getRelationTypeId());
|
||||
|
||||
SysUserRelationGraphVo graphNode = new SysUserRelationGraphVo();
|
||||
graphNode.setNodeId(node.nodeId);
|
||||
graphNode.setParentNodeId(node.parentNodeId);
|
||||
graphNode.setRoot(relation == null);
|
||||
graphNode.setRepeated(node.repeated);
|
||||
graphNode.setUserId(node.userId);
|
||||
graphNode.setUsername(user == null ? null : user.getUsername());
|
||||
graphNode.setName(user == null ? null : user.getName());
|
||||
graphNode.setNickname(user == null ? null : user.getNickname());
|
||||
graphNode.setDisplayName(getUserDisplayName(user, node.userId));
|
||||
graphNode.setAvatar(user == null ? null : user.getAvatar());
|
||||
graphNode.setGender(user == null ? null : user.getGender());
|
||||
if (relation != null) {
|
||||
String userRoleName = getUserRoleName(relationType, node.parentIsSubject);
|
||||
graphNode.setRelationId(relation.getRelationId());
|
||||
graphNode.setSubjectUserId(relation.getSubjectUserId());
|
||||
graphNode.setObjectUserId(relation.getObjectUserId());
|
||||
graphNode.setRelationTypeId(relation.getRelationTypeId());
|
||||
graphNode.setEffectiveTime(relation.getEffectiveTime());
|
||||
graphNode.setExpireTime(relation.getExpireTime());
|
||||
graphNode.setRemark(relation.getRemark());
|
||||
graphNode.setRelationDirection(node.parentIsSubject ? "subject-to-object" : "object-to-subject");
|
||||
graphNode.setRelationCode(relationType == null ? null : relationType.getRelationCode());
|
||||
graphNode.setRelationName(relationType == null ? null : relationType.getRelationName());
|
||||
graphNode.setCategory(relationType == null ? null : relationType.getCategory());
|
||||
graphNode.setDirectedFlag(relationType == null ? null : relationType.getDirectedFlag());
|
||||
graphNode.setUserRoleName(userRoleName);
|
||||
graphNode.setParentRoleName(getParentRoleName(relationType, node.parentIsSubject));
|
||||
graphNode.setRelationDescription(buildRelationDescription(
|
||||
user, node.userId, userMap.get(node.parentUserId), node.parentUserId,
|
||||
userRoleName, relationType));
|
||||
}
|
||||
return graphNode;
|
||||
}
|
||||
|
||||
private String getUserDisplayName(SysUser user, Long userId) {
|
||||
if (user == null) {
|
||||
return String.valueOf(userId);
|
||||
}
|
||||
if (StrUtil.isNotBlank(user.getName())) {
|
||||
return user.getName();
|
||||
}
|
||||
if (StrUtil.isNotBlank(user.getNickname())) {
|
||||
return user.getNickname();
|
||||
}
|
||||
return StrUtil.blankToDefault(user.getUsername(), String.valueOf(userId));
|
||||
}
|
||||
|
||||
private String getUserRoleName(SysUserRelationTypeEntity relationType, boolean parentIsSubject) {
|
||||
if (relationType == null) {
|
||||
return null;
|
||||
}
|
||||
return parentIsSubject ? relationType.getObjectRoleName() : relationType.getSubjectRoleName();
|
||||
}
|
||||
|
||||
private String getParentRoleName(SysUserRelationTypeEntity relationType, boolean parentIsSubject) {
|
||||
if (relationType == null) {
|
||||
return null;
|
||||
}
|
||||
return parentIsSubject ? relationType.getSubjectRoleName() : relationType.getObjectRoleName();
|
||||
}
|
||||
|
||||
private String buildRelationDescription(SysUser user, Long userId, SysUser parentUser, Long parentUserId,
|
||||
String userRoleName, SysUserRelationTypeEntity relationType) {
|
||||
String userName = getUserDisplayName(user, userId);
|
||||
String parentUserName = getUserDisplayName(parentUser, parentUserId);
|
||||
if (StrUtil.isNotBlank(userRoleName)) {
|
||||
return userName + "是" + parentUserName + "的" + userRoleName;
|
||||
}
|
||||
if (relationType != null && StrUtil.isNotBlank(relationType.getRelationName())) {
|
||||
return userName + "与" + parentUserName + "的关系是" + relationType.getRelationName();
|
||||
}
|
||||
return userName + "与" + parentUserName + "存在用户关系";
|
||||
}
|
||||
|
||||
private static class RelationGraphData {
|
||||
|
||||
private final List<RelationGraphNode> nodes = new ArrayList<>();
|
||||
|
||||
private final Set<Long> userIds = new LinkedHashSet<>();
|
||||
|
||||
private final Set<Long> relationIds = new HashSet<>();
|
||||
|
||||
private final Set<Long> relationTypeIds = new HashSet<>();
|
||||
}
|
||||
|
||||
private static class RelationGraphNode {
|
||||
|
||||
private final Long nodeId;
|
||||
|
||||
private final Long parentNodeId;
|
||||
|
||||
private final Long parentUserId;
|
||||
|
||||
private final Long userId;
|
||||
|
||||
private final SysUserRelationEntity relation;
|
||||
|
||||
private final boolean parentIsSubject;
|
||||
|
||||
private final boolean repeated;
|
||||
|
||||
private RelationGraphNode(Long nodeId, Long parentNodeId, Long parentUserId, Long userId,
|
||||
SysUserRelationEntity relation, boolean parentIsSubject, boolean repeated) {
|
||||
this.nodeId = nodeId;
|
||||
this.parentNodeId = parentNodeId;
|
||||
this.parentUserId = parentUserId;
|
||||
this.userId = userId;
|
||||
this.relation = relation;
|
||||
this.parentIsSubject = parentIsSubject;
|
||||
this.repeated = repeated;
|
||||
}
|
||||
|
||||
private static RelationGraphNode root(Long userId) {
|
||||
return new RelationGraphNode(TREE_ROOT_NODE_ID, TREE_ROOT_PARENT_ID, null,
|
||||
userId, null, false, false);
|
||||
}
|
||||
|
||||
private static RelationGraphNode child(Long nodeId, Long parentNodeId, Long parentUserId, Long userId,
|
||||
SysUserRelationEntity relation, boolean parentIsSubject,
|
||||
boolean repeated) {
|
||||
return new RelationGraphNode(nodeId, parentNodeId, parentUserId,
|
||||
userId, relation, parentIsSubject, repeated);
|
||||
}
|
||||
}
|
||||
|
||||
private static class RelationNodeContext {
|
||||
|
||||
private final Long nodeId;
|
||||
|
||||
private final Long userId;
|
||||
|
||||
private RelationNodeContext(Long nodeId, Long userId) {
|
||||
this.nodeId = nodeId;
|
||||
this.userId = userId;
|
||||
}
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
package com.bsd.pjcloud.admin.service.impl.user;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.bsd.pjcloud.admin.api.entity.user.SysUserRelationEntity;
|
||||
import com.bsd.pjcloud.admin.api.entity.user.SysUserRelationTypeEntity;
|
||||
import com.bsd.pjcloud.admin.mapper.user.SysUserRelationMapper;
|
||||
import com.bsd.pjcloud.admin.mapper.user.SysUserRelationTypeMapper;
|
||||
import com.bsd.pjcloud.admin.service.SysUserRelationTypeService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* 用户关系类型表
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SysUserRelationTypeServiceImpl extends ServiceImpl<SysUserRelationTypeMapper, SysUserRelationTypeEntity> implements SysUserRelationTypeService {
|
||||
|
||||
private final SysUserRelationMapper sysUserRelationMapper;
|
||||
|
||||
/**
|
||||
* 新增用户关系类型表
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long create(SysUserRelationTypeEntity dto) {
|
||||
validateUnique(dto, null);
|
||||
baseMapper.insert(dto);
|
||||
return dto.getRelationTypeId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户关系类型表
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long edit(SysUserRelationTypeEntity dto) {
|
||||
if (dto.getRelationTypeId() == null) {
|
||||
throw new IllegalArgumentException("关系类型ID不能为空");
|
||||
}
|
||||
if (getById(dto.getRelationTypeId()) == null) {
|
||||
throw new IllegalArgumentException("用户关系类型不存在");
|
||||
}
|
||||
validateUnique(dto, dto.getRelationTypeId());
|
||||
baseMapper.updateById(dto);
|
||||
return dto.getRelationTypeId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id删除用户关系类型表
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delById(ArrayList<Long> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Long relationCount = sysUserRelationMapper.selectCount(Wrappers.<SysUserRelationEntity>lambdaQuery()
|
||||
.in(SysUserRelationEntity::getRelationTypeId, ids));
|
||||
if (relationCount != null && relationCount > 0) {
|
||||
throw new IllegalStateException("所选关系类型已被用户关系引用,无法删除");
|
||||
}
|
||||
removeBatchByIds(ids);
|
||||
}
|
||||
|
||||
private void validateUnique(SysUserRelationTypeEntity dto, Long excludeId) {
|
||||
if (dto.getRelationTypeId() != null) {
|
||||
Long relationTypeIdCount = baseMapper.selectCount(Wrappers.<SysUserRelationTypeEntity>lambdaQuery()
|
||||
.eq(SysUserRelationTypeEntity::getRelationTypeId, dto.getRelationTypeId())
|
||||
.ne(excludeId != null, SysUserRelationTypeEntity::getRelationTypeId, excludeId));
|
||||
if (relationTypeIdCount != null && relationTypeIdCount > 0) {
|
||||
throw new IllegalArgumentException("关系类型ID不能重复");
|
||||
}
|
||||
}
|
||||
Long categoryCount = baseMapper.selectCount(Wrappers.<SysUserRelationTypeEntity>lambdaQuery()
|
||||
.eq(SysUserRelationTypeEntity::getCategory, dto.getCategory())
|
||||
.ne(excludeId != null, SysUserRelationTypeEntity::getRelationTypeId, excludeId));
|
||||
if (categoryCount != null && categoryCount > 0) {
|
||||
throw new IllegalArgumentException("关系分类不能重复");
|
||||
}
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.bsd.pjcloud.admin.service.impl.user;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.bsd.pjcloud.admin.api.entity.user.SysUserStudentEntity;
|
||||
import com.bsd.pjcloud.admin.mapper.user.SysUserStudentMapper;
|
||||
import com.bsd.pjcloud.admin.service.SysUserStudentService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 学生用户扩展信息表
|
||||
*/
|
||||
@Service
|
||||
public class SysUserStudentServiceImpl extends ServiceImpl<SysUserStudentMapper, SysUserStudentEntity> implements SysUserStudentService {
|
||||
|
||||
@Override
|
||||
public boolean existsStudentNo(Long userId, String studentNo) {
|
||||
if (StrUtil.isBlank(studentNo)) {
|
||||
return false;
|
||||
}
|
||||
return exists(Wrappers.<SysUserStudentEntity>lambdaQuery()
|
||||
.eq(SysUserStudentEntity::getStudentNo, studentNo.trim())
|
||||
.ne(userId != null, SysUserStudentEntity::getUserId, userId));
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.bsd.pjcloud.admin.mapper.user.SysUserIdentityMapper">
|
||||
|
||||
</mapper>
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.bsd.pjcloud.admin.mapper.user.SysUserRelationMapper">
|
||||
|
||||
|
||||
</mapper>
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.bsd.pjcloud.admin.mapper.user.SysUserRelationTypeMapper">
|
||||
|
||||
|
||||
</mapper>
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="com.bsd.pjcloud.admin.mapper.user.SysUserStudentMapper">
|
||||
|
||||
</mapper>
|
||||
Reference in new issue
Block a user