『博客开发日记』之更新个人信息接口的实现

本文最后更新于 2026年4月16日 晚上

更新用户信息接口的实现


更新用户信息接口的需求

昵称不能为空

电话号码和邮箱不能同时为空

同时电话号码要符合国内电话号码的要求

电话号码和邮箱不能和别人的重复


代码实现

在UserController中添加接口

1
2
3
4
5
6
7
8
  //更新个人信息
@PutMapping("/userInfo")
@SystemLog(businessName = "更新用户信息")
@ApiOperation(value = "更新用户信息", notes = "更新当前登录用户的个人信息")
public ResponseResult updateUserInfo(@RequestBody UpdateUserInfoDto dto)
{
return sysUserService.updateUserInfo(dto);
}

服务类中实现功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
//国内手机号正则:1开头,第二位3-9,后面9位数字
private static final String PHONE_REGEX = "^1[3-9]\\d{9}$";

//更新用户信息
@Override
public ResponseResult updateUserInfo(UpdateUserInfoDto updateUserInfoDto)
{
Long currentUserId = SecurityUtils.getUserId();
if (currentUserId == null) {
return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
}

//昵称不能为空
if (!StringUtils.hasText(updateUserInfoDto.getNickname())) {
return ResponseResult.errorResult(AppHttpCodeEnum.NICKNAME_NOT_NULL, "昵称不能为空");
}

//邮箱和电话号码不能同时为空
if (!StringUtils.hasText(updateUserInfoDto.getEmail()) && !StringUtils.hasText(updateUserInfoDto.getPhone())) {
return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR, "邮箱和电话号码不能同时为空");
}

//校验手机号格式
if (StringUtils.hasText(updateUserInfoDto.getPhone()) && !updateUserInfoDto.getPhone().matches(PHONE_REGEX)) {
return ResponseResult.errorResult(AppHttpCodeEnum.PHONE_FORMAT_ERROR, "请输入正确的手机号码");
}

//检查手机号是否被其他用户使用
if (StringUtils.hasText(updateUserInfoDto.getPhone())) {
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysUser::getPhone, updateUserInfoDto.getPhone())
.ne(SysUser::getId, currentUserId);
SysUser existSysUser = getOne(queryWrapper);
if (existSysUser != null) {
return ResponseResult.errorResult(AppHttpCodeEnum.PHONE_OCCUPIED, "你用别人的电话号码干嘛?");
}
}

//检查邮箱是否被其他用户使用
if (StringUtils.hasText(updateUserInfoDto.getEmail())) {
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysUser::getEmail, updateUserInfoDto.getEmail())
.ne(SysUser::getId, currentUserId);
SysUser existSysUser = getOne(queryWrapper);
if (existSysUser != null) {
return ResponseResult.errorResult(AppHttpCodeEnum.EMAIL_OCCUPIED, "你用别人的邮箱干嘛?");
}
}

//检查昵称是否被其他用户使用
if (StringUtils.hasText(updateUserInfoDto.getNickname())) {
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysUser::getNickname, updateUserInfoDto.getNickname())
.ne(SysUser::getId, currentUserId);
SysUser existSysUser = getOne(queryWrapper);
if (existSysUser != null) {
return ResponseResult.errorResult(AppHttpCodeEnum.NICKNAME_OCCUPIED, "这个昵称和别人的重复啦!");
}
}

//获取更新前的用户信息,用于判断头像和昵称是否变化
SysUser oldSysUser = getById(currentUserId);

//处理头像:如果是临时文件,转为正式文件
String avatar = updateUserInfoDto.getAvatar();
if (StringUtils.hasText(avatar) && avatar.contains("temp/")) {
avatar = ossFileService.moveTempToFormal(avatar);
}

//如果头像发生变化,删除OSS上的旧头像
String oldAvatar = oldSysUser.getAvatar();
if (StringUtils.hasText(avatar) && StringUtils.hasText(oldAvatar)
&& !avatar.equals(oldAvatar)) {
try {
ossFileService.deleteFileByUrl(oldAvatar);
log.info("从oss中删除旧头像成功: {}", oldAvatar);
} catch (Exception e) {
log.warn("从oss中删除旧头像失败: {}, 错误: {}", oldAvatar, e.getMessage()); //删除失败不影响更新流程,只记录日志
}
}

//使用LambdaUpdateWrapper条件更新
LambdaUpdateWrapper<SysUser> wrapper = new LambdaUpdateWrapper<SysUser>()
.eq(SysUser::getId, currentUserId)
.set(SysUser::getNickname, updateUserInfoDto.getNickname())
.set(SysUser::getSex, updateUserInfoDto.getSex())
.set(SysUser::getPhone, StringUtils.hasText(updateUserInfoDto.getPhone()) ? updateUserInfoDto.getPhone() : null)
.set(SysUser::getEmail, StringUtils.hasText(updateUserInfoDto.getEmail()) ? updateUserInfoDto.getEmail() : null)
.set(SysUser::getAvatar, avatar);

boolean success = update(null, wrapper);
if (!success) {
return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR, "更新用户信息失败");
}

//如果头像或昵称发生变化,同步更新评论表中该用户的所有评论
boolean avatarChanged = !avatar.equals(oldSysUser.getAvatar());
boolean nicknameChanged = !updateUserInfoDto.getNickname().equals(oldSysUser.getNickname());

if (avatarChanged || nicknameChanged) {
LambdaUpdateWrapper<com.mengze.domain.entity.Comment> commentWrapper =
new LambdaUpdateWrapper<com.mengze.domain.entity.Comment>()
.eq(com.mengze.domain.entity.Comment::getUserId, currentUserId);

if (avatarChanged) {
commentWrapper.set(com.mengze.domain.entity.Comment::getAvatar, avatar);
}
if (nicknameChanged) {
commentWrapper.set(com.mengze.domain.entity.Comment::getNickname, updateUserInfoDto.getNickname());
}

commentMapper.update(null, commentWrapper);
}

return ResponseResult.okResult();
}

创建 UpdateUserInfoDto

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* 更新用户信息DTO
*/
@Data
@ApiModel(description = "更新用户信息请求对象")
public class UpdateUserInfoDto {

@ApiModelProperty(value = "用户ID", required = true, example = "1")
private Long id;

@ApiModelProperty(value = "昵称", example = "张三")
private String nickname;

@ApiModelProperty(value = "邮箱", example = "user@example.com")
private String email;

@ApiModelProperty(value = "手机号", example = "13800138000")
private String phone;

@ApiModelProperty(value = "用户性别(0-男,1-女,2-隐藏)", example = "0")
private String sex;

@ApiModelProperty(value = "头像URL", example = "https://example.com/avatar.jpg")
private String avatar;
}

更新用户信息接口测试通过,注意要携带token才可以更新



PS:该系列只做为作者学习开发项目做的笔记用

不一定符合读者来学习,仅供参考


预告

后续会记录博客的开发过程

每次学习会做一份笔记来进行发表

“一花一世界,一叶一菩提”


版权所有 © 2026 云梦泽
欢迎访问我的个人网站:https://hgt12.github.io/


『博客开发日记』之更新个人信息接口的实现
http://example.com/2026/01/16/『博客开发日记』之更新个人信息接口的实现/
作者
云梦泽
发布于
2026年1月16日
更新于
2026年4月16日
许可协议