staffRoles = new ArrayList<>();
+
+ /**
+ * 创建时间
+ */
+ @Column(name = "created_at", updatable = false)
+ private LocalDateTime createdAt;
+
+ /**
+ * 更新时间
+ */
+ @Column(name = "updated_at")
+ private LocalDateTime updatedAt;
+
+ /**
+ * 关联的User实体
+ * 采用一对一关系
+ */
+ @OneToOne
+ @JoinColumn(name = "user_id")
+ private User user;
+}
diff --git a/module-auth/src/main/java/com/ether/pms/auth/entity/ProjectStaffRole.java b/module-auth/src/main/java/com/ether/pms/auth/entity/ProjectStaffRole.java
new file mode 100644
index 0000000..7ac93d3
--- /dev/null
+++ b/module-auth/src/main/java/com/ether/pms/auth/entity/ProjectStaffRole.java
@@ -0,0 +1,42 @@
+package com.ether.pms.auth.entity;
+
+import java.time.LocalDateTime;
+import java.util.UUID;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.PrePersist;
+import jakarta.persistence.Table;
+import lombok.Data;
+
+@Entity
+@Table(name = "project_staff_role")
+@Data
+public class ProjectStaffRole {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.UUID)
+ private UUID id;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "staff_id", nullable = false)
+ private ProjectStaff staff;
+
+ @ManyToOne(fetch = FetchType.EAGER)
+ @JoinColumn(name = "role_id", nullable = false)
+ private Role role;
+
+ @Column(name = "created_at")
+ private LocalDateTime createdAt;
+
+ @PrePersist
+ protected void onCreate() {
+ createdAt = LocalDateTime.now();
+ }
+}
\ No newline at end of file
diff --git a/module-auth/src/main/java/com/ether/pms/auth/entity/Resident.java b/module-auth/src/main/java/com/ether/pms/auth/entity/Resident.java
new file mode 100644
index 0000000..28907f8
--- /dev/null
+++ b/module-auth/src/main/java/com/ether/pms/auth/entity/Resident.java
@@ -0,0 +1,72 @@
+package com.ether.pms.auth.entity;
+
+import jakarta.persistence.*;
+import lombok.Data;
+import java.time.LocalDateTime;
+import java.util.UUID;
+
+/**
+ * 住户实体类
+ *
+ * 表示住户类型的用户信息,包含身份证、认证状态等住户相关信息。
+ *
+ * 与User实体为一对一关系,共享主键。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
+@Entity
+@Table(name = "resident")
+@Data
+public class Resident {
+
+ /**
+ * 用户ID
+ * 主键,也是外键指向auth_user表
+ */
+ @Id
+ private UUID userId;
+
+ /**
+ * 身份证号码
+ * 住户的身份证号,用于身份验证
+ */
+ @Column(length = 18)
+ private String idCard;
+
+ /**
+ * 住户类型
+ * 标识住户类型:OWNER(业主)、FAMILY(家属)、TENANT(租户)
+ */
+ @Column(length = 20)
+ private String residentType;
+
+ /**
+ * 认证状态
+ * 标识住户的认证状态:UNVERIFIED(未认证)、PENDING(待审核)、VERIFIED(已认证)、REJECTED(已拒绝)
+ */
+ @Column(length = 20)
+ private String verificationStatus;
+
+ /**
+ * 认证时间
+ * 记录住户认证通过的时间
+ */
+ private LocalDateTime verifiedAt;
+
+ /**
+ * 认证人ID
+ * 执行认证操作的管理员用户ID
+ */
+ private UUID verifiedBy;
+
+ /**
+ * 关联的User实体
+ * 采用一对一关系,共享主键
+ */
+ @OneToOne
+ @MapsId
+ @JoinColumn(name = "user_id")
+ private User user;
+}
diff --git a/module-auth/src/main/java/com/ether/pms/auth/entity/ResidentSpace.java b/module-auth/src/main/java/com/ether/pms/auth/entity/ResidentSpace.java
new file mode 100644
index 0000000..3fdc583
--- /dev/null
+++ b/module-auth/src/main/java/com/ether/pms/auth/entity/ResidentSpace.java
@@ -0,0 +1,71 @@
+package com.ether.pms.auth.entity;
+
+import jakarta.persistence.*;
+import lombok.Data;
+import java.time.LocalDate;
+import java.util.UUID;
+
+/**
+ * 住户房屋关联实体类
+ *
+ * 表示住户与房屋之间的关联关系,记录住户与房屋的绑定信息。
+ *
+ * 支持业主、家属、租户等多种关系类型,以及绑定状态管理。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
+@Entity
+@Table(name = "resident_space")
+@Data
+public class ResidentSpace {
+
+ /**
+ * 关联记录唯一标识符
+ * 采用UUID策略自动生成
+ */
+ @Id
+ @GeneratedValue(strategy = GenerationType.UUID)
+ private UUID id;
+
+ /**
+ * 用户ID
+ * 关联的用户唯一标识符
+ */
+ @Column(name = "user_id", nullable = false)
+ private UUID userId;
+
+ /**
+ * 房屋ID
+ * 关联的房屋唯一标识符
+ */
+ @Column(name = "space_id", nullable = false)
+ private UUID spaceId;
+
+ /**
+ * 关系类型
+ * 标识住户与房屋的关系:OWNER(业主)、FAMILY(家属)、TENANT(租户)
+ */
+ @Column(length = 20)
+ private String relationType;
+
+ /**
+ * 绑定状态
+ * 标识关联的状态:PENDING(待生效)、ACTIVE(生效中)、EXPIRED(已过期)、CANCELLED(已取消)
+ */
+ @Column(length = 20)
+ private String bindingStatus;
+
+ /**
+ * 开始日期
+ * 关联关系的生效日期
+ */
+ private LocalDate startDate;
+
+ /**
+ * 结束日期
+ * 关联关系的失效日期,永久关联则为空
+ */
+ private LocalDate endDate;
+}
diff --git a/module-auth/src/main/java/com/ether/pms/auth/entity/Role.java b/module-auth/src/main/java/com/ether/pms/auth/entity/Role.java
index 7a5dab8..204c6d3 100644
--- a/module-auth/src/main/java/com/ether/pms/auth/entity/Role.java
+++ b/module-auth/src/main/java/com/ether/pms/auth/entity/Role.java
@@ -9,45 +9,92 @@ import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
+/**
+ * 角色实体类
+ *
+ * 用于定义系统中的角色信息,包括角色代码、名称、描述、类型、数据范围等属性。
+ * 角色与权限通过多对多关联,一个角色可以拥有多个权限。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
@Entity
@Table(name = "auth_role")
@Data
public class Role {
-
+
+ /**
+ * 角色唯一标识符
+ * 使用UUID自动生成
+ */
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;
-
+
+ /**
+ * 角色代码
+ * 用于系统内部识别,必须唯一
+ * 格式:只能包含字母、数字和下划线,长度2-50位
+ */
@NotNull(message = "角色代码不能为空")
@Size(min = 2, max = 50, message = "角色代码长度必须在2-50位之间")
@Pattern(regexp = "^[a-zA-Z0-9_]+$", message = "角色代码只能包含字母、数字和下划线")
@Column(unique = true, nullable = false, length = 50)
private String code;
-
+
+ /**
+ * 角色名称
+ * 用于前端展示,长度2-50位
+ */
@NotNull(message = "角色名称不能为空")
@Size(min = 2, max = 50, message = "角色名称长度必须在2-50位之间")
@Column(nullable = false, length = 50)
private String name;
-
+
+ /**
+ * 角色描述
+ * 对角色的详细说明,长度不超过200位
+ */
@Size(max = 200, message = "角色描述长度不能超过200位")
@Column(length = 200)
private String description;
-
+
+ /**
+ * 角色类型
+ * 区分系统级、项目级、部门级角色
+ */
@Enumerated(EnumType.STRING)
@Column(length = 20)
private RoleType type;
-
+
+ /**
+ * 数据范围
+ * 定义角色可访问的数据范围,默认为本人数据
+ */
@Enumerated(EnumType.STRING)
@Column(length = 20)
private DataScope dataScope = DataScope.SELF;
-
+
+ /**
+ * 所属项目ID
+ * 用于项目级角色的项目归属
+ */
@Column(length = 50)
private String projectId;
-
+
+ /**
+ * 角色状态
+ * 启用或禁用,默认为启用
+ */
@Enumerated(EnumType.STRING)
@Column(length = 20)
private RoleStatus status = RoleStatus.ENABLED;
-
+
+ /**
+ * 角色关联的权限列表
+ * 多对多关系,通过auth_role_permission关联表维护
+ */
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "auth_role_permission",
@@ -55,55 +102,92 @@ public class Role {
inverseJoinColumns = @JoinColumn(name = "permission_id")
)
private List permissions;
-
+
+ /**
+ * 角色创建时间
+ * 自动设置,记录创建时刻
+ */
private LocalDateTime createdAt;
-
+
+ /**
+ * 角色更新时间
+ * 自动设置,每次更新时自动修改
+ */
private LocalDateTime updatedAt;
-
+
+ /**
+ * 持久化前回调
+ * 自动设置创建时间和更新时间
+ */
@PrePersist
public void prePersist() {
this.createdAt = LocalDateTime.now();
this.updatedAt = LocalDateTime.now();
}
-
+
+ /**
+ * 更新前回调
+ * 自动设置更新时间
+ */
@PreUpdate
public void preUpdate() {
this.updatedAt = LocalDateTime.now();
}
-
+
+ /**
+ * 角色类型枚举
+ * 定义角色的层级分类
+ */
public enum RoleType {
+ /** 系统级角色,可访问所有项目数据 */
SYSTEM("系统级"),
+ /** 项目级角色,仅可访问指定项目数据 */
PROJECT("项目级"),
+ /** 部门级角色,仅可访问本部门数据 */
DEPARTMENT("部门级");
-
+
private final String desc;
-
+
RoleType(String desc) {
this.desc = desc;
}
}
-
+
+ /**
+ * 数据范围枚举
+ * 定义角色可查看的数据范围级别
+ */
public enum DataScope {
+ /** 全部数据,可查看所有数据 */
ALL("全部"),
+ /** 本项目数据,仅可查看所属项目数据 */
PROJECT("本项目"),
+ /** 本部门数据,仅可查看本部门数据 */
DEPARTMENT("本部门"),
+ /** 本 人数据,仅可查看本人数据 */
SELF("本人");
-
+
private final String desc;
-
+
DataScope(String desc) {
this.desc = desc;
}
}
-
+
+ /**
+ * 角色状态枚举
+ * 定义角色的启用/禁用状态
+ */
public enum RoleStatus {
+ /** 角色已启用,可以正常使用 */
ENABLED("启用"),
+ /** 角色已禁用,不可使用 */
DISABLED("禁用");
-
+
private final String desc;
-
+
RoleStatus(String desc) {
this.desc = desc;
}
}
-}
+}
\ No newline at end of file
diff --git a/module-auth/src/main/java/com/ether/pms/auth/entity/Space.java b/module-auth/src/main/java/com/ether/pms/auth/entity/Space.java
new file mode 100644
index 0000000..d99e62b
--- /dev/null
+++ b/module-auth/src/main/java/com/ether/pms/auth/entity/Space.java
@@ -0,0 +1,84 @@
+package com.ether.pms.auth.entity;
+
+import jakarta.persistence.*;
+import lombok.Data;
+import java.math.BigDecimal;
+import java.util.UUID;
+
+/**
+ * 房屋空间实体类
+ *
+ * 表示项目中的房屋或空间信息,包含楼栋、单元、房号等。
+ *
+ * 支持住宅和商业两种类型的空间管理。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
+@Entity
+@Table(name = "space")
+@Data
+public class Space {
+
+ /**
+ * 空间唯一标识符
+ * 采用UUID策略自动生成
+ */
+ @Id
+ @GeneratedValue(strategy = GenerationType.UUID)
+ private UUID id;
+
+ /**
+ * 所属项目ID
+ * 空间所属项目的唯一标识符
+ */
+ private UUID projectId;
+
+ /**
+ * 楼栋
+ * 房屋所在的楼栋号或名称
+ */
+ @Column(length = 50)
+ private String building;
+
+ /**
+ * 单元
+ * 房屋所在的单元号
+ */
+ @Column(length = 50)
+ private String unit;
+
+ /**
+ * 房号
+ * 房屋的房间号
+ */
+ @Column(length = 50)
+ private String roomNo;
+
+ /**
+ * 房屋类型
+ * 标识房屋类型:RESIDENTIAL(住宅)、COMMERCIAL(商业)
+ */
+ @Column(length = 20)
+ private String spaceType;
+
+ /**
+ * 楼层
+ * 房屋所在的楼层
+ */
+ private Integer floor;
+
+ /**
+ * 建筑面积
+ * 房屋的建筑面积,单位平方米
+ */
+ private BigDecimal unitArea;
+
+ /**
+ * 状态
+ * 标识房屋的状态:正常、空置、已售等
+ */
+ @Column(length = 20)
+ private String status;
+}
diff --git a/module-auth/src/main/java/com/ether/pms/auth/entity/SysConfig.java b/module-auth/src/main/java/com/ether/pms/auth/entity/SysConfig.java
index 9adc3ab..328e08c 100644
--- a/module-auth/src/main/java/com/ether/pms/auth/entity/SysConfig.java
+++ b/module-auth/src/main/java/com/ether/pms/auth/entity/SysConfig.java
@@ -11,6 +11,13 @@ import org.hibernate.annotations.UpdateTimestamp;
import java.time.LocalDateTime;
import java.util.UUID;
+/**
+ * 系统配置实体类
+ * 用于存储系统的键值对配置信息,如物业企业名称等
+ *
+ * @author Ether Team
+ * @since 1.0.0
+ */
@Entity
@Table(name = "sys_config")
@Data
@@ -19,23 +26,47 @@ import java.util.UUID;
@Builder
public class SysConfig {
+ /**
+ * 配置项唯一标识
+ * 使用 UUID 自动生成
+ */
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;
+ /**
+ * 配置键
+ * 唯一标识一个配置项,如:property_company_name
+ */
@Column(name = "config_key", nullable = false, unique = true, length = 128)
private String configKey;
+ /**
+ * 配置值
+ * 使用 TEXT 类型存储,支持长文本
+ */
@Column(name = "config_value", columnDefinition = "TEXT")
private String configValue;
+ /**
+ * 配置描述
+ * 用于说明该配置项的用途
+ */
@Column(name = "description", length = 256)
private String description;
+ /**
+ * 创建时间
+ * 自动填充,不可更新
+ */
@CreationTimestamp
@Column(name = "created_at", nullable = false, updatable = false)
private LocalDateTime createdAt;
+ /**
+ * 更新时间
+ * 自动填充,更新时自动修改
+ */
@UpdateTimestamp
@Column(name = "updated_at", nullable = false)
private LocalDateTime updatedAt;
diff --git a/module-auth/src/main/java/com/ether/pms/auth/entity/User.java b/module-auth/src/main/java/com/ether/pms/auth/entity/User.java
index ed12425..bf9c3cc 100644
--- a/module-auth/src/main/java/com/ether/pms/auth/entity/User.java
+++ b/module-auth/src/main/java/com/ether/pms/auth/entity/User.java
@@ -10,48 +10,120 @@ import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
+/**
+ * 用户实体类
+ *
+ * 表示系统中的用户信息,包含用户的基本认证信息和个人资料。
+ *
+ * 使用JPA注解映射到auth_user表,支持基本的CRUD操作。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
@Entity
@Table(name = "auth_user")
@Data
public class User {
-
+
+ /**
+ * 用户唯一标识符
+ * 采用UUID策略自动生成
+ */
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;
-
+
+ /**
+ * 用户名
+ * 用于用户登录,唯一标识,长度3-50位,只能包含字母、数字和下划线
+ */
@NotNull(message = "用户名不能为空")
@Size(min = 3, max = 50, message = "用户名长度必须在3-50位之间")
@Pattern(regexp = "^[a-zA-Z0-9_]+$", message = "用户名只能包含字母、数字和下划线")
@Column(unique = true, nullable = false, length = 50)
private String username;
-
+
+ /**
+ * 密码(加密存储)
+ * 使用BCrypt加密后的密码原文
+ */
@NotNull(message = "密码不能为空")
@Column(nullable = false, length = 255)
private String password;
-
+
+ /**
+ * 密码盐值
+ * 用于增强密码加密的安全性
+ */
private String salt;
-
+
+ /**
+ * 真实姓名
+ * 用户的真实姓名,用于显示
+ */
@Column(length = 50)
private String realName;
-
+
+ /**
+ * 手机号码
+ * 中国大陆手机号格式,11位数字
+ */
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
@Column(length = 20)
private String phone;
-
+
+ /**
+ * 电子邮箱
+ * 用户的邮箱地址,用于通知和验证
+ */
@Email(message = "邮箱格式不正确")
@Column(length = 100)
private String email;
-
+
+ /**
+ * 头像URL
+ * 用户头像的存储路径或URL
+ */
private String avatar;
-
+
+ /**
+ * 用户状态
+ * 标识用户的当前状态:正常、锁定或禁用
+ */
@Enumerated(EnumType.STRING)
@Column(length = 20)
private UserStatus status = UserStatus.ACTIVE;
-
+
+ /**
+ * 用户类型
+ * 标识用户的类型:ENTERPRISE(企业用户)、PROJECT_STAFF(项目员工)、RESIDENT(住户)、CUSTOMER(客户)
+ */
+ @Column(length = 20)
+ private String userType;
+
+ /**
+ * 部门ID
+ * 用户所属的部门标识符
+ */
+ private UUID deptId;
+
+ /**
+ * 最后登录时间
+ * 记录用户最后一次成功登录的时间
+ */
private LocalDateTime lastLoginTime;
-
+
+ /**
+ * 最后登录IP
+ * 记录用户最后一次成功登录的IP地址
+ */
private String lastLoginIp;
-
+
+ /**
+ * 用户关联的角色列表
+ * 采用懒加载方式获取用户的所有角色
+ */
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "auth_user_role",
@@ -59,35 +131,73 @@ public class User {
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private List roles;
-
+
+ /**
+ * 创建时间
+ * 记录用户账号的创建时间
+ */
private LocalDateTime createdAt;
-
+
+ /**
+ * 更新时间
+ * 记录用户信息的最后修改时间
+ */
private LocalDateTime updatedAt;
-
+
+ /**
+ * 创建人ID
+ * 记录创建该用户的管理员或系统ID
+ */
private UUID createdBy;
-
+
+ /**
+ * 持久化前回调
+ * 在用户对象首次保存到数据库前自动设置创建时间和更新时间
+ */
@PrePersist
public void prePersist() {
this.createdAt = LocalDateTime.now();
this.updatedAt = LocalDateTime.now();
}
-
+
+ /**
+ * 更新前回调
+ * 在用户对象更新前自动设置更新时间
+ */
@PreUpdate
public void preUpdate() {
this.updatedAt = LocalDateTime.now();
}
-
+
+ /**
+ * 用户状态枚举
+ * 定义用户的三种状态:正常、锁定、禁用
+ */
public enum UserStatus {
+ /** 正常状态 - 用户可以正常登录和使用系统 */
ACTIVE("正常"),
+ /** 锁定状态 - 用户被锁定,暂时无法登录 */
LOCKED("锁定"),
+ /** 禁用状态 - 用户被禁用,无法使用系统 */
DISABLED("禁用");
-
+
+ /** 状态描述 */
private final String desc;
-
+
+ /**
+ * 构造函数
+ *
+ * @param desc 状态描述
+ */
UserStatus(String desc) {
this.desc = desc;
}
-
+
+ /**
+ * 获取状态描述
+ *
+ * @return 状态的中文描述
+ */
public String getDesc() {
return desc;
}
diff --git a/module-auth/src/main/java/com/ether/pms/auth/entity/UserProject.java b/module-auth/src/main/java/com/ether/pms/auth/entity/UserProject.java
index d5761c2..e16078c 100644
--- a/module-auth/src/main/java/com/ether/pms/auth/entity/UserProject.java
+++ b/module-auth/src/main/java/com/ether/pms/auth/entity/UserProject.java
@@ -5,31 +5,66 @@ import lombok.Data;
import java.time.LocalDateTime;
import java.util.UUID;
+/**
+ * 用户项目关联实体类
+ *
+ * 表示用户与项目之间的关联关系,记录用户在特定项目中的角色和加入时间。
+ *
+ * 一个用户可以关联多个项目,一个项目也可以关联多个用户,形成多对多关系。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
@Entity
@Table(name = "user_project")
@Data
public class UserProject {
+ /**
+ * 关联记录唯一标识符
+ * 采用UUID策略自动生成
+ */
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;
+ /**
+ * 用户ID
+ * 关联的用户唯一标识符
+ */
@Column(name = "user_id", nullable = false)
private UUID userId;
+ /**
+ * 项目ID
+ * 关联的项目唯一标识符
+ */
@Column(name = "project_id", nullable = false)
private UUID projectId;
+ /**
+ * 在项目中的角色
+ * 记录用户在关联项目中的角色,默认值为"member"(成员)
+ */
@Column(name = "role_in_project", nullable = false)
private String roleInProject = "member";
+ /**
+ * 加入时间
+ * 记录用户加入项目的时间,默认为当前时间
+ */
@Column(name = "joined_at", nullable = false)
private LocalDateTime joinedAt = LocalDateTime.now();
+ /**
+ * 持久化前回调
+ * 在关联记录首次保存前,如果加入时间为空则设置为当前时间
+ */
@PrePersist
public void prePersist() {
if (this.joinedAt == null) {
this.joinedAt = LocalDateTime.now();
}
}
-}
+}
\ No newline at end of file
diff --git a/module-auth/src/main/java/com/ether/pms/auth/repository/DeptRepository.java b/module-auth/src/main/java/com/ether/pms/auth/repository/DeptRepository.java
new file mode 100644
index 0000000..ccee90e
--- /dev/null
+++ b/module-auth/src/main/java/com/ether/pms/auth/repository/DeptRepository.java
@@ -0,0 +1,97 @@
+package com.ether.pms.auth.repository;
+
+import com.ether.pms.auth.entity.Dept;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+/**
+ * 部门数据访问层接口
+ *
+ * 提供部门数据的持久化操作,继承Spring Data JPA的JpaRepository接口。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
+@Repository
+public interface DeptRepository extends JpaRepository {
+
+ /**
+ * 查询顶级部门列表
+ *
+ * 查询没有上级部门的部门,即树形结构的根节点。
+ *
+ * @return 顶级部门列表
+ */
+ List findByParentIdIsNullOrderBySortOrder();
+
+ /**
+ * 根据父部门ID查询子部门列表
+ *
+ * @param parentId 父部门唯一标识符
+ * @return 该父部门下的所有子部门列表
+ */
+ List findByParentIdOrderBySortOrder(UUID parentId);
+
+ /**
+ * 根据部门编码查询部门
+ *
+ * @param deptCode 部门编码
+ * @return 包含部门的Optional对象
+ */
+ Optional findByDeptCode(String deptCode);
+
+ /**
+ * 根据部门类型查询部门列表
+ *
+ * @param deptType 部门类型
+ * @return 该类型的所有部门列表
+ */
+ List findByDeptTypeOrderBySortOrder(String deptType);
+
+ /**
+ * 查询所有启用的部门
+ *
+ * @return 所有状态为ACTIVE的部门
+ */
+ List findByStatusOrderBySortOrder(String status);
+
+ /**
+ * 根据部门负责人查询部门
+ *
+ * @param leaderId 负责人用户ID
+ * @return 该负责人管理的部门列表
+ */
+ List findByLeaderId(UUID leaderId);
+
+ /**
+ * 查询所有部门(用于树形结构构建)
+ *
+ * @return 所有部门列表
+ */
+ @Query("SELECT d FROM Dept d ORDER BY d.sortOrder")
+ List findAllForTree();
+
+ /**
+ * 检查部门编码是否存在
+ *
+ * @param deptCode 部门编码
+ * @return 存在返回true
+ */
+ boolean existsByDeptCode(String deptCode);
+
+ /**
+ * 根据ID查询部门及其默认角色
+ *
+ * @param id 部门ID
+ * @return 部门的默认角色编码
+ */
+ @Query("SELECT d.defaultRoleCode FROM Dept d WHERE d.id = :id")
+ String findDefaultRoleCodeById(@Param("id") UUID id);
+}
diff --git a/module-auth/src/main/java/com/ether/pms/auth/repository/EnterpriseUserRepository.java b/module-auth/src/main/java/com/ether/pms/auth/repository/EnterpriseUserRepository.java
new file mode 100644
index 0000000..d7e4595
--- /dev/null
+++ b/module-auth/src/main/java/com/ether/pms/auth/repository/EnterpriseUserRepository.java
@@ -0,0 +1,38 @@
+package com.ether.pms.auth.repository;
+
+import com.ether.pms.auth.entity.EnterpriseUser;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+/**
+ * 企业用户数据访问层接口
+ *
+ * 提供企业用户数据的持久化操作,继承Spring Data JPA的JpaRepository接口。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
+@Repository
+public interface EnterpriseUserRepository extends JpaRepository {
+
+ /**
+ * 根据用户ID查询企业用户
+ *
+ * @param userId 用户唯一标识符
+ * @return 包含企业用户的Optional对象
+ */
+ Optional findByUserId(UUID userId);
+
+ /**
+ * 根据部门ID查询企业用户列表
+ *
+ * @param deptId 部门唯一标识符
+ * @return 该部门下的所有企业用户列表
+ */
+ List findByDeptId(UUID deptId);
+}
diff --git a/module-auth/src/main/java/com/ether/pms/auth/repository/PermissionRepository.java b/module-auth/src/main/java/com/ether/pms/auth/repository/PermissionRepository.java
index 265a817..7490d48 100644
--- a/module-auth/src/main/java/com/ether/pms/auth/repository/PermissionRepository.java
+++ b/module-auth/src/main/java/com/ether/pms/auth/repository/PermissionRepository.java
@@ -6,12 +6,46 @@ import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.UUID;
+/**
+ * 权限数据访问层接口
+ *
+ * 提供权限(Permission)实体的数据库操作方法,继承Spring Data JPA的JpaRepository。
+ * 支持按权限类型、父权限代码等条件查询。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
@Repository
public interface PermissionRepository extends JpaRepository {
-
+
+ /**
+ * 根据权限类型查询权限列表
+ *
+ * 按权限类型筛选,如MENU(菜单)、BUTTON(按钮)、API(接口)等。
+ *
+ * @param type 权限类型
+ * @return 该类型的所有权限列表
+ */
List findByType(String type);
-
+
+ /**
+ * 根据父权限代码查询子权限列表
+ *
+ * 用于构建权限树形结构,查找属于某个父权限的所有子权限。
+ *
+ * @param parentCode 父权限代码
+ * @return 该父权限下的所有子权限列表
+ */
List findByParentCode(String parentCode);
-
+
+ /**
+ * 检查权限代码是否存在
+ *
+ * 用于创建权限时的唯一性校验。
+ *
+ * @param code 权限代码
+ * @return 存在返回true,不存在返回false
+ */
boolean existsByCode(String code);
-}
+}
\ No newline at end of file
diff --git a/module-auth/src/main/java/com/ether/pms/auth/repository/ProjectStaffRepository.java b/module-auth/src/main/java/com/ether/pms/auth/repository/ProjectStaffRepository.java
new file mode 100644
index 0000000..6eeaac4
--- /dev/null
+++ b/module-auth/src/main/java/com/ether/pms/auth/repository/ProjectStaffRepository.java
@@ -0,0 +1,86 @@
+package com.ether.pms.auth.repository;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+import com.ether.pms.auth.entity.ProjectStaff;
+
+/**
+ * 项目员工数据访问层接口
+ *
+ * 提供项目员工数据的持久化操作,继承Spring Data JPA的JpaRepository接口。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
+@Repository
+public interface ProjectStaffRepository extends JpaRepository {
+
+ /**
+ * 根据用户ID查询项目员工
+ *
+ * @param userId 用户唯一标识符
+ * @return 包含项目员工的Optional对象
+ */
+ Optional findByUserId(UUID userId);
+
+ /**
+ * 根据用户ID查询所有项目员工记录
+ *
+ * @param userId 用户唯一标识符
+ * @return 该用户的所有项目员工记录列表
+ */
+ List findAllByUserId(UUID userId);
+
+ /**
+ * 根据项目ID查询所有项目员工
+ *
+ * @param projectId 项目唯一标识符
+ * @return 该项目下的所有员工列表
+ */
+ List findByProjectId(UUID projectId);
+
+ /**
+ * 根据项目ID查询所有项目员工(包含角色信息)
+ *
+ * @param projectId 项目唯一标识符
+ * @return 该项目下的所有员工列表(包含角色信息)
+ */
+ @Query("SELECT DISTINCT ps FROM ProjectStaff ps " +
+ "LEFT JOIN FETCH ps.staffRoles sr " +
+ "LEFT JOIN FETCH sr.role " +
+ "LEFT JOIN FETCH ps.user " +
+ "WHERE ps.projectId = :projectId")
+ List findByProjectIdWithRoles(UUID projectId);
+
+ /**
+ * 根据用户ID和项目ID删除项目员工关联
+ *
+ * @param userId 用户唯一标识符
+ * @param projectId 项目唯一标识符
+ */
+ void deleteByUserIdAndProjectId(UUID projectId, UUID userId);
+
+ /**
+ * 根据用户ID和项目ID查询项目员工
+ *
+ * @param userId 用户唯一标识符
+ * @param projectId 项目唯一标识符
+ * @return 包含项目员工的Optional对象
+ */
+ Optional findByUserIdAndProjectId(UUID userId, UUID projectId);
+
+ /**
+ * 根据项目ID统计成员数量
+ *
+ * @param projectId 项目唯一标识符
+ * @return 该项目的成员数量
+ */
+ long countByProjectId(UUID projectId);
+}
diff --git a/module-auth/src/main/java/com/ether/pms/auth/repository/ProjectStaffRoleRepository.java b/module-auth/src/main/java/com/ether/pms/auth/repository/ProjectStaffRoleRepository.java
new file mode 100644
index 0000000..7a244ee
--- /dev/null
+++ b/module-auth/src/main/java/com/ether/pms/auth/repository/ProjectStaffRoleRepository.java
@@ -0,0 +1,37 @@
+package com.ether.pms.auth.repository;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import com.ether.pms.auth.entity.ProjectStaffRole;
+
+@Repository
+public interface ProjectStaffRoleRepository extends JpaRepository {
+
+ /**
+ * 根据员工ID查询所有角色关联
+ *
+ * @param staffId 员工ID
+ * @return 角色关联列表
+ */
+ List findByStaff_Id(UUID staffId);
+
+ /**
+ * 根据员工ID删除所有角色关联
+ *
+ * @param staffId 员工ID
+ */
+ void deleteByStaff_Id(UUID staffId);
+
+ /**
+ * 检查是否存在指定员工和角色的关联
+ *
+ * @param staffId 员工ID
+ * @param roleId 角色ID
+ * @return 是否存在
+ */
+ boolean existsByStaff_IdAndRole_Id(UUID staffId, UUID roleId);
+}
\ No newline at end of file
diff --git a/module-auth/src/main/java/com/ether/pms/auth/repository/ResidentRepository.java b/module-auth/src/main/java/com/ether/pms/auth/repository/ResidentRepository.java
new file mode 100644
index 0000000..d068764
--- /dev/null
+++ b/module-auth/src/main/java/com/ether/pms/auth/repository/ResidentRepository.java
@@ -0,0 +1,38 @@
+package com.ether.pms.auth.repository;
+
+import com.ether.pms.auth.entity.Resident;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+/**
+ * 住户数据访问层接口
+ *
+ * 提供住户数据的持久化操作,继承Spring Data JPA的JpaRepository接口。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
+@Repository
+public interface ResidentRepository extends JpaRepository {
+
+ /**
+ * 根据用户ID查询住户
+ *
+ * @param userId 用户唯一标识符
+ * @return 包含住户的Optional对象
+ */
+ Optional findByUserId(UUID userId);
+
+ /**
+ * 根据认证状态查询住户列表
+ *
+ * @param status 认证状态
+ * @return 该状态下的所有住户列表
+ */
+ List findByVerificationStatus(String status);
+}
diff --git a/module-auth/src/main/java/com/ether/pms/auth/repository/ResidentSpaceRepository.java b/module-auth/src/main/java/com/ether/pms/auth/repository/ResidentSpaceRepository.java
new file mode 100644
index 0000000..afa46ee
--- /dev/null
+++ b/module-auth/src/main/java/com/ether/pms/auth/repository/ResidentSpaceRepository.java
@@ -0,0 +1,47 @@
+package com.ether.pms.auth.repository;
+
+import com.ether.pms.auth.entity.ResidentSpace;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+/**
+ * 住户房屋关联数据访问层接口
+ *
+ * 提供住户房屋关联数据的持久化操作,继承Spring Data JPA的JpaRepository接口。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
+@Repository
+public interface ResidentSpaceRepository extends JpaRepository {
+
+ /**
+ * 根据用户ID查询所有住户房屋关联
+ *
+ * @param userId 用户唯一标识符
+ * @return 该用户的所有住户房屋关联列表
+ */
+ List findByUserId(UUID userId);
+
+ /**
+ * 根据房屋ID查询所有住户房屋关联
+ *
+ * @param spaceId 房屋唯一标识符
+ * @return 该房屋的所有住户关联列表
+ */
+ List findBySpaceId(UUID spaceId);
+
+ /**
+ * 根据用户ID和房屋ID查询住户房屋关联
+ *
+ * @param userId 用户唯一标识符
+ * @param spaceId 房屋唯一标识符
+ * @return 包含住户房屋关联的Optional对象
+ */
+ Optional findByUserIdAndSpaceId(UUID userId, UUID spaceId);
+}
diff --git a/module-auth/src/main/java/com/ether/pms/auth/repository/RoleRepository.java b/module-auth/src/main/java/com/ether/pms/auth/repository/RoleRepository.java
index bafb3c9..0de9cb5 100644
--- a/module-auth/src/main/java/com/ether/pms/auth/repository/RoleRepository.java
+++ b/module-auth/src/main/java/com/ether/pms/auth/repository/RoleRepository.java
@@ -8,17 +8,68 @@ import java.util.List;
import java.util.Optional;
import java.util.UUID;
+/**
+ * 角色数据访问层接口
+ *
+ * 提供角色(Role)实体的数据库操作方法,继承Spring Data JPA的JpaRepository。
+ * 支持按角色代码、项目ID、类型等条件查询,以及带权限信息的复杂查询。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
@Repository
public interface RoleRepository extends JpaRepository {
+ /**
+ * 根据角色代码查询角色
+ *
+ * 角色代码在系统中唯一,用于精确查找特定角色。
+ *
+ * @param code 角色代码
+ * @return 角色对象(如果存在)
+ */
Optional findByCode(String code);
+ /**
+ * 检查角色代码是否存在
+ *
+ * 用于创建角色时的唯一性校验。
+ *
+ * @param code 角色代码
+ * @return 存在返回true,不存在返回false
+ */
boolean existsByCode(String code);
+ /**
+ * 根据项目ID查询角色列表
+ *
+ * 获取指定项目下的所有角色,通常用于项目级别的角色筛选。
+ *
+ * @param projectId 项目ID
+ * @return 该项目下的角色列表
+ */
List findByProjectId(String projectId);
+ /**
+ * 根据角色类型查询角色列表
+ *
+ * 按角色类型(如系统级、项目级、部门级)筛选角色。
+ *
+ * @param type 角色类型枚举
+ * @return 该类型的所有角色列表
+ */
List findByType(Role.RoleType type);
+ /**
+ * 根据角色ID查询角色及其关联的权限信息
+ *
+ * 使用EntityGraph eagerly加载permissions关联数据,
+ * 避免N+1查询问题,提升查询性能。
+ *
+ * @param id 角色ID
+ * @return 包含权限信息的角色对象(如果存在)
+ */
@EntityGraph(attributePaths = {"permissions"})
Optional findWithPermissionsById(UUID id);
-}
+}
\ No newline at end of file
diff --git a/module-auth/src/main/java/com/ether/pms/auth/repository/SpaceRepository.java b/module-auth/src/main/java/com/ether/pms/auth/repository/SpaceRepository.java
new file mode 100644
index 0000000..cd340cb
--- /dev/null
+++ b/module-auth/src/main/java/com/ether/pms/auth/repository/SpaceRepository.java
@@ -0,0 +1,41 @@
+package com.ether.pms.auth.repository;
+
+import com.ether.pms.auth.entity.Space;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+/**
+ * 房屋空间数据访问层接口
+ *
+ * 提供房屋空间数据的持久化操作,继承Spring Data JPA的JpaRepository接口。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
+@Repository
+public interface SpaceRepository extends JpaRepository {
+
+ /**
+ * 根据项目ID查询所有房屋空间
+ *
+ * @param projectId 项目唯一标识符
+ * @return 该项目下的所有房屋空间列表
+ */
+ List findByProjectId(UUID projectId);
+
+ /**
+ * 根据项目ID、楼栋、单元和房号查询房屋空间
+ *
+ * @param projectId 项目唯一标识符
+ * @param building 楼栋
+ * @param unit 单元
+ * @param roomNo 房号
+ * @return 包含房屋空间的Optional对象
+ */
+ Optional findByProjectIdAndBuildingAndUnitAndRoomNo(UUID projectId, String building, String unit, String roomNo);
+}
diff --git a/module-auth/src/main/java/com/ether/pms/auth/repository/SysConfigRepository.java b/module-auth/src/main/java/com/ether/pms/auth/repository/SysConfigRepository.java
index c187e29..0edb8a1 100644
--- a/module-auth/src/main/java/com/ether/pms/auth/repository/SysConfigRepository.java
+++ b/module-auth/src/main/java/com/ether/pms/auth/repository/SysConfigRepository.java
@@ -7,8 +7,21 @@ import org.springframework.stereotype.Repository;
import java.util.Optional;
import java.util.UUID;
+/**
+ * 系统配置数据访问层
+ * 提供对 sys_config 表的 CRUD 操作
+ *
+ * @author Ether Team
+ * @since 1.0.0
+ */
@Repository
public interface SysConfigRepository extends JpaRepository {
+ /**
+ * 根据配置键查询配置项
+ *
+ * @param configKey 配置键,如:property_company_name
+ * @return 配置项 Optional 包装
+ */
Optional findByConfigKey(String configKey);
}
diff --git a/module-auth/src/main/java/com/ether/pms/auth/repository/UserProjectRepository.java b/module-auth/src/main/java/com/ether/pms/auth/repository/UserProjectRepository.java
index bca1003..ee73234 100644
--- a/module-auth/src/main/java/com/ether/pms/auth/repository/UserProjectRepository.java
+++ b/module-auth/src/main/java/com/ether/pms/auth/repository/UserProjectRepository.java
@@ -10,19 +10,85 @@ import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.UUID;
+/**
+ * 用户项目关联数据访问层接口
+ *
+ * 提供用户与项目关联关系的持久化操作,继承Spring Data JPA的JpaRepository接口。
+ *
+ * 支持用户项目关系查询、分页、批量操作等功能。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
@Repository
public interface UserProjectRepository extends JpaRepository {
+ /**
+ * 根据用户ID查询该用户关联的所有项目
+ *
+ * 返回指定用户参与的所有项目关联记录列表。
+ *
+ * @param userId 用户唯一标识符
+ * @return 该用户关联的所有项目列表
+ */
List findByUserId(UUID userId);
+ /**
+ * 根据项目ID查询该项目的所有关联用户
+ *
+ * 返回参与指定项目的所有用户关联记录列表。
+ *
+ * @param projectId 项目唯一标识符
+ * @return 该项目关联的所有用户列表
+ */
List findByProjectId(UUID projectId);
+ /**
+ * 根据项目ID分页查询该项目的所有关联用户
+ *
+ * 支持分页展示项目成员列表。
+ *
+ * @param projectId 项目唯一标识符
+ * @param pageable 分页参数,包含页码和每页大小
+ * @return 分页的用户项目关联列表
+ */
Page findByProjectId(UUID projectId, Pageable pageable);
+ /**
+ * 根据用户ID查询该用户关联的所有项目ID
+ *
+ * 仅返回项目ID列表,用于快速判断用户参与的项目。
+ *
+ * @param userId 用户唯一标识符
+ * @return 该用户关联的所有项目ID列表
+ */
@Query("SELECT up.projectId FROM UserProject up WHERE up.userId = :userId")
List findProjectIdsByUserId(@Param("userId") UUID userId);
+ /**
+ * 检查用户与项目的关联是否存在
+ *
+ * 用于判断用户是否参与了指定项目。
+ *
+ * @param userId 用户唯一标识符
+ * @param projectId 项目唯一标识符
+ * @return 存在返回true,不存在返回false
+ */
boolean existsByUserIdAndProjectId(UUID userId, UUID projectId);
+ /**
+ * 删除用户与项目的关联
+ *
+ * 根据用户ID和项目ID删除关联记录,用于用户退出项目或移除项目成员。
+ *
+ * @param userId 用户唯一标识符
+ * @param projectId 项目唯一标识符
+ */
void deleteByUserIdAndProjectId(UUID userId, UUID projectId);
-}
+
+ /**
+ * 统计项目下的成员数量
+ */
+ long countByProjectId(UUID projectId);
+}
\ No newline at end of file
diff --git a/module-auth/src/main/java/com/ether/pms/auth/repository/UserRepository.java b/module-auth/src/main/java/com/ether/pms/auth/repository/UserRepository.java
index d831b40..ec68913 100644
--- a/module-auth/src/main/java/com/ether/pms/auth/repository/UserRepository.java
+++ b/module-auth/src/main/java/com/ether/pms/auth/repository/UserRepository.java
@@ -9,24 +9,121 @@ import java.util.List;
import java.util.Optional;
import java.util.UUID;
+/**
+ * 用户数据访问层接口
+ *
+ * 提供用户数据的持久化操作,继承Spring Data JPA的JpaRepository接口。
+ *
+ * 包含用户查询、角色关联查询等数据库操作方法。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
@Repository
public interface UserRepository extends JpaRepository {
+ /**
+ * 根据用户名查询用户
+ *
+ * 最基础的按用户名查询方法,返回Optional包装的用户对象。
+ *
+ * @param username 用户名
+ * @return 包含用户的Optional对象,如果不存在则为空
+ */
Optional findByUsername(String username);
+ /**
+ * 根据用户名查询用户及其关联的角色
+ *
+ * 使用LEFT JOIN FETCH预加载用户的角色信息,避免N+1查询问题。
+ *
+ * @param username 用户名
+ * @return 包含用户及其角色的Optional对象
+ */
@Query("SELECT u FROM User u LEFT JOIN FETCH u.roles WHERE u.username = :username")
Optional findByUsernameWithRoles(@Param("username") String username);
+ /**
+ * 查询所有用户及其关联的角色
+ *
+ * 一次性加载所有用户及其角色信息,适用于管理后台用户列表。
+ *
+ * @return 包含所有用户及其角色的列表
+ */
@Query("SELECT u FROM User u LEFT JOIN FETCH u.roles")
List findAllWithRoles();
+ /**
+ * 根据ID查询用户及其关联的角色
+ *
+ * 使用LEFT JOIN FETCH预加载用户的角色信息。
+ *
+ * @param id 用户唯一标识符
+ * @return 包含用户及其角色的Optional对象
+ */
@Query("SELECT u FROM User u LEFT JOIN FETCH u.roles WHERE u.id = :id")
Optional findByIdWithRoles(@Param("id") UUID id);
+ /**
+ * 根据角色ID查询所有拥有该角色的用户
+ *
+ * 用于查询具有特定角色的所有用户列表。
+ *
+ * @param roleId 角色唯一标识符
+ * @return 拥有该角色的所有用户列表
+ */
@Query("SELECT u FROM User u JOIN u.roles r WHERE r.id = :roleId")
List findByRoleId(@Param("roleId") UUID roleId);
+ /**
+ * 检查用户名是否存在
+ *
+ * 用于用户注册时验证用户名唯一性。
+ *
+ * @param username 用户名
+ * @return 存在返回true,不存在返回false
+ */
boolean existsByUsername(String username);
+ /**
+ * 检查手机号是否存在
+ *
+ * 用于用户注册或更新时验证手机号唯一性。
+ *
+ * @param phone 手机号码
+ * @return 存在返回true,不存在返回false
+ */
boolean existsByPhone(String phone);
-}
+
+ /**
+ * 根据用户类型查询用户列表
+ *
+ * 用于查询特定类型的用户,如ENTERPRISE、PROJECT_STAFF等。
+ *
+ * @param userType 用户类型
+ * @return 该类型的所有用户列表
+ */
+ List findByUserType(String userType);
+
+ /**
+ * 根据部门ID查询用户列表
+ *
+ * 用于查询属于特定部门的所有用户。
+ *
+ * @param deptId 部门唯一标识符
+ * @return 该部门下的所有用户列表
+ */
+ List findByDeptId(UUID deptId);
+
+ /**
+ * 根据项目ID查询项目员工
+ *
+ * 通过关联ProjectStaff表查询属于指定项目的所有员工用户。
+ *
+ * @param projectId 项目唯一标识符
+ * @return该项目下的所有员工用户列表
+ */
+ @Query("SELECT u FROM User u JOIN ProjectStaff ps ON u.id = ps.userId WHERE ps.projectId = :projectId")
+ List findProjectStaffsByProjectId(@Param("projectId") UUID projectId);
+}
\ No newline at end of file
diff --git a/module-auth/src/main/java/com/ether/pms/auth/service/DeptService.java b/module-auth/src/main/java/com/ether/pms/auth/service/DeptService.java
new file mode 100644
index 0000000..f36b34f
--- /dev/null
+++ b/module-auth/src/main/java/com/ether/pms/auth/service/DeptService.java
@@ -0,0 +1,154 @@
+package com.ether.pms.auth.service;
+
+import com.ether.pms.auth.entity.Dept;
+import com.ether.pms.auth.entity.User;
+import com.ether.pms.auth.repository.DeptRepository;
+import com.ether.pms.auth.repository.UserRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+/**
+ * 部门服务层
+ *
+ * 提供部门相关的业务逻辑处理,包括部门树查询、部门CRUD、部门员工查询等功能。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
+@Service
+@RequiredArgsConstructor
+public class DeptService {
+
+ private final DeptRepository deptRepository;
+ private final UserRepository userRepository;
+
+ /**
+ * 获取部门树
+ *
+ * 返回所有部门的列表,支持前端构建树形结构。
+ *
+ * @return 所有部门的列表
+ */
+ public List getDeptTree() {
+ return deptRepository.findAllForTree();
+ }
+
+ /**
+ * 获取所有启用的部门列表
+ *
+ * @return 启用的部门列表
+ */
+ public List getActiveDepts() {
+ return deptRepository.findByStatusOrderBySortOrder("ACTIVE");
+ }
+
+ /**
+ * 根据ID获取部门
+ *
+ * @param id 部门ID
+ * @return 部门对象
+ */
+ public Optional getById(UUID id) {
+ return deptRepository.findById(id);
+ }
+
+ /**
+ * 获取部门及下属员工
+ *
+ * 根据部门ID查询该部门下的所有员工用户。
+ *
+ * @param deptId 部门唯一标识符
+ * @return 该部门下的所有员工用户列表
+ */
+ public List getDeptEmployees(UUID deptId) {
+ return userRepository.findByDeptId(deptId);
+ }
+
+ /**
+ * 创建部门
+ *
+ * @param dept 待创建的部门对象
+ * @return 创建成功的部门对象
+ */
+ @Transactional
+ public Dept createDept(Dept dept) {
+ if (dept.getSortOrder() == null) {
+ dept.setSortOrder(0);
+ }
+ if (dept.getStatus() == null) {
+ dept.setStatus("ACTIVE");
+ }
+ if (dept.getDeptType() == null) {
+ dept.setDeptType("ADMIN");
+ }
+ return deptRepository.save(dept);
+ }
+
+ /**
+ * 更新部门
+ *
+ * @param id 部门ID
+ * @param dept 更新后的部门信息
+ * @return 更新后的部门对象
+ */
+ @Transactional
+ public Dept updateDept(UUID id, Dept dept) {
+ Dept existing = deptRepository.findById(id)
+ .orElseThrow(() -> new IllegalArgumentException("部门不存在: " + id));
+
+ existing.setDeptName(dept.getDeptName());
+ existing.setDeptCode(dept.getDeptCode());
+ existing.setParentId(dept.getParentId());
+ existing.setDeptType(dept.getDeptType());
+ existing.setDefaultRoleCode(dept.getDefaultRoleCode());
+ existing.setLeaderId(dept.getLeaderId());
+ existing.setSortOrder(dept.getSortOrder());
+ existing.setStatus(dept.getStatus());
+
+ return deptRepository.save(existing);
+ }
+
+ /**
+ * 删除部门
+ *
+ * @param id 部门ID
+ */
+ @Transactional
+ public void deleteDept(UUID id) {
+ Dept dept = deptRepository.findById(id)
+ .orElseThrow(() -> new IllegalArgumentException("部门不存在: " + id));
+
+ List children = deptRepository.findByParentIdOrderBySortOrder(id);
+ if (!children.isEmpty()) {
+ throw new IllegalStateException("请先删除子部门");
+ }
+
+ deptRepository.delete(dept);
+ }
+
+ /**
+ * 根据部门类型查询部门
+ *
+ * @param deptType 部门类型
+ * @return 该类型的部门列表
+ */
+ public List getByType(String deptType) {
+ return deptRepository.findByDeptTypeOrderBySortOrder(deptType);
+ }
+
+ /**
+ * 检查部门编码是否存在
+ *
+ * @param deptCode 部门编码
+ * @return 存在返回true
+ */
+ public boolean existsByCode(String deptCode) {
+ return deptRepository.existsByDeptCode(deptCode);
+ }
+}
diff --git a/module-auth/src/main/java/com/ether/pms/auth/service/LoginService.java b/module-auth/src/main/java/com/ether/pms/auth/service/LoginService.java
index c356095..bdf0eee 100644
--- a/module-auth/src/main/java/com/ether/pms/auth/service/LoginService.java
+++ b/module-auth/src/main/java/com/ether/pms/auth/service/LoginService.java
@@ -1,6 +1,8 @@
package com.ether.pms.auth.service;
+import com.ether.pms.auth.entity.ProjectStaff;
import com.ether.pms.auth.entity.User;
+import com.ether.pms.auth.repository.ProjectStaffRepository;
import com.ether.pms.auth.repository.UserRepository;
import com.ether.pms.auth.util.JwtTokenProvider;
import com.ether.pms.common.BusinessException;
@@ -9,57 +11,72 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
+import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class LoginService {
-
+
private final UserRepository userRepository;
+ private final ProjectStaffRepository projectStaffRepository;
private final JwtTokenProvider jwtTokenProvider;
private final PasswordService passwordService;
private final LoginAttemptService loginAttemptService;
-
+
@Transactional
public Map login(String username, String password, String ip) {
if (loginAttemptService.isLockedOut(username)) {
throw new BusinessException(ErrorCode.AUTH_002);
}
-
+
User user = userRepository.findByUsernameWithRoles(username).orElse(null);
-
+
if (user == null || !passwordService.matches(password, user.getPassword())) {
if (user != null) {
loginAttemptService.recordFailure(username);
}
throw new BusinessException(ErrorCode.AUTH_001);
}
-
+
if (user.getStatus() == User.UserStatus.LOCKED) {
throw new BusinessException(ErrorCode.AUTH_002);
}
if (user.getStatus() == User.UserStatus.DISABLED) {
throw new BusinessException(ErrorCode.AUTH_003);
}
-
+
loginAttemptService.recordSuccess(username);
-
- Map claims = new HashMap<>();
+
+ Set allRoles = new HashSet<>();
if (user.getRoles() != null) {
- claims.put("roles", user.getRoles().stream()
- .map(r -> r.getCode())
- .toList());
+ allRoles.addAll(user.getRoles().stream()
+ .map(r -> r.getCode())
+ .toList());
}
-
+
+ List projectStaffs = projectStaffRepository.findAllByUserId(user.getId());
+ for (ProjectStaff staff : projectStaffs) {
+ if (staff.getStaffRoles() != null) {
+ allRoles.addAll(staff.getStaffRoles().stream()
+ .filter(sr -> sr.getRole() != null)
+ .map(sr -> sr.getRole().getCode())
+ .toList());
+ }
+ }
+
+ Map claims = new HashMap<>();
+ claims.put("roles", new ArrayList<>(allRoles));
+
String token = jwtTokenProvider.generateToken(user.getId(), user.getUsername(), claims);
-
+
Map result = new HashMap<>();
result.put("token", token);
result.put("userId", user.getId());
result.put("username", user.getUsername());
result.put("realName", user.getRealName());
-
+ result.put("roles", new ArrayList<>(allRoles));
+
return result;
}
}
diff --git a/module-auth/src/main/java/com/ether/pms/auth/service/PasswordService.java b/module-auth/src/main/java/com/ether/pms/auth/service/PasswordService.java
index d2fa31e..1d12240 100644
--- a/module-auth/src/main/java/com/ether/pms/auth/service/PasswordService.java
+++ b/module-auth/src/main/java/com/ether/pms/auth/service/PasswordService.java
@@ -44,15 +44,15 @@ public class PasswordService {
throw new IllegalArgumentException("密码长度必须在" + minLength + "-" + maxLength + "位之间");
}
- if (requireUppercase && !containsAny(password, 'A', 'Z')) {
+ if (requireUppercase && !Pattern.compile("[A-Z]").matcher(password).find()) {
throw new IllegalArgumentException("密码必须包含大写字母");
}
-
- if (requireLowercase && !containsAny(password, 'a', 'z')) {
+
+ if (requireLowercase && !Pattern.compile("[a-z]").matcher(password).find()) {
throw new IllegalArgumentException("密码必须包含小写字母");
}
- if (requireDigit && !containsAny(password, '0', '9')) {
+ if (requireDigit && !Pattern.compile("[0-9]").matcher(password).find()) {
throw new IllegalArgumentException("密码必须包含数字");
}
diff --git a/module-auth/src/main/java/com/ether/pms/auth/service/PermissionService.java b/module-auth/src/main/java/com/ether/pms/auth/service/PermissionService.java
index 1588010..e5b71c2 100644
--- a/module-auth/src/main/java/com/ether/pms/auth/service/PermissionService.java
+++ b/module-auth/src/main/java/com/ether/pms/auth/service/PermissionService.java
@@ -11,33 +11,91 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.UUID;
+/**
+ * 权限业务逻辑服务类
+ *
+ * 提供权限(Permission)相关的业务操作,包括权限的增删改查、类型筛选、菜单权限获取等功能。
+ * 所有写操作均支持事务管理,确保数据一致性。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
@Service
@RequiredArgsConstructor
public class PermissionService {
-
+
+ /** 权限数据访问仓库 */
private final PermissionRepository permissionRepository;
-
+
+ /**
+ * 查询所有权限
+ *
+ * @return 所有权限的列表
+ */
public List findAll() {
return permissionRepository.findAll();
}
-
+
+ /**
+ * 根据权限ID查询权限
+ *
+ * 如果权限不存在,抛出PERMISSION_002业务异常。
+ *
+ * @param id 权限ID
+ * @return 权限对象
+ * @throws BusinessException 如果权限不存在
+ */
public Permission findById(UUID id) {
return permissionRepository.findById(id)
.orElseThrow(() -> new BusinessException(ErrorCode.PERMISSION_002));
}
-
+
+ /**
+ * 根据权限类型查询权限列表
+ *
+ * 按权限类型筛选,如MENU、BUTTON、API等。
+ *
+ * @param type 权限类型
+ * @return 该类型的所有权限列表
+ */
public List findByType(String type) {
return permissionRepository.findByType(type);
}
-
+
+ /**
+ * 根据父权限代码查询子权限列表
+ *
+ * 用于获取某个父权限下的所有子权限,构建权限树。
+ *
+ * @param parentCode 父权限代码
+ * @return 该父权限下的所有子权限列表
+ */
public List findByParentCode(String parentCode) {
return permissionRepository.findByParentCode(parentCode);
}
-
+
+ /**
+ * 查询所有菜单类型权限
+ *
+ * 获取type为MENU的所有权限,通常用于前端菜单渲染。
+ *
+ * @return 所有菜单权限列表
+ */
public List findMenuPermissions() {
return permissionRepository.findByType("MENU");
}
-
+
+ /**
+ * 创建新权限
+ *
+ * 如果权限代码已存在,抛出PERMISSION_001业务异常。
+ * 创建时会自动设置创建时间和更新时间。
+ *
+ * @param permission 要创建的权限对象
+ * @return 创建后的权限对象(包含数据库生成的主键)
+ * @throws BusinessException 如果权限代码已存在
+ */
@Transactional
public Permission create(Permission permission) {
if (permissionRepository.existsByCode(permission.getCode())) {
@@ -45,11 +103,22 @@ public class PermissionService {
}
return permissionRepository.save(permission);
}
-
+
+ /**
+ * 更新权限信息
+ *
+ * 仅更新传入参数中非空的字段,保持其他字段不变。
+ * 如果权限不存在,抛出PERMISSION_002业务异常。
+ *
+ * @param id 要更新的权限ID
+ * @param permission 包含新数据的权限对象
+ * @return 更新后的权限对象
+ * @throws BusinessException 如果权限不存在
+ */
@Transactional
public Permission update(UUID id, Permission permission) {
Permission existing = findById(id);
-
+
if (permission.getName() != null) {
existing.setName(permission.getName());
}
@@ -71,12 +140,19 @@ public class PermissionService {
if (permission.getSortOrder() != null) {
existing.setSortOrder(permission.getSortOrder());
}
-
+
return permissionRepository.save(existing);
}
-
+
+ /**
+ * 删除权限
+ *
+ * 根据权限ID删除权限记录。
+ *
+ * @param id 要删除的权限ID
+ */
@Transactional
public void delete(UUID id) {
permissionRepository.deleteById(id);
}
-}
+}
\ No newline at end of file
diff --git a/module-auth/src/main/java/com/ether/pms/auth/service/RoleService.java b/module-auth/src/main/java/com/ether/pms/auth/service/RoleService.java
index e8e2bb0..71f39ea 100644
--- a/module-auth/src/main/java/com/ether/pms/auth/service/RoleService.java
+++ b/module-auth/src/main/java/com/ether/pms/auth/service/RoleService.java
@@ -15,32 +15,88 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.UUID;
+/**
+ * 角色业务逻辑服务类
+ *
+ * 提供角色(Role)相关的业务操作,包括角色的增删改查、权限分配、用户关联等功能。
+ * 所有操作均支持事务管理,确保数据一致性。
+ *
+ * @author Ether开发团队
+ * @version 1.0.0
+ * @since 2024-01-01
+ */
@Service
@RequiredArgsConstructor
public class RoleService {
-
+
+ /** 角色数据访问仓库 */
private final RoleRepository roleRepository;
+
+ /** 权限数据访问仓库 */
private final PermissionRepository permissionRepository;
+
+ /** 用户数据访问仓库 */
private final UserRepository userRepository;
-
+
+ /**
+ * 查询所有角色
+ *
+ * @return 所有角色的列表
+ */
public List findAll() {
return roleRepository.findAll();
}
-
+
+ /**
+ * 根据角色ID查询角色
+ *
+ * 如果角色不存在,抛出ROLE_002业务异常。
+ *
+ * @param id 角色ID
+ * @return 角色对象
+ * @throws BusinessException 如果角色不存在
+ */
public Role findById(UUID id) {
return roleRepository.findById(id)
.orElseThrow(() -> new BusinessException(ErrorCode.ROLE_002));
}
-
+
+ /**
+ * 根据角色代码查询角色
+ *
+ * 如果角色不存在,抛出ROLE_002业务异常。
+ *
+ * @param code 角色代码
+ * @return 角色对象
+ * @throws BusinessException 如果角色不存在
+ */
public Role findByCode(String code) {
return roleRepository.findByCode(code)
.orElseThrow(() -> new BusinessException(ErrorCode.ROLE_002));
}
-
+
+ /**
+ * 根据项目ID查询角色列表
+ *
+ * 获取指定项目下的所有角色。
+ *
+ * @param projectId 项目ID
+ * @return 该项目下的角色列表
+ */
public List findByProjectId(String projectId) {
return roleRepository.findByProjectId(projectId);
}
-
+
+ /**
+ * 创建新角色
+ *
+ * 如果角色代码已存在,抛出ROLE_001业务异常。
+ * 创建时会自动设置创建时间和更新时间。
+ *
+ * @param role 要创建的角色对象
+ * @return 创建后的角色对象(包含数据库生成的主键)
+ * @throws BusinessException 如果角色代码已存在
+ */
@Transactional
public Role create(Role role) {
if (roleRepository.existsByCode(role.getCode())) {
@@ -48,11 +104,22 @@ public class RoleService {
}
return roleRepository.save(role);
}
-
+
+ /**
+ * 更新角色信息
+ *
+ * 仅更新传入参数中非空的字段,保持其他字段不变。
+ * 如果角色不存在,抛出ROLE_002业务异常。
+ *
+ * @param id 要更新的角色ID
+ * @param role 包含新数据的角色对象
+ * @return 更新后的角色对象
+ * @throws BusinessException 如果角色不存在
+ */
@Transactional
public Role update(UUID id, Role role) {
Role existing = findById(id);
-
+
if (role.getName() != null) {
existing.setName(role.getName());
}
@@ -71,10 +138,20 @@ public class RoleService {
if (role.getStatus() != null) {
existing.setStatus(role.getStatus());
}
-
+
return roleRepository.save(existing);
}
-
+
+ /**
+ * 为角色分配权限
+ *
+ * 替换角色原有的所有权限为新分配的权限列表。
+ * 如果角色或权限不存在,抛出相应业务异常。
+ *
+ * @param roleId 角色ID
+ * @param permissionIds 要分配的权限ID列表
+ * @throws BusinessException 如果角色或权限不存在
+ */
@Transactional
public void assignPermissions(UUID roleId, List permissionIds) {
Role role = findById(roleId);
@@ -82,19 +159,61 @@ public class RoleService {
role.setPermissions(permissions);
roleRepository.save(role);
}
-
+
+ /**
+ * 删除角色
+ *
+ *