/** * 自然写互动课堂教学管理云平台软件 V1.0 * * 数据模型 - 用户实体 * 对应数据表:user (MySQL) * 支持教师/学生/管理员/家长四种角色 */ package com.writech.cloud.model; import javax.persistence.*; import java.time.LocalDateTime; /** * 用户主表实体类 * * RBAC角色定义: * - admin:系统管理员(学校/用户/设备管理全权限) * - teacher:教师(班级管理/作业发布/学情查看) * - student:学生(作业查看/学习数据查询) * - parent:家长(子女学情查看/消息接收) * * 安全设计: * - 手机号使用AES-256加密存储(encryptedPhone字段) * - 密码使用BCrypt哈希存储 * - 身份证号等敏感信息加密后存储 */ @Entity @Table(name = "user", indexes = { @Index(name = "idx_phone", columnList = "encryptedPhone"), @Index(name = "idx_school_role", columnList = "schoolId, role"), @Index(name = "idx_wechat", columnList = "wechatOpenId") }) public class User { /** 用户唯一ID(UUID格式) */ @Id @Column(length = 32) private String id; /** 用户姓名 */ @Column(nullable = false, length = 64) private String name; /** 手机号(明文,仅用于内部处理,不直接存储) */ @Transient private String phone; /** 加密后的手机号(AES-256-CBC加密存储) */ @Column(length = 128) private String encryptedPhone; /** 密码哈希(BCrypt,强度因子10) */ @Column(length = 128) private String passwordHash; /** 用户角色:admin/teacher/student/parent */ @Column(nullable = false, length = 16) private String role; /** 所属学校ID */ @Column(length = 32) private String schoolId; /** 所属学校名称(冗余存储,减少关联查询) */ @Column(length = 128) private String schoolName; /** 头像URL */ @Column(length = 256) private String avatar; /** 微信OpenID(第三方登录绑定) */ @Column(length = 64) private String wechatOpenId; /** 钉钉用户ID(第三方登录绑定) */ @Column(length = 64) private String dingtalkUserId; /** 账户状态:1=正常, 0=禁用, -1=注销 */ @Column(nullable = false) private int status = 1; /** Token版本号(用于使所有旧Token失效) */ @Column(nullable = false) private int tokenVersion = 0; /** 账户创建时间 */ @Column(nullable = false) private LocalDateTime createTime; /** 最后登录时间 */ private LocalDateTime lastLoginTime; /** 最后登录IP */ @Column(length = 45) private String lastLoginIp; // ==================== Getter / Setter ==================== public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getEncryptedPhone() { return encryptedPhone; } public void setEncryptedPhone(String encryptedPhone) { this.encryptedPhone = encryptedPhone; } public String getPasswordHash() { return passwordHash; } public void setPasswordHash(String passwordHash) { this.passwordHash = passwordHash; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } public String getSchoolId() { return schoolId; } public void setSchoolId(String schoolId) { this.schoolId = schoolId; } public String getSchoolName() { return schoolName; } public void setSchoolName(String schoolName) { this.schoolName = schoolName; } public String getAvatar() { return avatar; } public void setAvatar(String avatar) { this.avatar = avatar; } public String getWechatOpenId() { return wechatOpenId; } public void setWechatOpenId(String wechatOpenId) { this.wechatOpenId = wechatOpenId; } public String getDingtalkUserId() { return dingtalkUserId; } public void setDingtalkUserId(String dingtalkUserId) { this.dingtalkUserId = dingtalkUserId; } public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public int getTokenVersion() { return tokenVersion; } public void setTokenVersion(int tokenVersion) { this.tokenVersion = tokenVersion; } public LocalDateTime getCreateTime() { return createTime; } public void setCreateTime(LocalDateTime createTime) { this.createTime = createTime; } public LocalDateTime getLastLoginTime() { return lastLoginTime; } public void setLastLoginTime(LocalDateTime lastLoginTime) { this.lastLoginTime = lastLoginTime; } public String getLastLoginIp() { return lastLoginIp; } public void setLastLoginIp(String lastLoginIp) { this.lastLoginIp = lastLoginIp; } @Override public String toString() { return "User{id='" + id + "', name='" + name + "', role='" + role + "', schoolId='" + schoolId + "', status=" + status + "}"; } }