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
+
+
+
+