获取信息需要用户已经完成登陆操作,因此使用了登陆拦截,添加 @LoginValidator注解即可

获取用户信息

在 UserInfoController 下定义获取登陆用户的信息方法

UserInfoController
@GetMapping("getUserInfo")
@LoginValidator
public SessionWebUserVO getUserInfo(HttpSession session) {
return (SessionWebUserVO) session.getAttribute(Constants.SESSION_KEY);
}

注销登录操作

@PostMapping("/logout")
@LoginValidator
public void logout(HttpSession session) {
session.invalidate();
}

重置密码功能

接口信息

请求参数和注册方法一致

路径地址 http://localhost:7090/api/resetPwd
请求方式 POST
请求参数 RegisterDTO
返回结果

定义Service

找到 UserInfoService接口,在其中添加:

UserInfoService
/**
* 重置密码
*
* @param email 邮箱
* @param password 密码
* @param emailCode 邮箱验证码
*/
void resetPwd(String email, String password, String emailCode);

在 UserInfoServiceImpl 中实现该方法

UserInfoServiceImpl
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

private final EmailCodeService emailCodeService;

public UserInfoServiceImpl(EmailCodeService emailCodeService) {
this.emailCodeService = emailCodeService;
}

/**
* 重置密码
*
* @param email 邮箱
* @param password 密码
* @param emailCode 邮箱验证码
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void resetPwd(String email, String password, String emailCode) {
UserInfo emailUser = this.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getEmail, email));
if (null == emailUser) {
throw new BizException("邮箱账号不存在");
}
emailCodeService.checkCode(email, emailCode);
emailUser.setPassword(MD5.encrypt(password));
updateById(emailUser);
}
}

定义Controller

在 UserInfoController 下定义登陆方法,登陆成功后将用户信息放入到Session中,并将验证码从Session中删除,防止验证码重复使用。

UserInfoController
@RestController("userInfoController")
@ResponseResult
@Validated
public class UserInfoController {

private final UserInfoService userInfoService;

public UserInfoController(UserInfoService userInfoService) {
this.userInfoService = userInfoService;
}

@PostMapping("/resetPwd")
public void resetPwd(HttpSession session,
@Valid @RequestBody RegisterDTO registerDto) {
try {
if (!registerDto.getCheckCode().equalsIgnoreCase((String) session.getAttribute(Constants.CHECK_CODE_KEY))) {
throw new BizException("图片验证码错误");
}
userInfoService.resetPwd(registerDto.getEmail(), registerDto.getPassword(), registerDto.getEmailCode());
} finally {
session.removeAttribute(Constants.CHECK_CODE_KEY);
}
}
}

更新用户密码

接口信息

路径地址 http://localhost:7090/api/updatePassword
请求方式 POST
请求参数 password
返回结果

定义Controller

在 UserInfoController 下定义更新用户密码,参数校验使用了Spring Validate。

UserInfoController
@RestController("userInfoController")
@ResponseResult
@Validated
public class UserInfoController {

private final UserInfoService userInfoService;

public UserInfoController(UserInfoService userInfoService) {
this.userInfoService = userInfoService;
}

@PostMapping("/updatePassword")
@LoginValidator
public void updatePassword(HttpSession session,
@Size(min = 8, max = 18, message = "密码长度8-18") String password) {
SessionWebUserVO userVo = (SessionWebUserVO) session.getAttribute(Constants.SESSION_KEY);
UserInfo userInfo = new UserInfo();
userInfo.setId(userVo.getId());
userInfo.setPassword(MD5.encrypt(password));
userInfoService.updateById(userInfo);
}
}

用户头像服务

获取头像服务

用户头像在部署系统中存储方式为工程目录+文件目录+头像目录+用户ID+头像文件后缀,即只需要知道用户的ID就可以找到头像所在目录,然后通过文件流的方式返回给前端。

接口信息

请求参数和注册方法一致,通过文件流的方式写给前端

路径地址 http://localhost:7090/api/getAvatar/{userId}
请求方式 GET
请求参数 userId
返回结果

定义常量

静态常量,Constants 类中定义常量

Constants
public static final String FILE_FOLDER_FILE = "/file/";
public static final String FILE_FOLDER_TEMP = "/file/temp/";
public static final String FILE_FOLDER_AVATAR_NAME = "avatar/";
public static final String AVATAR_SUFFIX = ".jpg";
public static final String AVATAR_DEFAULT = "default_avatar.jpg";

定义Controller

在 UserInfoController 下定义获取头像方法,通过拼接目录和用户ID以及文件后缀,得到文件的路径,然后通过文件流的方式返回前端,如果没有则返回默认头像。

UserInfoController
@RestController("userInfoController")
@ResponseResult
@Validated
public class UserInfoController {

@Resource
AppConfig appConfig;

@GetMapping("getAvatar/{userId}")
public void getAvatar(HttpServletResponse response, @PathVariable @NotNull String userId) {
String avatarFolderName = Constants.FILE_FOLDER_FILE + Constants.FILE_FOLDER_AVATAR_NAME;
File folder = new File(appConfig.getProjectFolder() + avatarFolderName);
if (!folder.exists()) {
folder.mkdirs();
}
String avatarPath = appConfig.getProjectFolder() + avatarFolderName + userId + Constants.AVATAR_SUFFIX;
File file = new File(avatarPath);
if (!file.exists()) {
// 默认头像
String defaultAvatarPath = appConfig.getProjectFolder() + avatarFolderName + Constants.AVATAR_DEFAULT;
File defaultAvatar = new File(defaultAvatarPath);
if (!defaultAvatar.exists()) {
printNoDefaultImage(response);
return;
}
avatarPath = defaultAvatarPath;
}
response.setContentType("image/jpg");
FileUtil.readFile(response, avatarPath);
}

private void printNoDefaultImage(HttpServletResponse response) {
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpStatus.OK.value());
PrintWriter writer = null;
try {
writer = response.getWriter();
writer.println("请在头像目录下放置默认头像default_avatar.jpg");
writer.close();
} catch (IOException e) {
throw new BizException("输出默认头像失败");
}
}
}

更新用户头像

接口信息

路径地址 http://localhost:7090/api/updateUserAvatar
请求方式 POST
请求参数 MultipartFile
返回结果

定义Controller

在 UserInfoController 下定义更新头像方法,接收到文件后,写入到头像目录,头像文件名为用户ID,后缀统一为JPG,更新成功后将Session中用户信息更新。

UserInfoController
@RestController("userInfoController")
@ResponseResult
@Validated
public class UserInfoController {

private final UserInfoService userInfoService;

public UserInfoController(UserInfoService userInfoService) {
this.userInfoService = userInfoService;
}

@PostMapping("/updateUserAvatar")
@LoginValidator
public void updateUserAvatar(HttpSession session, MultipartFile avatar) {
SessionWebUserVO userVo = (SessionWebUserVO) session.getAttribute(Constants.SESSION_KEY);
String baseFolder = appConfig.getProjectFolder() + Constants.FILE_FOLDER_FILE;
File targetFileFolder = new File(baseFolder + Constants.FILE_FOLDER_AVATAR_NAME);
if (!targetFileFolder.exists()) {
targetFileFolder.mkdirs();
}
File targetFile = new File(targetFileFolder.getPath() + "/" + userVo.getId() + Constants.AVATAR_SUFFIX);
try {
avatar.transferTo(targetFile);
} catch (IOException e) {
throw new BizException("头像更新失败");
}
UserInfo userInfo = new UserInfo();
userInfo.setId(userVo.getId());
userInfo.setQqAvatar("");
userInfoService.updateById(userInfo);
userVo.setAvatar(null);
session.setAttribute(Constants.SESSION_KEY, userVo);
}
}