From fe3da4b1f85e845a1a6062d2e6ae6e30aea104e9 Mon Sep 17 00:00:00 2001 From: bruce Date: Mon, 10 Feb 2025 16:40:47 +0800 Subject: [PATCH] =?UTF-8?q?v0.01=20=E5=90=8E=E7=AB=AF=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 29 ++- .../com/bruce/sams/Constant/HttpStatus.java | 94 ++++++++ .../sams/Controller/LoginController.java | 35 +++ .../bruce/sams/Controller/UserController.java | 18 ++ .../java/com/bruce/sams/Entity/SysUser.java | 151 ++++++++++++ .../bruce/sams/Exception/CustomException.java | 11 + .../User/IncorrectPasswordException.java | 12 + .../InsufficientPermissionsException.java | 12 + .../Exception/User/InvalidInputException.java | 12 + .../Exception/User/UserNotFoundException.java | 12 + .../java/com/bruce/sams/Utils/AjaxResult.java | 215 ++++++++++++++++++ .../com/bruce/sams/Utils/PasswordEncoder.java | 33 +++ .../java/com/bruce/sams/Utils/TokenUtil.java | 87 +++++++ .../com/bruce/sams/mapper/SysUserMapper.java | 19 ++ .../bruce/sams/service/SysLoginService.java | 11 + .../bruce/sams/service/SysUserService.java | 20 ++ .../service/impl/SysLoginServiceImpl.java | 49 ++++ .../sams/service/impl/SysUserServiceImpl.java | 71 ++++++ src/main/resources/application.properties | 1 - src/main/resources/application.yml | 10 + .../com/bruce/sams/mapper/SysUserMapper.xml | 30 +++ 21 files changed, 926 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/bruce/sams/Constant/HttpStatus.java create mode 100644 src/main/java/com/bruce/sams/Controller/LoginController.java create mode 100644 src/main/java/com/bruce/sams/Controller/UserController.java create mode 100644 src/main/java/com/bruce/sams/Entity/SysUser.java create mode 100644 src/main/java/com/bruce/sams/Exception/CustomException.java create mode 100644 src/main/java/com/bruce/sams/Exception/User/IncorrectPasswordException.java create mode 100644 src/main/java/com/bruce/sams/Exception/User/InsufficientPermissionsException.java create mode 100644 src/main/java/com/bruce/sams/Exception/User/InvalidInputException.java create mode 100644 src/main/java/com/bruce/sams/Exception/User/UserNotFoundException.java create mode 100644 src/main/java/com/bruce/sams/Utils/AjaxResult.java create mode 100644 src/main/java/com/bruce/sams/Utils/PasswordEncoder.java create mode 100644 src/main/java/com/bruce/sams/Utils/TokenUtil.java create mode 100644 src/main/java/com/bruce/sams/mapper/SysUserMapper.java create mode 100644 src/main/java/com/bruce/sams/service/SysLoginService.java create mode 100644 src/main/java/com/bruce/sams/service/SysUserService.java create mode 100644 src/main/java/com/bruce/sams/service/impl/SysLoginServiceImpl.java create mode 100644 src/main/java/com/bruce/sams/service/impl/SysUserServiceImpl.java delete mode 100644 src/main/resources/application.properties create mode 100644 src/main/resources/application.yml create mode 100644 src/main/resources/com/bruce/sams/mapper/SysUserMapper.xml diff --git a/pom.xml b/pom.xml index 94e7fea8..10ba91db 100644 --- a/pom.xml +++ b/pom.xml @@ -38,12 +38,12 @@ org.springframework.boot spring-boot-starter-web - - org.mybatis.spring.boot - mybatis-spring-boot-starter - 3.0.4 - + + com.baomidou + mybatis-plus-spring-boot3-starter + 3.5.10.1 + com.mysql mysql-connector-j @@ -70,6 +70,25 @@ spring-security-test test + + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime + diff --git a/src/main/java/com/bruce/sams/Constant/HttpStatus.java b/src/main/java/com/bruce/sams/Constant/HttpStatus.java new file mode 100644 index 00000000..7560e0ef --- /dev/null +++ b/src/main/java/com/bruce/sams/Constant/HttpStatus.java @@ -0,0 +1,94 @@ +package com.bruce.sams.Constant; + +/** + * 返回状态码 + * + * @author ruoyi + */ +public class HttpStatus +{ + /** + * 操作成功 + */ + public static final int SUCCESS = 200; + + /** + * 对象创建成功 + */ + public static final int CREATED = 201; + + /** + * 请求已经被接受 + */ + public static final int ACCEPTED = 202; + + /** + * 操作已经执行成功,但是没有返回数据 + */ + public static final int NO_CONTENT = 204; + + /** + * 资源已被移除 + */ + public static final int MOVED_PERM = 301; + + /** + * 重定向 + */ + public static final int SEE_OTHER = 303; + + /** + * 资源没有被修改 + */ + public static final int NOT_MODIFIED = 304; + + /** + * 参数列表错误(缺少,格式不匹配) + */ + public static final int BAD_REQUEST = 400; + + /** + * 未授权 + */ + public static final int UNAUTHORIZED = 401; + + /** + * 访问受限,授权过期 + */ + public static final int FORBIDDEN = 403; + + /** + * 资源,服务未找到 + */ + public static final int NOT_FOUND = 404; + + /** + * 不允许的http方法 + */ + public static final int BAD_METHOD = 405; + + /** + * 资源冲突,或者资源被锁 + */ + public static final int CONFLICT = 409; + + /** + * 不支持的数据,媒体类型 + */ + public static final int UNSUPPORTED_TYPE = 415; + + /** + * 系统内部错误 + */ + public static final int ERROR = 500; + + /** + * 接口未实现 + */ + public static final int NOT_IMPLEMENTED = 501; + + /** + * 系统警告消息 + */ + public static final int WARN = 601; +} diff --git a/src/main/java/com/bruce/sams/Controller/LoginController.java b/src/main/java/com/bruce/sams/Controller/LoginController.java new file mode 100644 index 00000000..820c47f5 --- /dev/null +++ b/src/main/java/com/bruce/sams/Controller/LoginController.java @@ -0,0 +1,35 @@ +package com.bruce.sams.Controller; + +import com.bruce.sams.service.SysLoginService; +import com.bruce.sams.Utils.AjaxResult; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/login") +public class LoginController { + + @Autowired + private SysLoginService sysLoginService; + + /** + * 用户登录 + * + * @param username 用户名 + * @param password 密码 + * @return AjaxResult 包含登录状态和token + */ + @PostMapping + public AjaxResult login(@RequestParam String username, @RequestParam String password) { + try { + // 调用登录服务,生成Token + String token = sysLoginService.login(username, password); + + // 返回成功的响应,并包含生成的Token + return AjaxResult.success("登录成功", token); + } catch (Exception e) { + // 如果捕获到异常,返回错误信息 + return AjaxResult.error("登录失败: " + e.getMessage()); + } + } +} diff --git a/src/main/java/com/bruce/sams/Controller/UserController.java b/src/main/java/com/bruce/sams/Controller/UserController.java new file mode 100644 index 00000000..a5921e63 --- /dev/null +++ b/src/main/java/com/bruce/sams/Controller/UserController.java @@ -0,0 +1,18 @@ +package com.bruce.sams.Controller; + +import com.bruce.sams.service.SysUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/user") +public class UserController { + @Autowired + private SysUserService userService; + + public Object addUesr(){ + + return null; + } +} diff --git a/src/main/java/com/bruce/sams/Entity/SysUser.java b/src/main/java/com/bruce/sams/Entity/SysUser.java new file mode 100644 index 00000000..7b36d1ee --- /dev/null +++ b/src/main/java/com/bruce/sams/Entity/SysUser.java @@ -0,0 +1,151 @@ +package com.bruce.sams.Entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * 系统用户表 + * @TableName sys_user + */ +@TableName(value ="sys_user") +@Data +public class SysUser { + /** + * 用户ID + */ + @TableId(type = IdType.AUTO) + private Long userId; + + /** + * 用户角色 + */ + private Long roleId; + + /** + * 用户昵称 + */ + private String nickName; + + /** + * 真实姓名 + */ + private String userName; + + /** + * 密码 + */ + private String passwd; + + /** + * 学号/教职工号 + */ + private String schoolId; + + /** + * 所属院系 + */ + private Long collegeId; + + /** + * 用户邮箱 + */ + private String email; + + /** + * 手机号码 + */ + private String phonenumber; + + /** + * 用户性别(0男 1女 2未知) + */ + private String sex; + + /** + * 头像地址 + */ + private String avatar; + + /** + * 帐号状态(0正常 1停用) + */ + private String status; + + /** + * 备注 + */ + private String remark; + + @Override + public boolean equals(Object that) { + if (this == that) { + return true; + } + if (that == null) { + return false; + } + if (getClass() != that.getClass()) { + return false; + } + SysUser other = (SysUser) that; + return (this.getUserId() == null ? other.getUserId() == null : this.getUserId().equals(other.getUserId())) + && (this.getRoleId() == null ? other.getRoleId() == null : this.getRoleId().equals(other.getRoleId())) + && (this.getNickName() == null ? other.getNickName() == null : this.getNickName().equals(other.getNickName())) + && (this.getUserName() == null ? other.getUserName() == null : this.getUserName().equals(other.getUserName())) + && (this.getPasswd() == null ? other.getPasswd() == null : this.getPasswd().equals(other.getPasswd())) + && (this.getSchoolId() == null ? other.getSchoolId() == null : this.getSchoolId().equals(other.getSchoolId())) + && (this.getCollegeId() == null ? other.getCollegeId() == null : this.getCollegeId().equals(other.getCollegeId())) + && (this.getEmail() == null ? other.getEmail() == null : this.getEmail().equals(other.getEmail())) + && (this.getPhonenumber() == null ? other.getPhonenumber() == null : this.getPhonenumber().equals(other.getPhonenumber())) + && (this.getSex() == null ? other.getSex() == null : this.getSex().equals(other.getSex())) + && (this.getAvatar() == null ? other.getAvatar() == null : this.getAvatar().equals(other.getAvatar())) + && (this.getStatus() == null ? other.getStatus() == null : this.getStatus().equals(other.getStatus())) + && (this.getRemark() == null ? other.getRemark() == null : this.getRemark().equals(other.getRemark())); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((getUserId() == null) ? 0 : getUserId().hashCode()); + result = prime * result + ((getRoleId() == null) ? 0 : getRoleId().hashCode()); + result = prime * result + ((getNickName() == null) ? 0 : getNickName().hashCode()); + result = prime * result + ((getUserName() == null) ? 0 : getUserName().hashCode()); + result = prime * result + ((getPasswd() == null) ? 0 : getPasswd().hashCode()); + result = prime * result + ((getSchoolId() == null) ? 0 : getSchoolId().hashCode()); + result = prime * result + ((getCollegeId() == null) ? 0 : getCollegeId().hashCode()); + result = prime * result + ((getEmail() == null) ? 0 : getEmail().hashCode()); + result = prime * result + ((getPhonenumber() == null) ? 0 : getPhonenumber().hashCode()); + result = prime * result + ((getSex() == null) ? 0 : getSex().hashCode()); + result = prime * result + ((getAvatar() == null) ? 0 : getAvatar().hashCode()); + result = prime * result + ((getStatus() == null) ? 0 : getStatus().hashCode()); + result = prime * result + ((getRemark() == null) ? 0 : getRemark().hashCode()); + return result; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName()); + sb.append(" ["); + sb.append("Hash = ").append(hashCode()); + sb.append(", userId=").append(userId); + sb.append(", roleId=").append(roleId); + sb.append(", nickName=").append(nickName); + sb.append(", userName=").append(userName); + sb.append(", passwd=").append(passwd); + sb.append(", schoolId=").append(schoolId); + sb.append(", collegeId=").append(collegeId); + sb.append(", email=").append(email); + sb.append(", phonenumber=").append(phonenumber); + sb.append(", sex=").append(sex); + sb.append(", avatar=").append(avatar); + sb.append(", status=").append(status); + sb.append(", remark=").append(remark); + sb.append("]"); + return sb.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/bruce/sams/Exception/CustomException.java b/src/main/java/com/bruce/sams/Exception/CustomException.java new file mode 100644 index 00000000..d3a17c90 --- /dev/null +++ b/src/main/java/com/bruce/sams/Exception/CustomException.java @@ -0,0 +1,11 @@ +package com.bruce.sams.Exception; + +public class CustomException extends RuntimeException { + public CustomException(String message) { + super(message); + } + + public CustomException(String message, Throwable cause) { + super(message, cause); + } +} \ No newline at end of file diff --git a/src/main/java/com/bruce/sams/Exception/User/IncorrectPasswordException.java b/src/main/java/com/bruce/sams/Exception/User/IncorrectPasswordException.java new file mode 100644 index 00000000..e2fb59d1 --- /dev/null +++ b/src/main/java/com/bruce/sams/Exception/User/IncorrectPasswordException.java @@ -0,0 +1,12 @@ +package com.bruce.sams.Exception.User; + +import com.bruce.sams.Exception.CustomException; + +/** + * 密码错误异常 + */ +public class IncorrectPasswordException extends CustomException { + public IncorrectPasswordException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/com/bruce/sams/Exception/User/InsufficientPermissionsException.java b/src/main/java/com/bruce/sams/Exception/User/InsufficientPermissionsException.java new file mode 100644 index 00000000..3010ab37 --- /dev/null +++ b/src/main/java/com/bruce/sams/Exception/User/InsufficientPermissionsException.java @@ -0,0 +1,12 @@ +package com.bruce.sams.Exception.User; + +import com.bruce.sams.Exception.CustomException; + +/** + * 权限不足异常 + */ +public class InsufficientPermissionsException extends CustomException { + public InsufficientPermissionsException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/com/bruce/sams/Exception/User/InvalidInputException.java b/src/main/java/com/bruce/sams/Exception/User/InvalidInputException.java new file mode 100644 index 00000000..97f6ba05 --- /dev/null +++ b/src/main/java/com/bruce/sams/Exception/User/InvalidInputException.java @@ -0,0 +1,12 @@ +package com.bruce.sams.Exception.User; + +import com.bruce.sams.Exception.CustomException; + +/** + * 无效输入异常 + */ +public class InvalidInputException extends CustomException { + public InvalidInputException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/com/bruce/sams/Exception/User/UserNotFoundException.java b/src/main/java/com/bruce/sams/Exception/User/UserNotFoundException.java new file mode 100644 index 00000000..960acd79 --- /dev/null +++ b/src/main/java/com/bruce/sams/Exception/User/UserNotFoundException.java @@ -0,0 +1,12 @@ +package com.bruce.sams.Exception.User; + +import com.bruce.sams.Exception.CustomException; + +/** + * 用户不存在 + */ +public class UserNotFoundException extends CustomException { + public UserNotFoundException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/com/bruce/sams/Utils/AjaxResult.java b/src/main/java/com/bruce/sams/Utils/AjaxResult.java new file mode 100644 index 00000000..c49ddc55 --- /dev/null +++ b/src/main/java/com/bruce/sams/Utils/AjaxResult.java @@ -0,0 +1,215 @@ +package com.bruce.sams.Utils; + +import com.bruce.sams.Constant.HttpStatus; + +import java.util.HashMap; +import java.util.Objects; + +/** + * 操作消息提醒 + * + * @author ruoyi + */ +public class AjaxResult extends HashMap +{ + private static final long serialVersionUID = 1L; + + /** 状态码 */ + public static final String CODE_TAG = "code"; + + /** 返回内容 */ + public static final String MSG_TAG = "msg"; + + /** 数据对象 */ + public static final String DATA_TAG = "data"; + + /** + * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。 + */ + public AjaxResult() + { + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + */ + public AjaxResult(int code, String msg) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + * @param data 数据对象 + */ + public AjaxResult(int code, String msg, Object data) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + if(data!=null){ + super.put(DATA_TAG, data); + } + } + + /** + * 返回成功消息 + * + * @return 成功消息 + */ + public static AjaxResult success() + { + return AjaxResult.success("操作成功"); + } + + /** + * 返回成功数据 + * + * @return 成功消息 + */ + public static AjaxResult success(Object data) + { + return AjaxResult.success("操作成功", data); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @return 成功消息 + */ + public static AjaxResult success(String msg) + { + return AjaxResult.success(msg, null); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 成功消息 + */ + public static AjaxResult success(String msg, Object data) + { + return new AjaxResult(HttpStatus.SUCCESS, msg, data); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @return 警告消息 + */ + public static AjaxResult warn(String msg) + { + return AjaxResult.warn(msg, null); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 警告消息 + */ + public static AjaxResult warn(String msg, Object data) + { + return new AjaxResult(HttpStatus.WARN, msg, data); + } + + /** + * 返回错误消息 + * + * @return 错误消息 + */ + public static AjaxResult error() + { + return AjaxResult.error("操作失败"); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @return 错误消息 + */ + public static AjaxResult error(String msg) + { + return AjaxResult.error(msg, null); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 错误消息 + */ + public static AjaxResult error(String msg, Object data) + { + return new AjaxResult(HttpStatus.ERROR, msg, data); + } + + /** + * 返回错误消息 + * + * @param code 状态码 + * @param msg 返回内容 + * @return 错误消息 + */ + public static AjaxResult error(int code, String msg) + { + return new AjaxResult(code, msg, null); + } + + /** + * 是否为成功消息 + * + * @return 结果 + */ + public boolean isSuccess() + { + return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG)); + } + + /** + * 是否为警告消息 + * + * @return 结果 + */ + public boolean isWarn() + { + return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG)); + } + + /** + * 是否为错误消息 + * + * @return 结果 + */ + public boolean isError() + { + return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG)); + } + + /** + * 方便链式调用 + * + * @param key 键 + * @param value 值 + * @return 数据对象 + */ + @Override + public AjaxResult put(String key, Object value) + { + super.put(key, value); + return this; + } +} diff --git a/src/main/java/com/bruce/sams/Utils/PasswordEncoder.java b/src/main/java/com/bruce/sams/Utils/PasswordEncoder.java new file mode 100644 index 00000000..96398b60 --- /dev/null +++ b/src/main/java/com/bruce/sams/Utils/PasswordEncoder.java @@ -0,0 +1,33 @@ +package com.bruce.sams.Utils; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.crypto.bcrypt.BCrypt; +import org.springframework.stereotype.Component; + +@Component +public class PasswordEncoder { + + // 从配置文件中读取 bcrypt 的强度(默认强度为12),用于生成盐值。 + @Value("${bcrypt.strength:12}") // 如果没有设置,则默认为12 + private int bcryptStrength; + + + /** + * 密码加密 + * @param rawPassword 原始密码 + * @return 密文字符串 + */ + public String encode(String rawPassword) { + return BCrypt.hashpw(rawPassword, BCrypt.gensalt(bcryptStrength)); + } + + /** + * 密码验证 + * @param rawPassword 匹配 + * @param encodedPassword 存储密文 + * @return 匹配返回 True,否则返回 False + */ + public Boolean matches(String rawPassword, String encodedPassword) { + return BCrypt.checkpw(rawPassword, encodedPassword); + } +} \ No newline at end of file diff --git a/src/main/java/com/bruce/sams/Utils/TokenUtil.java b/src/main/java/com/bruce/sams/Utils/TokenUtil.java new file mode 100644 index 00000000..8b2f8f32 --- /dev/null +++ b/src/main/java/com/bruce/sams/Utils/TokenUtil.java @@ -0,0 +1,87 @@ +package com.bruce.sams.Utils; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; +import org.springframework.stereotype.Component; + +import java.security.Key; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +public class TokenUtil { + + // 密钥,用于签名和验证Token + private static final Key SECRET_KEY = Keys.secretKeyFor(SignatureAlgorithm.HS256); + + // Token过期时间(单位:毫秒) + private static final long EXPIRATION_TIME = 3600000; // 1小时 + + /** + * 生成Token + * + * @param userId 用户ID + * @return 生成的Token + */ + public static String generateToken(String userId) { + Map claims = new HashMap<>(); + claims.put("userId", userId); // 将用户ID放入Token的负载部分 + + return Jwts.builder() + .setClaims(claims) // 设置自定义信息 + .setIssuedAt(new Date(System.currentTimeMillis())) // 设置签发时间 + .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) // 设置过期时间 + .signWith(SECRET_KEY) // 使用密钥进行签名 + .compact(); // 生成Token + } + + /** + * 验证Token是否有效 + * + * @param token Token字符串 + * @return 是否有效 + */ + public static boolean validateToken(String token) { + try { + Jwts.parserBuilder() + .setSigningKey(SECRET_KEY) // 设置密钥 + .build() + .parseClaimsJws(token); // 解析Token + return true; // 如果没有异常,表示Token有效 + } catch (Exception e) { + return false; // 如果解析失败,表示Token无效 + } + } + + /** + * 从Token中提取用户ID + * + * @param token Token字符串 + * @return 用户ID + */ + public static String getUserIdFromToken(String token) { + Claims claims = Jwts.parserBuilder() + .setSigningKey(SECRET_KEY) // 设置密钥 + .build() + .parseClaimsJws(token) // 解析Token + .getBody(); + return claims.get("userId", String.class); // 提取用户ID + } + + /** + * 获取Token的过期时间 + * + * @param token Token字符串 + * @return 过期时间 + */ + public static Date getExpirationDateFromToken(String token) { + Claims claims = Jwts.parserBuilder() + .setSigningKey(SECRET_KEY) // 设置密钥 + .build() + .parseClaimsJws(token) // 解析Token + .getBody(); + return claims.getExpiration(); // 获取Token的过期时间 + } +} diff --git a/src/main/java/com/bruce/sams/mapper/SysUserMapper.java b/src/main/java/com/bruce/sams/mapper/SysUserMapper.java new file mode 100644 index 00000000..663a6c23 --- /dev/null +++ b/src/main/java/com/bruce/sams/mapper/SysUserMapper.java @@ -0,0 +1,19 @@ +package com.bruce.sams.mapper; + +import com.bruce.sams.Entity.SysUser; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** +* @author bruce +* @description 针对表【sys_user(系统用户表)】的数据库操作Mapper +* @createDate 2025-02-08 00:19:50 +* @Entity com.bruce.sams.Entity.SysUser +*/ +@Mapper +public interface SysUserMapper extends BaseMapper { +} + + + + diff --git a/src/main/java/com/bruce/sams/service/SysLoginService.java b/src/main/java/com/bruce/sams/service/SysLoginService.java new file mode 100644 index 00000000..4b11627a --- /dev/null +++ b/src/main/java/com/bruce/sams/service/SysLoginService.java @@ -0,0 +1,11 @@ +package com.bruce.sams.service; + +public interface SysLoginService { + /** + * 用户登录方法 + * @param username 用户名 + * @param password 密码 + * @return token + */ + public String login(String username, String password); +} diff --git a/src/main/java/com/bruce/sams/service/SysUserService.java b/src/main/java/com/bruce/sams/service/SysUserService.java new file mode 100644 index 00000000..53683fdc --- /dev/null +++ b/src/main/java/com/bruce/sams/service/SysUserService.java @@ -0,0 +1,20 @@ +package com.bruce.sams.service; + +import com.bruce.sams.Entity.SysUser; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author bruce +* @description 针对表【sys_user(系统用户表)】的数据库操作Service +* @createDate 2025-02-08 00:19:50 +*/ +public interface SysUserService extends IService { + + /** + * 修改密码 + * @param userId 用户ID + * @param newPassword 新密码 + * @return 修改成功T 失败F + */ + public boolean changePassword(Long userId, String newPassword); +} diff --git a/src/main/java/com/bruce/sams/service/impl/SysLoginServiceImpl.java b/src/main/java/com/bruce/sams/service/impl/SysLoginServiceImpl.java new file mode 100644 index 00000000..63fb12b5 --- /dev/null +++ b/src/main/java/com/bruce/sams/service/impl/SysLoginServiceImpl.java @@ -0,0 +1,49 @@ +package com.bruce.sams.service.impl; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bruce.sams.Entity.SysUser; +import com.bruce.sams.Exception.User.IncorrectPasswordException; +import com.bruce.sams.Exception.User.UserNotFoundException; +import com.bruce.sams.Utils.PasswordEncoder; +import com.bruce.sams.Utils.TokenUtil; +import com.bruce.sams.mapper.SysUserMapper; +import com.bruce.sams.service.SysLoginService; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +@Service +public class SysLoginServiceImpl extends ServiceImpl + implements SysLoginService { + + @Resource + private PasswordEncoder passwordEncoder; + + /** + * 用户登录验证 + * @param schoolId 学号 + * @param password 原始密码 + * @return 如果登录成功返回用户信息和Token,否则返回null + */ + @Override + public String login(String schoolId, String password) { + // 查找用户 + SysUser user = this.getOne(Wrappers.lambdaQuery().eq(SysUser::getSchoolId, schoolId)); + + //如果用户不存在,抛出用户未找到异常 + if (user == null) { + throw new UserNotFoundException("用户不存在"); + } + + // 检查密码是否正确 + if (!passwordEncoder.matches(password, user.getPasswd())) { + throw new IncorrectPasswordException("密码错误"); + } + + // 登录成功,生成Token + + // 返回Token + return TokenUtil.generateToken(user.getUserId().toString()); + } + +} diff --git a/src/main/java/com/bruce/sams/service/impl/SysUserServiceImpl.java b/src/main/java/com/bruce/sams/service/impl/SysUserServiceImpl.java new file mode 100644 index 00000000..55edef8f --- /dev/null +++ b/src/main/java/com/bruce/sams/service/impl/SysUserServiceImpl.java @@ -0,0 +1,71 @@ +package com.bruce.sams.service.impl; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.bruce.sams.Entity.SysUser; +import com.bruce.sams.Utils.PasswordEncoder; +import com.bruce.sams.service.SysUserService; +import com.bruce.sams.mapper.SysUserMapper; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +/** + * @author bruce + * @description 针对表【sys_user(系统用户表)】的数据库操作Service实现 + * @createDate 2025-02-08 00:19:50 + */ +@Service +public class SysUserServiceImpl extends ServiceImpl + implements SysUserService { + + @Resource + private PasswordEncoder passwordEncoder; + + /** + * 新增用户(更改加密) + * @param entity 新增用户实体 + * @return 新增成功T 失败F + */ + @Override + public boolean save(SysUser entity) { + // 如果用户输入了密码,则加密后保存 + if (entity.getPasswd() != null) { + entity.setPasswd(passwordEncoder.encode(entity.getPasswd())); // 加密密码 + } + return super.save(entity); // 调用父类方法保存用户 + } + + /** + * 根据ID更新(更改加密) + * @param entity 修改用户实体 + * @return 新增成功T 失败F + */ + @Override + public boolean updateById(SysUser entity) { + // 更新时如果密码字段有变化,则加密新密码 + if (entity.getPasswd() != null) { + entity.setPasswd(passwordEncoder.encode(entity.getPasswd())); // 加密新密码 + } + return super.updateById(entity); // 调用父类方法更新用户信息 + } + + /** + * 修改密码 + * @param userId 用户ID + * @param newPassword 新密码 + * @return 修改成功T 失败F + */ + @Override + public boolean changePassword(Long userId, String newPassword) { + // 根据用户ID获取用户信息 + SysUser user = this.getById(userId); + if (user == null) { + throw new RuntimeException("用户不存在"); // 如果用户不存在,抛出异常 + } + // 加密新密码 + String encodedPassword = passwordEncoder.encode(newPassword); + user.setPasswd(encodedPassword); // 设置加密后的新密码 + return this.updateById(user); // 更新用户信息 + } + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index 7d8ce2b4..00000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -spring.application.name=SAMS diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 00000000..cbd9b118 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,10 @@ +spring: + application: + name: SAMS + + datasource: + url: jdbc:mysql://localhost:3306/SAMS + username: root + password: admin123 + driver-class-name: com.mysql.cj.jdbc.Driver + diff --git a/src/main/resources/com/bruce/sams/mapper/SysUserMapper.xml b/src/main/resources/com/bruce/sams/mapper/SysUserMapper.xml new file mode 100644 index 00000000..5ae0c236 --- /dev/null +++ b/src/main/resources/com/bruce/sams/mapper/SysUserMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + user_id,role_id,nick_name,user_name,passwd,school_id, + college_id,email,phonenumber,sex,avatar, + status,remark + + + +