diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
index 5e227045..b31b831d 100644
--- a/.idea/dataSources.xml
+++ b/.idea/dataSources.xml
@@ -9,6 +9,37 @@
+
+
+
+ $ProjectFileDir$
+
+
+ redis
+ true
+ true
+ $PROJECT_DIR$/unilife-server/src/main/resources/application.yml
+ jdbc.RedisDriver
+ jdbc:redis://127.0.0.1:6379/0
+
+
+
+
+
+
+ $ProjectFileDir$
+
+
+ mysql.8
+ true
+ true
+ $PROJECT_DIR$/unilife-server/src/main/resources/application.yml
+ com.mysql.cj.jdbc.Driver
+ jdbc:mysql://localhost:3306/UniLife?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8
+
+
+
+
$ProjectFileDir$
diff --git a/unilife-server/pom.xml b/unilife-server/pom.xml
index a0bdd72b..b8029f4d 100644
--- a/unilife-server/pom.xml
+++ b/unilife-server/pom.xml
@@ -36,6 +36,12 @@
spring-boot-starter-web
+
+ com.github.pagehelper
+ pagehelper-spring-boot-starter
+ 2.1.0
+
+
org.mybatis.spring.boot
@@ -117,6 +123,10 @@
spring-boot-starter-test
test
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
diff --git a/unilife-server/src/main/java/com/unilife/common/result/Result.java b/unilife-server/src/main/java/com/unilife/common/result/Result.java
index f16d1a59..1e91ff21 100644
--- a/unilife-server/src/main/java/com/unilife/common/result/Result.java
+++ b/unilife-server/src/main/java/com/unilife/common/result/Result.java
@@ -40,7 +40,7 @@ public class Result{
}
public static Result success(T data, String message) {
- return new Result<>(200, message, null);
+ return new Result<>(200, message, data);
}
/**
diff --git a/unilife-server/src/main/java/com/unilife/controller/UserController.java b/unilife-server/src/main/java/com/unilife/controller/UserController.java
index e26704c7..78a3bcd7 100644
--- a/unilife-server/src/main/java/com/unilife/controller/UserController.java
+++ b/unilife-server/src/main/java/com/unilife/controller/UserController.java
@@ -5,6 +5,9 @@ import com.unilife.model.dto.EmailDTO;
import com.unilife.model.dto.LoginDTO;
import com.unilife.model.dto.LoginEmailDTO;
import com.unilife.model.dto.RegisterDTO;
+import com.unilife.model.dto.UpdateEmailDTO;
+import com.unilife.model.dto.UpdatePasswordDTO;
+import com.unilife.model.dto.UpdateProfileDTO;
import com.unilife.model.vo.LoginVO;
import com.unilife.service.UserService;
import com.unilife.utils.BaseContext;
@@ -13,10 +16,15 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
import jakarta.servlet.http.HttpServletRequest;
@@ -63,7 +71,72 @@ public class UserController {
@Operation(summary = "邮箱验证码登录")
@PostMapping("login/code")
public Result> loginWithEmailCode(@RequestBody LoginEmailDTO loginEmailDTO, HttpServletRequest request) {
- return userService.loginWithEmail(loginEmailDTO, request);
+ Result> login = userService.loginWithEmail(loginEmailDTO, request);
+ LoginVO vo = (LoginVO) login.getData();
+ if (vo == null) {
+ return login;
+ }
+ Long id = vo.getId();
+ String token = jwtUtil.generateToken(id);
+ vo.setToken(token);
+ BaseContext.setId(id);
+ return Result.success(vo);
+ }
+
+ // 用户信息管理相关API
+
+ @Operation(summary = "获取用户个人信息")
+ @GetMapping("profile")
+ public Result> getUserProfile() {
+ // 从当前上下文获取用户ID
+ Long userId = BaseContext.getId();
+ if (userId == null) {
+ return Result.error(401, "未登录");
+ }
+ return userService.getUserProfile(userId);
+ }
+
+ @Operation(summary = "更新用户个人信息")
+ @PutMapping("profile")
+ public Result> updateUserProfile(@RequestBody UpdateProfileDTO profileDTO) {
+ // 从当前上下文获取用户ID
+ Long userId = BaseContext.getId();
+ if (userId == null) {
+ return Result.error(401, "未登录");
+ }
+ return userService.updateUserProfile(userId, profileDTO);
+ }
+
+ @Operation(summary = "修改用户密码")
+ @PutMapping("password")
+ public Result> updatePassword(@RequestBody UpdatePasswordDTO passwordDTO) {
+ // 从当前上下文获取用户ID
+ Long userId = BaseContext.getId();
+ if (userId == null) {
+ return Result.error(401, "未登录");
+ }
+ return userService.updatePassword(userId, passwordDTO);
+ }
+
+ @Operation(summary = "上传用户头像")
+ @PostMapping("avatar")
+ public Result> updateAvatar(@RequestParam("file") MultipartFile file) {
+ // 从当前上下文获取用户ID
+ Long userId = BaseContext.getId();
+ if (userId == null) {
+ return Result.error(401, "未登录");
+ }
+ return userService.updateAvatar(userId, file);
}
+ @Operation(summary = "更新用户邮箱")
+ @PutMapping("email")
+ public Result> updateEmail(@RequestBody UpdateEmailDTO emailDTO) {
+ // 从当前上下文获取用户ID
+ Long userId = BaseContext.getId();
+ if (userId == null) {
+ return Result.error(401, "未登录");
+ }
+ return userService.updateEmail(userId, emailDTO);
+ }
}
diff --git a/unilife-server/src/main/java/com/unilife/interceptor/JwtInterceptor.java b/unilife-server/src/main/java/com/unilife/interceptor/JwtInterceptor.java
index 5230f151..168f9c8b 100644
--- a/unilife-server/src/main/java/com/unilife/interceptor/JwtInterceptor.java
+++ b/unilife-server/src/main/java/com/unilife/interceptor/JwtInterceptor.java
@@ -25,15 +25,22 @@ public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
-
log.info("JwtInterceptor preHandle");
- String token = request.getHeader("Authorization");
- if(StrUtil.isBlank(token)){
+ String authHeader = request.getHeader("Authorization");
+
+ if(StrUtil.isBlank(authHeader)){
response.setStatus(401);
return false;
}
+ // 处理Bearer token格式
+ String token = authHeader;
+ if(authHeader.startsWith("Bearer ")){
+ token = authHeader.substring(7);
+ }
+ log.info("Extracted token:{}", token);
+
boolean verified = jwtUtil.verifyToken(token);
if (!verified) {
response.setStatus(401);
@@ -42,9 +49,11 @@ public class JwtInterceptor implements HandlerInterceptor {
//从token中获取userid并存入threadlocal
Long userId = jwtUtil.getUserIdFromToken(token);
+ if(userId == null) {
+ response.setStatus(401);
+ return false;
+ }
BaseContext.setId(userId);
-
-
return true;
}
diff --git a/unilife-server/src/main/java/com/unilife/mapper/UserMapper.java b/unilife-server/src/main/java/com/unilife/mapper/UserMapper.java
index a5020f4a..29f2ffa1 100644
--- a/unilife-server/src/main/java/com/unilife/mapper/UserMapper.java
+++ b/unilife-server/src/main/java/com/unilife/mapper/UserMapper.java
@@ -4,11 +4,21 @@ import com.unilife.model.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
+import java.util.Date;
+
@Mapper
public interface UserMapper {
void insert(User user);
- User FindByEmail(@Param("email") String email, @Param("password") String password);
- User getUserByEmail(String email);
+ User findByEmail(String email);
+ void updateLoginInfo(@Param("userId") Long userId,
+ @Param("ipLocation") String ipLocation,
+ @Param("loginTime") Date loginTime);
void UpdateIPLocation(@Param("email") String email,@Param("loginIp") String loginIp);
- User FindByOnlyEmail(@Param("email") String email);
+
+ // 用户信息管理相关方法
+ User getUserById(Long id);
+ void updateUserProfile(User user);
+ void updatePassword(@Param("id") Long id, @Param("newPassword") String newPassword);
+ void updateAvatar(@Param("id") Long id, @Param("avatar") String avatarUrl);
+ void updateEmail(@Param("id") Long id, @Param("email") String email);
}
diff --git a/unilife-server/src/main/java/com/unilife/service/UserService.java b/unilife-server/src/main/java/com/unilife/service/UserService.java
index 9b4a0781..d2115120 100644
--- a/unilife-server/src/main/java/com/unilife/service/UserService.java
+++ b/unilife-server/src/main/java/com/unilife/service/UserService.java
@@ -4,7 +4,11 @@ import com.unilife.common.result.Result;
import com.unilife.model.dto.LoginDTO;
import com.unilife.model.dto.LoginEmailDTO;
import com.unilife.model.dto.RegisterDTO;
+import com.unilife.model.dto.UpdateEmailDTO;
+import com.unilife.model.dto.UpdatePasswordDTO;
+import com.unilife.model.dto.UpdateProfileDTO;
import jakarta.servlet.http.HttpServletRequest;
+import org.springframework.web.multipart.MultipartFile;
public interface UserService {
@@ -12,7 +16,18 @@ public interface UserService {
Result login(LoginDTO loginDTO, HttpServletRequest request);
- Result sendVerificationCode(String email,HttpServletRequest request);
+ Result sendVerificationCode(String email, HttpServletRequest request);
- Result loginWithEmail(LoginEmailDTO loginEmailDTO,HttpServletRequest request);
+ Result loginWithEmail(LoginEmailDTO loginEmailDTO, HttpServletRequest request);
+
+ // 用户信息管理相关方法
+ Result getUserProfile(Long userId);
+
+ Result updateUserProfile(Long userId, UpdateProfileDTO profileDTO);
+
+ Result updatePassword(Long userId, UpdatePasswordDTO passwordDTO);
+
+ Result updateAvatar(Long userId, MultipartFile file);
+
+ Result updateEmail(Long userId, UpdateEmailDTO emailDTO);
}
diff --git a/unilife-server/src/main/java/com/unilife/service/impl/UserServiceImpl.java b/unilife-server/src/main/java/com/unilife/service/impl/UserServiceImpl.java
index 28675275..b2f103c5 100644
--- a/unilife-server/src/main/java/com/unilife/service/impl/UserServiceImpl.java
+++ b/unilife-server/src/main/java/com/unilife/service/impl/UserServiceImpl.java
@@ -8,6 +8,9 @@ import com.unilife.mapper.UserMapper;
import com.unilife.model.dto.LoginDTO;
import com.unilife.model.dto.LoginEmailDTO;
import com.unilife.model.dto.RegisterDTO;
+import com.unilife.model.dto.UpdateEmailDTO;
+import com.unilife.model.dto.UpdatePasswordDTO;
+import com.unilife.model.dto.UpdateProfileDTO;
import com.unilife.model.entity.User;
import com.unilife.model.vo.LoginVO;
import com.unilife.model.vo.RegisterVO;
@@ -18,7 +21,9 @@ import com.unilife.utils.RegexUtils;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import jakarta.servlet.http.HttpServletRequest;
+import lombok.Data;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
@@ -26,10 +31,13 @@ import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
import java.time.Duration;
+import java.time.LocalDateTime;
+import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@@ -69,7 +77,7 @@ public class UserServiceImpl implements UserService {
if(registerDTO.getPassword().length() < 6) {
return Result.error(400,"密码长度过短!");
}
- User getuser = userMapper.FindByOnlyEmail(registerDTO.getEmail());
+ User getuser = userMapper.findByEmail(registerDTO.getEmail());
if(getuser != null) {
return Result.error(400,"用户已存在!");
}
@@ -86,24 +94,36 @@ public class UserServiceImpl implements UserService {
@Override
public Result login(LoginDTO loginDTO,HttpServletRequest request) {
- User user = new User();
- BeanUtil.copyProperties(loginDTO,user);//将登录的前端传来的消息拷贝给这个user
- User getuser = userMapper.FindByEmail(user.getEmail(),user.getPassword());
- if(getuser == null)
- {
- return Result.error(loginDTO,"用户不存在,登录失败!");
+ if(loginDTO==null|| StringUtils.isEmpty(loginDTO.getEmail())||StringUtils.isEmpty(loginDTO.getPassword())){
+ return Result.error(400,"邮箱或密码不能为空");
}
- if(!user.getPassword().equals(getuser.getPassword()))
- {
- return Result.error(loginDTO,"密码错误,登录失败!");
+
+ User user = userMapper.findByEmail(loginDTO.getEmail());
+ if (user == null) {
+ return Result.error(400, "账号或密码错误");
}
- String LastLogIpLocation = getuser.getLoginIp();
- String IPAddress = ipLocationService.getClientIP(request);
- String Location = ipLocationService.getIPLocation(IPAddress);
- getuser.setLoginIp(Location);
- userMapper.UpdateIPLocation(getuser.getEmail(), getuser.getLoginIp());
+
+ if (!loginDTO.getPassword().equals(user.getPassword())) {
+ return Result.error(400, "账号或密码错误");
+ }
+
+ if (user.getStatus() != 1) {
+ return Result.error(403, "账号已被禁用,请联系管理员");
+ }
+
+
+ String LastLogIpLocation = user.getLoginIp();
+ String currentIp = ipLocationService.getClientIP(request);
+ String ipLocation = ipLocationService.getIPLocation(currentIp);
+ user.setLoginIp(ipLocation);
+ user.setLoginTime(LocalDateTime.now());
+ userMapper.updateLoginInfo(user.getId(),ipLocation,new Date());
+
LoginVO loginVO = new LoginVO();
- return Result.success(loginVO,"上次登录IP归属地为" + LastLogIpLocation);
+ BeanUtil.copyProperties(user,loginVO);
+ String message = StringUtils.isEmpty(LastLogIpLocation) ? "首次登录" : "上次登录IP归属地为" + LastLogIpLocation;
+ return Result.success(loginVO, message);
+
}
@Override
@@ -177,39 +197,43 @@ public class UserServiceImpl implements UserService {
String email=loginEmailDTO.getEmail();
if(RegexUtils.isEmailInvalid(email)){
- return Result.error(null,"请输入正确的邮箱");
+ return Result.error(400,"请输入正确的邮箱");
}
String cacheCode = stringRedisTemplate.opsForValue().get(RedisConstant.LOGIN_EMAIL_KEY + email);
if (cacheCode == null) {
- return Result.error(null, "验证码已过期或未发送,请重新获取");
+ return Result.error(400, "验证码已过期或未发送,请重新获取");
}
// 3. 校验验证码是否正确
String code = loginEmailDTO.getCode();
if (!cacheCode.equals(code)) {
- return Result.error(null, "验证码错误");
+ return Result.error(400, "验证码错误");
}
// 4. 验证通过,删除验证码
stringRedisTemplate.delete(RedisConstant.LOGIN_EMAIL_KEY + email);
// 5. 查询用户是否存在
- User user=userMapper.getUserByEmail(email);
+ User user=userMapper.findByEmail(email);
if(user == null){
user = createUserWithEmail(email,request);
}
- //6.生成登录凭证
- //TODO
+ // 更新登录信息
+ String currentIp = ipLocationService.getClientIP(request);
+ String ipLocation = ipLocationService.getIPLocation(currentIp);
+ user.setLoginIp(ipLocation);
+ user.setLoginTime(LocalDateTime.now());
+ userMapper.updateLoginInfo(user.getId(), ipLocation, new Date());
- String token = jwtUtil.generateToken(user.getId());
- // 8. 返回用户信息和登录凭证
- Map userInfo = new HashMap<>();
- userInfo.put("token", token);
- userInfo.put("user", user);
+ // 创建LoginVO对象,与普通登录保持一致的返回格式
+ LoginVO loginVO = new LoginVO();
+ BeanUtil.copyProperties(user, loginVO);
- return Result.success(userInfo);
+ // 返回结果,不在这里生成token,由Controller统一处理
+ String message = "邮箱验证码登录成功";
+ return Result.success(loginVO, message);
}
/**
@@ -243,4 +267,147 @@ public class UserServiceImpl implements UserService {
return user;
}
+ @Override
+ public Result getUserProfile(Long userId) {
+ // 根据用户ID获取用户信息
+ User user = userMapper.getUserById(userId);
+ if (user == null) {
+ return Result.error(404, "用户不存在");
+ }
+
+ // 出于安全考虑,不返回密码字段
+ user.setPassword(null);
+
+ return Result.success(user);
+ }
+
+ @Override
+ public Result updateUserProfile(Long userId, UpdateProfileDTO profileDTO) {
+ // 检查用户是否存在
+ User user = userMapper.getUserById(userId);
+ if (user == null) {
+ return Result.error(404, "用户不存在");
+ }
+
+ // 更新用户信息
+ user.setNickname(profileDTO.getNickname());
+ user.setBio(profileDTO.getBio());
+ user.setGender(profileDTO.getGender());
+ user.setDepartment(profileDTO.getDepartment());
+ user.setMajor(profileDTO.getMajor());
+ user.setGrade(profileDTO.getGrade());
+
+ // 保存更新
+ userMapper.updateUserProfile(user);
+
+ return Result.success(null, "个人资料更新成功");
+ }
+
+ @Override
+ public Result updatePassword(Long userId, UpdatePasswordDTO passwordDTO) {
+ // 检查用户是否存在
+ User user = userMapper.getUserById(userId);
+ if (user == null) {
+ return Result.error(404, "用户不存在");
+ }
+
+ // 验证验证码
+ String cacheCode = stringRedisTemplate.opsForValue().get(RedisConstant.LOGIN_EMAIL_KEY + user.getEmail());
+ if (cacheCode == null) {
+ return Result.error(400, "验证码已过期或未发送,请重新获取");
+ }
+
+ if (!cacheCode.equals(passwordDTO.getCode())) {
+ return Result.error(400, "验证码错误");
+ }
+
+ // 验证通过,删除验证码
+ stringRedisTemplate.delete(RedisConstant.LOGIN_EMAIL_KEY + user.getEmail());
+
+ // 更新密码
+ userMapper.updatePassword(userId, passwordDTO.getNewPassword());
+
+ return Result.success(null, "密码修改成功");
+ }
+
+ @Override
+ public Result updateAvatar(Long userId, MultipartFile file) {
+ // 检查用户是否存在
+ User user = userMapper.getUserById(userId);
+ if (user == null) {
+ return Result.error(404, "用户不存在");
+ }
+
+ // 检查文件是否为空
+ if (file.isEmpty()) {
+ return Result.error(400, "上传文件不能为空");
+ }
+
+ // 检查文件类型
+ String contentType = file.getContentType();
+ if (contentType == null || !contentType.startsWith("image/")) {
+ return Result.error(400, "只能上传图片文件");
+ }
+
+ try {
+ // 生成文件名
+ String originalFilename = file.getOriginalFilename();
+ String suffix = originalFilename != null ? originalFilename.substring(originalFilename.lastIndexOf(".")) : ".jpg";
+ String filename = "avatar_" + userId + "_" + System.currentTimeMillis() + suffix;
+
+ // TODO: 实际项目中应该将文件保存到云存储或服务器指定目录
+ // 这里简化处理,假设保存成功并返回URL
+ String avatarUrl = "https://example.com/avatars/" + filename;
+
+ // 更新用户头像URL
+ userMapper.updateAvatar(userId, avatarUrl);
+
+ Map data = new HashMap<>();
+ data.put("avatar", avatarUrl);
+
+ return Result.success(data, "头像上传成功");
+ } catch (Exception e) {
+ log.error("头像上传失败", e);
+ return Result.error(500, "头像上传失败");
+ }
+ }
+
+ @Override
+ public Result updateEmail(Long userId, UpdateEmailDTO emailDTO) {
+ // 检查用户是否存在
+ User user = userMapper.getUserById(userId);
+ if (user == null) {
+ return Result.error(404, "用户不存在");
+ }
+
+ // 检查邮箱格式
+ String email = emailDTO.getEmail();
+ if (RegexUtils.isEmailInvalid(email)) {
+ return Result.error(400, "邮箱格式不正确");
+ }
+
+ // 检查邮箱是否已被使用
+ User existingUser = userMapper.findByEmail(email);
+ if (existingUser != null && !existingUser.getId().equals(userId)) {
+ return Result.error(400, "该邮箱已被其他用户使用");
+ }
+
+ // 验证验证码
+ String cacheCode = stringRedisTemplate.opsForValue().get(RedisConstant.LOGIN_EMAIL_KEY + email);
+ if (cacheCode == null) {
+ return Result.error(400, "验证码已过期或未发送,请重新获取");
+ }
+
+ if (!cacheCode.equals(emailDTO.getCode())) {
+ return Result.error(400, "验证码错误");
+ }
+
+ // 验证通过,删除验证码
+ stringRedisTemplate.delete(RedisConstant.LOGIN_EMAIL_KEY + email);
+
+ // 更新邮箱
+ userMapper.updateEmail(userId, email);
+
+ return Result.success(null, "邮箱更新成功");
+ }
}
diff --git a/unilife-server/src/main/java/com/unilife/utils/JwtUtil.java b/unilife-server/src/main/java/com/unilife/utils/JwtUtil.java
index 6d3974d4..c33d5fd9 100644
--- a/unilife-server/src/main/java/com/unilife/utils/JwtUtil.java
+++ b/unilife-server/src/main/java/com/unilife/utils/JwtUtil.java
@@ -2,6 +2,7 @@ package com.unilife.utils;
import cn.hutool.core.date.DateTime;
import cn.hutool.jwt.JWTUtil;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@@ -9,6 +10,7 @@ import java.util.HashMap;
import java.util.Map;
@Component
+@Slf4j
public class JwtUtil {
@Value("${jwt.secret}")
private String secret;
@@ -36,7 +38,7 @@ public class JwtUtil {
}
public Long getUserIdFromToken(String token) {
try {
- return (Long)JWTUtil.parseToken(token).getPayload("userId");
+ return Long.valueOf(JWTUtil.parseToken(token).getPayload("userId").toString());
}catch (Exception e){
return null;
}
diff --git a/unilife-server/src/main/resources/mappers/UserMapper.xml b/unilife-server/src/main/resources/mappers/UserMapper.xml
index 2caed2f5..053ff252 100644
--- a/unilife-server/src/main/resources/mappers/UserMapper.xml
+++ b/unilife-server/src/main/resources/mappers/UserMapper.xml
@@ -37,18 +37,22 @@
)
-
-
-
-
\ No newline at end of file
+
+
+
+ SELECT id,
+ username,
+ email,
+ nickname,
+ avatar,
+ bio,
+ gender,
+ student_id as studentId,
+ department,
+ major,
+ grade,
+ points,
+ role,
+ status,
+ is_verified as isVerified,
+ login_ip as loginIp,
+ login_time as loginTime,
+ created_at as createdAt,
+ updated_at as updatedAt
+ FROM users
+ WHERE id = #{id}
+
+
+
+ UPDATE users
+ SET nickname = #{nickname},
+ bio = #{bio},
+ gender = #{gender},
+ department = #{department},
+ major = #{major},
+ grade = #{grade},
+ updated_at = NOW()
+ WHERE id = #{id}
+
+
+
+ UPDATE users
+ SET password = #{newPassword},
+ updated_at = NOW()
+ WHERE id = #{id}
+
+
+
+ UPDATE users
+ SET avatar = #{avatar},
+ updated_at = NOW()
+ WHERE id = #{id}
+
+
+
+ UPDATE users
+ SET email = #{email},
+ updated_at = NOW()
+ WHERE id = #{id}
+
+