init: UserBaseService (backend + deploy + scripts)
ci-userbase-service / build-and-push (push) Successful in 40s
ci-userbase-service / build-and-push (push) Successful in 40s
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
package com.yunhai.userbase.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author chenx
|
||||
* @date 2026/7/15 15:53
|
||||
* @description
|
||||
*/
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "app_category")
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
|
||||
public class AppCategory extends BaseEntity {
|
||||
//类别名称
|
||||
@Column(name = "name", nullable = false)
|
||||
private String name;
|
||||
|
||||
@Column(name = "sort_no")
|
||||
private Integer sortNo;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.yunhai.userbase.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author chenx
|
||||
* @date 2026/7/22
|
||||
* @description 应用模块(树形,逻辑外键,最深5层)<br>
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@Entity
|
||||
@Table(
|
||||
name = "app_module",
|
||||
indexes = {
|
||||
@Index(name = "idx_app_module_app", columnList = "app_id"),
|
||||
@Index(name = "idx_app_module_parent", columnList = "parent_id")
|
||||
},
|
||||
uniqueConstraints = {
|
||||
@UniqueConstraint(name = "uk_app_module_custom", columnNames = {"app_id", "custom_id"})
|
||||
}
|
||||
)
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
|
||||
public class AppModule extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 所属应用ID(逻辑外键 → ApplicationInfo.id),创建后不可改。<br>
|
||||
*/
|
||||
@NotNull
|
||||
@Column(name = "app_id", nullable = false, updatable = false)
|
||||
private Integer appId;
|
||||
|
||||
/**
|
||||
* 父模块ID(逻辑外键 → AppModule.id);根模块为 null。<br>
|
||||
*/
|
||||
@Column(name = "parent_id")
|
||||
private Integer parentId;
|
||||
|
||||
/**
|
||||
* 模块名称。<br>
|
||||
*/
|
||||
@NotBlank
|
||||
@Column(name = "name", nullable = false)
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 自定义ID(应用内唯一,业务编码,如 "user-mgmt")。<br>
|
||||
*/
|
||||
@NotBlank
|
||||
@Column(name = "custom_id", nullable = false, length = 64)
|
||||
private String customId;
|
||||
|
||||
/**
|
||||
* 模块路径(前端路由/资源路径,如 "/system/user")。<br>
|
||||
*/
|
||||
@Column(name = "path", length = 255)
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 层级:根=1,子=父+1,上限5(由 Service 校验)。<br>
|
||||
*/
|
||||
@NotNull
|
||||
@Column(name = "level", nullable = false)
|
||||
private Integer level;
|
||||
|
||||
/**
|
||||
* 排序号(沿用 AppCategory 约定)。<br>
|
||||
*/
|
||||
@Column(name = "sort_no")
|
||||
private Integer sortNo;
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.yunhai.userbase.entity;
|
||||
|
||||
import com.yunhai.userbase.common.converter.ListIntegerJsonConverter;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Convert;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Table;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author chenx
|
||||
* @date 2026/7/15 15:53
|
||||
* @description
|
||||
*/
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "application_info")
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
|
||||
public class ApplicationInfo extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 应用名称(页面*必填)
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 应用类型ID
|
||||
*/
|
||||
private Integer categoryId;
|
||||
|
||||
/**
|
||||
* 排序号,仅在同一个应用类型内生效;默认为 null(新增时不赋值)。<br>
|
||||
*/
|
||||
@Column(name = "sort_no")
|
||||
private Integer sortNo;
|
||||
|
||||
/**
|
||||
* 应用描述
|
||||
*/
|
||||
@Column(name = "app_desc", length = 500)
|
||||
private String desc;
|
||||
|
||||
/**
|
||||
* appKey 系统生成唯一标识,整型,从100000起自增。<br>
|
||||
*/
|
||||
@NotNull
|
||||
@Column(name = "app_key", unique = true, nullable = false)
|
||||
private Integer appKey;
|
||||
|
||||
/**
|
||||
* appSecret 密钥,支持重设
|
||||
*/
|
||||
@NotBlank
|
||||
@Column(name = "app_secret", nullable = false, length = 128)
|
||||
private String appSecret;
|
||||
|
||||
//应用前端类型
|
||||
@Convert(converter = ListIntegerJsonConverter.class)
|
||||
// @Column(name = "clients", columnDefinition = "json")
|
||||
@Column(name = "clients", columnDefinition = "TEXT")
|
||||
private List<Integer> clients;
|
||||
|
||||
/**
|
||||
* PC应用访问地址
|
||||
*/
|
||||
@Column(name = "pc_url")
|
||||
private String pcUrl;
|
||||
|
||||
/**
|
||||
* PC应用图标 图片URL
|
||||
*/
|
||||
@Column(name = "pc_icon")
|
||||
private String pcIcon;
|
||||
|
||||
/**
|
||||
* App访问地址(移动端主地址)
|
||||
*/
|
||||
@Column(name = "app_url")
|
||||
private String appUrl;
|
||||
|
||||
/**
|
||||
* App应用图标 图片URL
|
||||
*/
|
||||
@Column(name = "app_icon")
|
||||
private String appIcon;
|
||||
|
||||
/**
|
||||
* 公众号应用地址
|
||||
*/
|
||||
@Column(name = "official_account_url")
|
||||
private String officialAccountUrl;
|
||||
|
||||
/**
|
||||
* 钉钉应用地址
|
||||
*/
|
||||
@Column(name = "dingtalk_url")
|
||||
private String dingtalkUrl;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.yunhai.userbase.entity;
|
||||
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import com.yunhai.userbase.common.listener.UserAuditListener;
|
||||
import com.yunhai.userbase.common.validation.ValidationGroups;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.hibernate.annotations.UpdateTimestamp;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author chenx
|
||||
* @date 2026/7/14 10:46
|
||||
* @description
|
||||
*/
|
||||
|
||||
@MappedSuperclass
|
||||
@Getter
|
||||
@Setter
|
||||
@EntityListeners(UserAuditListener.class)
|
||||
public abstract class BaseEntity implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@NotNull(groups = ValidationGroups.Update.class)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 创建人ID
|
||||
*/
|
||||
@Column(name = "create_user", nullable = false, updatable = false)
|
||||
private Integer createUser;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@CreationTimestamp
|
||||
@Column(name = "create_time", nullable = false, updatable = false)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 更新人ID
|
||||
*/
|
||||
@Column(name = "update_user")
|
||||
private Integer updateUser;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@UpdateTimestamp
|
||||
@Column(name = "update_time")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.yunhai.userbase.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.Table;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author chenx
|
||||
* @date 2026/7/27
|
||||
* @description 应用业务角色。<br>
|
||||
* 普通角色:allAppFlag=false 且 appId 必填;<br>
|
||||
* 全应用角色:allAppFlag=true 且 appId 为空;<br>
|
||||
* 注意:这里的“业务角色”不等同于 {@code sys_user.roles} 对应的系统身份枚举。<br>
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "sys_app_role", indexes = {
|
||||
@Index(name = "idx_app_role_app", columnList = "app_id"),
|
||||
@Index(name = "idx_app_role_all_app", columnList = "all_app_flag"),
|
||||
@Index(name = "idx_app_role_name", columnList = "name")
|
||||
})
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
|
||||
public class SysAppRole extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 角色名称。<br>
|
||||
*/
|
||||
@NotBlank
|
||||
@Column(name = "name", nullable = false, length = 100)
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 所属应用ID(逻辑外键 → ApplicationInfo.id)。<br>
|
||||
* 普通角色必填;全应用角色为空。<br>
|
||||
*/
|
||||
@Column(name = "app_id")
|
||||
private Integer appId;
|
||||
|
||||
/**
|
||||
* 是否全应用角色。<br>
|
||||
* true=可跨应用勾选模块;false=仅能授权所属应用下的模块。<br>
|
||||
*/
|
||||
@NotNull
|
||||
@Column(name = "all_app_flag", nullable = false)
|
||||
private Boolean allAppFlag = Boolean.FALSE;
|
||||
|
||||
/**
|
||||
* 角色备注。<br>
|
||||
*/
|
||||
@Column(name = "remark", length = 500)
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 是否禁用。<br>
|
||||
* 禁用后角色关系可保留,但权限计算时应忽略该角色。<br>
|
||||
*/
|
||||
@NotNull
|
||||
@Column(name = "disabled", nullable = false)
|
||||
private Boolean disabled = Boolean.FALSE;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.yunhai.userbase.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author chenx
|
||||
* @date 2026/7/27
|
||||
* @description 业务角色-模块权限关系表(逻辑外键,无物理 FK)。<br>
|
||||
* 存在记录即代表该角色显式拥有该模块。<br>
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@Entity
|
||||
@Table(
|
||||
name = "sys_app_role_module_rel",
|
||||
indexes = {
|
||||
@Index(name = "idx_app_role_module_role", columnList = "role_id"),
|
||||
@Index(name = "idx_app_role_module_module", columnList = "module_id")
|
||||
},
|
||||
uniqueConstraints = {
|
||||
@UniqueConstraint(name = "uk_app_role_module", columnNames = {"role_id", "module_id"})
|
||||
}
|
||||
)
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
|
||||
public class SysAppRoleModuleRel extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 角色ID(逻辑外键 → SysAppRole.id)。<br>
|
||||
*/
|
||||
@NotNull
|
||||
@Column(name = "role_id", nullable = false)
|
||||
private Integer roleId;
|
||||
|
||||
/**
|
||||
* 模块ID(逻辑外键 → AppModule.id)。<br>
|
||||
*/
|
||||
@NotNull
|
||||
@Column(name = "module_id", nullable = false)
|
||||
private Integer moduleId;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.yunhai.userbase.entity;
|
||||
|
||||
import com.yunhai.userbase.common.converter.GroupTypeEnumConverter;
|
||||
import com.yunhai.userbase.enums.GroupTypeEnum;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author chenx
|
||||
* @date 2026/7/13 22:48
|
||||
* @description 系统节点(组)表
|
||||
*/
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "sys_group")
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
|
||||
public class SysGroup extends BaseEntity {
|
||||
|
||||
private String name;
|
||||
|
||||
@Column(name = "parent_id", nullable = false)
|
||||
private Integer parentId;
|
||||
|
||||
@Column(name = "type")
|
||||
@Convert(converter = GroupTypeEnumConverter.class)
|
||||
private GroupTypeEnum type;
|
||||
|
||||
private Integer sort;
|
||||
|
||||
|
||||
// 一对多反向关联中间表
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "groupId", insertable = false, updatable = false)
|
||||
private List<SysUserGroupRel> userGroupRelList;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.yunhai.userbase.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author chenx
|
||||
* @date 2026/7/23
|
||||
* @description 组应用开通表(逻辑外键,无物理 FK)。<br>
|
||||
* 记录某个组显式开通了哪些应用;仅当本表存在记录时,「组授权」界面右侧才显示该应用。<br>
|
||||
* 开通不继承:子组要使用应用必须自己开通。<br>
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@Entity
|
||||
@Table(
|
||||
name = "sys_group_app_rel",
|
||||
indexes = {
|
||||
@Index(name = "idx_group_app_rel_app", columnList = "app_id")
|
||||
},
|
||||
uniqueConstraints = {
|
||||
@UniqueConstraint(name = "uk_group_app", columnNames = {"group_id", "app_id"})
|
||||
}
|
||||
)
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
|
||||
public class SysGroupAppRel extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 组ID(逻辑外键 → SysGroup.id)。<br>
|
||||
*/
|
||||
@NotNull
|
||||
@Column(name = "group_id", nullable = false)
|
||||
private Integer groupId;
|
||||
|
||||
/**
|
||||
* 应用ID(逻辑外键 → ApplicationInfo.id)。<br>
|
||||
*/
|
||||
@NotNull
|
||||
@Column(name = "app_id", nullable = false)
|
||||
private Integer appId;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.yunhai.userbase.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author chenx
|
||||
* @date 2026/7/23
|
||||
* @description 组模块权限表(逻辑外键,无物理 FK)。<br>
|
||||
* 存在记录即代表该组勾选了该模块;inheritFlag=true 时当前组及其所有子孙组自动继承该模块权限。<br>
|
||||
* 取消勾选时物理删除记录。<br>
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@Entity
|
||||
@Table(
|
||||
name = "sys_group_module_perm",
|
||||
indexes = {
|
||||
@Index(name = "idx_group_module_perm_module", columnList = "module_id")
|
||||
},
|
||||
uniqueConstraints = {
|
||||
@UniqueConstraint(name = "uk_group_module", columnNames = {"group_id", "module_id"})
|
||||
}
|
||||
)
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
|
||||
public class SysGroupModulePerm extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 组ID(逻辑外键 → SysGroup.id)。<br>
|
||||
*/
|
||||
@NotNull
|
||||
@Column(name = "group_id", nullable = false)
|
||||
private Integer groupId;
|
||||
|
||||
/**
|
||||
* 模块ID(逻辑外键 → AppModule.id)。<br>
|
||||
*/
|
||||
@NotNull
|
||||
@Column(name = "module_id", nullable = false)
|
||||
private Integer moduleId;
|
||||
|
||||
/**
|
||||
* 是否子组继承(false=仅本组生效,true=子孙组自动继承),对应 UI「子组继承」勾选框。<br>
|
||||
*/
|
||||
@NotNull
|
||||
@Column(name = "inherit_flag", nullable = false)
|
||||
private Boolean inheritFlag = Boolean.FALSE;
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package com.yunhai.userbase.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.Table;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
|
||||
/**
|
||||
* 系统操作日志实体。<br>
|
||||
* 记录用户的关键操作(增删改查),便于审计与问题排查。<br>
|
||||
*
|
||||
* @author chenx
|
||||
* @date 2026/7/28
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "sys_operation_log", indexes = {
|
||||
@Index(name = "idx_create_time", columnList = "create_time"),
|
||||
@Index(name = "idx_user_time", columnList = "user_id, create_time"),
|
||||
@Index(name = "idx_uri_time", columnList = "request_uri, create_time"),
|
||||
@Index(name = "idx_level_time", columnList = "log_level, create_time"),
|
||||
@Index(name = "idx_ip_time", columnList = "request_ip, create_time")
|
||||
})
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
|
||||
public class SysOperationLog implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@EqualsAndHashCode.Include
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 日志级别:1-重要(删除) 2-次要(新增/编辑) 3-一般(查询)
|
||||
*/
|
||||
@Column(name = "log_level", nullable = false, columnDefinition = "TINYINT")
|
||||
private Integer logLevel;
|
||||
|
||||
/**
|
||||
* 操作用户ID
|
||||
*/
|
||||
@Column(name = "user_id", nullable = false)
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 操作用户名
|
||||
*/
|
||||
@Column(name = "username", nullable = false, length = 64)
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 请求IP
|
||||
*/
|
||||
@Column(name = "request_ip", nullable = false, length = 64)
|
||||
private String requestIp;
|
||||
|
||||
/**
|
||||
* 请求路径
|
||||
*/
|
||||
@Column(name = "request_uri", nullable = false, length = 512)
|
||||
private String requestUri;
|
||||
|
||||
/**
|
||||
* 请求方法 GET/POST/PUT/DELETE
|
||||
*/
|
||||
@Column(name = "request_method", nullable = false, length = 16)
|
||||
private String requestMethod;
|
||||
|
||||
/**
|
||||
* 操作类型 DELETE/CREATE/UPDATE/QUERY
|
||||
*/
|
||||
@Column(name = "operation_type", nullable = false, length = 32)
|
||||
private String operationType;
|
||||
|
||||
/**
|
||||
* 类名.方法名
|
||||
*/
|
||||
@Column(name = "class_method", nullable = false, length = 512)
|
||||
private String classMethod;
|
||||
|
||||
/**
|
||||
* 请求参数JSON
|
||||
*/
|
||||
@Column(name = "request_params", columnDefinition = "TEXT")
|
||||
private String requestParams;
|
||||
|
||||
/**
|
||||
* 响应结果(GZIP压缩)
|
||||
*/
|
||||
@Column(name = "response_data", columnDefinition = "MEDIUMBLOB")
|
||||
private byte[] responseData;
|
||||
|
||||
/**
|
||||
* HTTP状态码
|
||||
*/
|
||||
@Column(name = "status_code", nullable = false)
|
||||
private Integer statusCode;
|
||||
|
||||
/**
|
||||
* 耗时(ms)
|
||||
*/
|
||||
@Column(name = "cost_time", nullable = false)
|
||||
private Long costTime;
|
||||
|
||||
/**
|
||||
* 浏览器UA
|
||||
*/
|
||||
@Column(name = "user_agent", length = 512)
|
||||
private String userAgent;
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
@Column(name = "error_msg", columnDefinition = "TEXT")
|
||||
private String errorMsg;
|
||||
|
||||
/**
|
||||
* 操作时间
|
||||
*/
|
||||
@CreationTimestamp
|
||||
@Column(name = "create_time", nullable = false, updatable = false, columnDefinition = "DATETIME(3)")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.yunhai.userbase.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.yunhai.userbase.common.converter.ListIntegerJsonConverter;
|
||||
import com.yunhai.userbase.common.converter.StatusEnumConverter;
|
||||
import com.yunhai.userbase.common.converter.UserTypeEnumConverter;
|
||||
import com.yunhai.userbase.enums.StatusEnum;
|
||||
import com.yunhai.userbase.enums.UserTypeEnum;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author chenx
|
||||
* @date 2026/7/13 23:30
|
||||
* @description 系统用户表
|
||||
*/
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@Entity
|
||||
@Table(name = "sys_user")
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
|
||||
public class SysUser extends BaseEntity {
|
||||
|
||||
@Column(name = "username", nullable = false, unique = true)
|
||||
private String account;
|
||||
private String password;
|
||||
//出生日期
|
||||
private LocalDate birthday;
|
||||
|
||||
@JsonProperty("name")
|
||||
private String realName;
|
||||
|
||||
private String phone;
|
||||
|
||||
private String idcard;
|
||||
|
||||
//头像
|
||||
private String profilePicture;
|
||||
|
||||
/**
|
||||
* 角色列表,存储为 MySQL JSON 类型,读取时自动映射为 List<Long>
|
||||
* 取值对应 {@link com.yunhai.userbase.enums.SysRoleEnum} 的 key,例如 [1,2,3]
|
||||
*/
|
||||
@Convert(converter = ListIntegerJsonConverter.class)
|
||||
// @Column(name = "roles", columnDefinition = "json")
|
||||
@Column(name = "roles",columnDefinition = "TEXT")
|
||||
private List<Integer> roles;
|
||||
|
||||
// 一对多:关联用户分组中间表,实现多对多业务
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "userId", insertable = false, updatable = false)
|
||||
private List<SysUserGroupRel> userGroupRelList;
|
||||
|
||||
// 是否禁用:存储为 StatusEnum(0=正常/未禁用,1=禁用),与 GroupTypeEnum 同机制;默认启用
|
||||
@Convert(converter = StatusEnumConverter.class)
|
||||
private StatusEnum disabled;
|
||||
//是否过期
|
||||
private Boolean expired=false;
|
||||
|
||||
/**
|
||||
* 用户类型:0=普通用户,1=超级管理员,2=学校管理员(见 UserTypeEnum)。
|
||||
* 由应用层根据用户账号/角色推导:内置超级管理员账号固定为 1,其余账号含 ADMIN(7) 角色则为 2,默认 0。
|
||||
*/
|
||||
@Convert(converter = UserTypeEnumConverter.class)
|
||||
private UserTypeEnum type;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.yunhai.userbase.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Index;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @author chenx
|
||||
* @date 2026/7/27
|
||||
* @description 用户-业务角色关系表(逻辑外键,无物理 FK)。<br>
|
||||
* 一个用户可绑定多个业务角色;一个角色也可绑定多个用户。<br>
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
@Entity
|
||||
@Table(
|
||||
name = "sys_user_app_role_rel",
|
||||
indexes = {
|
||||
@Index(name = "idx_user_app_role_user", columnList = "user_id"),
|
||||
@Index(name = "idx_user_app_role_role", columnList = "role_id")
|
||||
},
|
||||
uniqueConstraints = {
|
||||
@UniqueConstraint(name = "uk_user_app_role", columnNames = {"user_id", "role_id"})
|
||||
}
|
||||
)
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
|
||||
public class SysUserAppRoleRel extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 用户ID(逻辑外键 → SysUser.id)。<br>
|
||||
*/
|
||||
@NotNull
|
||||
@Column(name = "user_id", nullable = false)
|
||||
private Integer userId;
|
||||
|
||||
/**
|
||||
* 角色ID(逻辑外键 → SysAppRole.id)。<br>
|
||||
*/
|
||||
@NotNull
|
||||
@Column(name = "role_id", nullable = false)
|
||||
private Integer roleId;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.yunhai.userbase.entity;
|
||||
|
||||
import com.yunhai.userbase.common.validation.ValidationGroups;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author chenx
|
||||
* @date 2026/7/15 15:05
|
||||
* @description 用户当前角色
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Entity
|
||||
@Table(
|
||||
name = "sys_user_current_role",
|
||||
uniqueConstraints = @UniqueConstraint(columnNames = {"userId"}),
|
||||
indexes = {@Index(columnList = "userId")}
|
||||
)
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
|
||||
public class SysUserCurrentRole {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@NotNull(groups = ValidationGroups.Update.class)
|
||||
private Integer id;
|
||||
|
||||
/**
|
||||
* 用户ID,一对一唯一
|
||||
*/
|
||||
@Column(nullable = false)
|
||||
private Integer userId;
|
||||
|
||||
/**
|
||||
* 用户切换选中的学校ID(根级group)
|
||||
*/
|
||||
private Integer schoolId;
|
||||
/**
|
||||
* 用户切换后生效角色ID
|
||||
*/
|
||||
private Integer roleId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.yunhai.userbase.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author chenx
|
||||
* @date 2026/7/15 15:03
|
||||
* @description 组用户多对多关联表
|
||||
*/
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Entity
|
||||
@Table(name = "sys_user_group_rel")
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
|
||||
public class SysUserGroupRel {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@NotNull(groups = Update.class)
|
||||
private Integer id;
|
||||
/** 用户ID */
|
||||
private Integer userId;
|
||||
/** 分组ID */
|
||||
private Integer groupId;
|
||||
/** 是否主归属 1=本职主学校/部门 0=兼职兼任 */
|
||||
private Integer isMain;
|
||||
|
||||
private LocalDateTime createTime;
|
||||
|
||||
// 关联用户,仅查询,不维护外键
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "userId", referencedColumnName = "id", insertable = false, updatable = false)
|
||||
private SysUser user;
|
||||
|
||||
// 关联分组,仅查询,不维护外键
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "groupId", referencedColumnName = "id", insertable = false, updatable = false)
|
||||
private SysGroup group;
|
||||
|
||||
|
||||
public @interface Update {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user