Commit 6cf1e920d73b039db70cb5e837b8c80ec5a637ec

Authored by 芋道源码
Committed by Gitee
2 parents 4048e598 aac051a6

!15 增加 个人信息设置 功能

Merge pull request !15 from niu_dehua/feat_userprofile
src/main/java/cn/iocoder/dashboard/modules/infra/service/job/impl/InfJobServiceImpl.java
... ... @@ -41,7 +41,7 @@ public class InfJobServiceImpl implements InfJobService {
41 41 private SchedulerManager schedulerManager;
42 42  
43 43 @Override
44   - @Transactional
  44 + @Transactional(rollbackFor = Exception.class)
45 45 public Long createJob(InfJobCreateReqVO createReqVO) throws SchedulerException {
46 46 validateCronExpression(createReqVO.getCronExpression());
47 47 // 校验唯一性
... ... @@ -66,7 +66,7 @@ public class InfJobServiceImpl implements InfJobService {
66 66 }
67 67  
68 68 @Override
69   - @Transactional
  69 + @Transactional(rollbackFor = Exception.class)
70 70 public void updateJob(InfJobUpdateReqVO updateReqVO) throws SchedulerException {
71 71 validateCronExpression(updateReqVO.getCronExpression());
72 72 // 校验存在
... ... @@ -86,7 +86,7 @@ public class InfJobServiceImpl implements InfJobService {
86 86 }
87 87  
88 88 @Override
89   - @Transactional
  89 + @Transactional(rollbackFor = Exception.class)
90 90 public void updateJobStatus(Long id, Integer status) throws SchedulerException {
91 91 // 校验 status
92 92 if (!containsAny(status, InfJobStatusEnum.NORMAL.getStatus(), InfJobStatusEnum.STOP.getStatus())) {
... ... @@ -120,7 +120,7 @@ public class InfJobServiceImpl implements InfJobService {
120 120 }
121 121  
122 122 @Override
123   - @Transactional
  123 + @Transactional(rollbackFor = Exception.class)
124 124 public void deleteJob(Long id) throws SchedulerException {
125 125 // 校验存在
126 126 InfJobDO job = this.validateJobExists(id);
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/SysUserController.java
... ... @@ -40,8 +40,8 @@ public class SysUserController {
40 40 @Resource
41 41 private SysDeptService deptService;
42 42  
43   - @ApiOperation("获得用户分页列表")
44 43 @GetMapping("/page")
  44 + @ApiOperation("获得用户分页列表")
45 45 @PreAuthorize("@ss.hasPermission('system:user:list')")
46 46 public CommonResult<PageResult<SysUserPageItemRespVO>> pageUsers(@Validated SysUserPageReqVO reqVO) {
47 47 // 获得用户分页列表
... ... @@ -66,9 +66,9 @@ public class SysUserController {
66 66 /**
67 67 * 根据用户编号获取详细信息
68 68 */
  69 + @GetMapping("/get")
69 70 @ApiOperation("获得用户详情")
70 71 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
71   - @GetMapping("/get")
72 72 // @PreAuthorize("@ss.hasPermi('system:user:query')")
73 73 public CommonResult<SysUserRespVO> getInfo(@RequestParam("id") Long id) {
74 74 return success(SysUserConvert.INSTANCE.convert(userService.getUser(id)));
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/SysUserProfileController.java
1 1 package cn.iocoder.dashboard.modules.system.controller.user;
2 2  
  3 +import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
  4 +import cn.iocoder.dashboard.common.pojo.CommonResult;
  5 +import cn.iocoder.dashboard.framework.security.core.util.SecurityFrameworkUtils;
  6 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileRespVO;
  7 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
  8 +import cn.iocoder.dashboard.modules.system.convert.auth.SysAuthConvert;
  9 +import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
  10 +import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO;
  11 +import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
  12 +import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
  13 +import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService;
  14 +import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
  15 +import cn.iocoder.dashboard.util.collection.CollectionUtils;
  16 +import io.swagger.annotations.Api;
  17 +import io.swagger.annotations.ApiOperation;
  18 +import lombok.extern.slf4j.Slf4j;
  19 +import org.springframework.web.bind.annotation.GetMapping;
  20 +import org.springframework.web.bind.annotation.PostMapping;
  21 +import org.springframework.web.bind.annotation.RequestBody;
  22 +import org.springframework.web.bind.annotation.RequestMapping;
  23 +import org.springframework.web.bind.annotation.RequestParam;
  24 +import org.springframework.web.bind.annotation.RestController;
  25 +import org.springframework.web.multipart.MultipartFile;
  26 +
  27 +import javax.annotation.Resource;
  28 +import javax.servlet.http.HttpServletRequest;
  29 +import java.io.IOException;
  30 +import java.util.List;
  31 +
  32 +import static cn.iocoder.dashboard.common.pojo.CommonResult.success;
  33 +import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.FILE_IS_EMPTY;
  34 +
  35 +/**
  36 + * @author niudehua
  37 + */
  38 +@RestController
  39 +@RequestMapping("/system/user/profile")
  40 +@Api(tags = "用户个人中心")
  41 +@Slf4j
3 42 public class SysUserProfileController {
4 43  
5   -// /**
6   -// * 个人信息
7   -// */
8   -// @GetMapping
9   -// public AjaxResult profile()
10   -// {
11   -// LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
12   -// SysUser user = loginUser.getUser();
13   -// AjaxResult ajax = AjaxResult.success(user);
14   -// ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername()));
15   -// ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername()));
16   -// return ajax;
17   -// }
18   -//
19   -// /**
20   -// * 修改用户
21   -// */
22   -// @Log(title = "个人信息", businessType = BusinessType.UPDATE)
23   -// @PutMapping
24   -// public AjaxResult updateProfile(@RequestBody SysUser user)
25   -// {
26   -// if (userService.updateUserProfile(user) > 0)
27   -// {
28   -// LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
29   -// // 更新缓存用户信息
30   -// loginUser.getUser().setNickName(user.getNickName());
31   -// loginUser.getUser().setPhonenumber(user.getPhonenumber());
32   -// loginUser.getUser().setEmail(user.getEmail());
33   -// loginUser.getUser().setSex(user.getSex());
34   -// tokenService.setLoginUser(loginUser);
35   -// return AjaxResult.success();
36   -// }
37   -// return AjaxResult.error("修改个人信息异常,请联系管理员");
38   -// }
39   -//
40   -// /**
41   -// * 重置密码
42   -// */
43   -// @Log(title = "个人信息", businessType = BusinessType.UPDATE)
44   -// @PutMapping("/updatePwd")
45   -// public AjaxResult updatePwd(String oldPassword, String newPassword)
46   -// {
47   -// LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
48   -// String userName = loginUser.getUsername();
49   -// String password = loginUser.getPassword();
50   -// if (!SecurityUtils.matchesPassword(oldPassword, password))
51   -// {
52   -// return AjaxResult.error("修改密码失败,旧密码错误");
53   -// }
54   -// if (SecurityUtils.matchesPassword(newPassword, password))
55   -// {
56   -// return AjaxResult.error("新密码不能与旧密码相同");
57   -// }
58   -// if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0)
59   -// {
60   -// // 更新缓存用户密码
61   -// loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword));
62   -// tokenService.setLoginUser(loginUser);
63   -// return AjaxResult.success();
64   -// }
65   -// return AjaxResult.error("修改密码异常,请联系管理员");
66   -// }
67   -//
68   -// /**
69   -// * 头像上传
70   -// */
71   -// @Log(title = "用户头像", businessType = BusinessType.UPDATE)
72   -// @PostMapping("/avatar")
73   -// public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws IOException
74   -// {
75   -// if (!file.isEmpty())
76   -// {
77   -// LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
78   -// String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file);
79   -// if (userService.updateUserAvatar(loginUser.getUsername(), avatar))
80   -// {
81   -// AjaxResult ajax = AjaxResult.success();
82   -// ajax.put("imgUrl", avatar);
83   -// // 更新缓存用户头像
84   -// loginUser.getUser().setAvatar(avatar);
85   -// tokenService.setLoginUser(loginUser);
86   -// return ajax;
87   -// }
88   -// }
89   -// return AjaxResult.error("上传图片异常,请联系管理员");
90   -// }
  44 + @Resource
  45 + private SysUserService userService;
  46 + @Resource
  47 + private SysPermissionService permissionService;
  48 + @Resource
  49 + private SysRoleService roleService;
  50 +
  51 + @GetMapping("/get")
  52 + @ApiOperation("获得登录用户信息")
  53 + public CommonResult<SysUserProfileRespVO> profile() {
  54 + // 获取用户信息
  55 + Long userId = SecurityFrameworkUtils.getLoginUserId();
  56 + SysUserDO user = userService.getUser(userId);
  57 + SysUserProfileRespVO userProfileRespVO = SysUserConvert.INSTANCE.convert03(user);
  58 + List<SysRoleDO> userRoles = roleService.listRolesFromCache(permissionService.listUserRoleIs(userId));
  59 + userProfileRespVO.setRoles(CollectionUtils.convertSet(userRoles, SysUserConvert.INSTANCE::convert));
  60 + return success(userProfileRespVO);
  61 + }
  62 +
  63 + @PostMapping("/update")
  64 + @ApiOperation("修改用户个人信息")
  65 + public CommonResult<Boolean> updateProfile(@RequestBody SysUserProfileUpdateReqVO reqVO, HttpServletRequest request) {
  66 + userService.updateUserProfile(reqVO);
  67 + SecurityFrameworkUtils.setLoginUser(SysAuthConvert.INSTANCE.convert(reqVO), request);
  68 + return success(true);
  69 + }
91 70  
  71 + @PostMapping("/upload-avatar")
  72 + @ApiOperation("上传用户个人头像")
  73 + public CommonResult<Boolean> uploadAvatar(@RequestParam("avatarFile") MultipartFile file) throws IOException {
  74 + if (file.isEmpty()) {
  75 + throw ServiceExceptionUtil.exception(FILE_IS_EMPTY);
  76 + }
  77 + userService.updateAvatar(SecurityFrameworkUtils.getLoginUserId(), file.getInputStream());
  78 + return success(true);
  79 + }
92 80 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/vo/user/SysUserProfileRespVO.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.controller.user.vo.user;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.AllArgsConstructor;
  6 +import lombok.Data;
  7 +import lombok.EqualsAndHashCode;
  8 +import lombok.NoArgsConstructor;
  9 +
  10 +import java.util.Set;
  11 +
  12 +
  13 +@ApiModel("用户个人中心信息 Response VO")
  14 +@Data
  15 +@NoArgsConstructor
  16 +@AllArgsConstructor
  17 +@EqualsAndHashCode(callSuper = true)
  18 +public class SysUserProfileRespVO extends SysUserRespVO {
  19 +
  20 + /**
  21 + * 所属角色
  22 + */
  23 + @ApiModelProperty(value = "所属角色", required = true, example = "123456")
  24 + private Set<Role> roles;
  25 +
  26 + @ApiModel("角色")
  27 + @Data
  28 + public static class Role {
  29 +
  30 + @ApiModelProperty(value = "角色编号", required = true, example = "1")
  31 + private Long id;
  32 +
  33 + @ApiModelProperty(value = "角色名称", required = true, example = "普通角色")
  34 + private String name;
  35 +
  36 + }
  37 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/vo/user/SysUserProfileUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.controller.user.vo.user;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +
  7 +import javax.validation.constraints.Email;
  8 +import javax.validation.constraints.NotNull;
  9 +import javax.validation.constraints.Size;
  10 +
  11 +@ApiModel("用户个人信息更新 Request VO")
  12 +@Data
  13 +public class SysUserProfileUpdateReqVO {
  14 +
  15 + @ApiModelProperty(value = "用户编号", required = true, example = "1024")
  16 + @NotNull(message = "用户编号不能为空")
  17 + private Long id;
  18 +
  19 + @ApiModelProperty(value = "用户昵称", required = true, example = "芋艿")
  20 + @Size(max = 30, message = "用户昵称长度不能超过30个字符")
  21 + private String nickname;
  22 +
  23 + @ApiModelProperty(value = "用户邮箱", example = "yudao@iocoder.cn")
  24 + @Email(message = "邮箱格式不正确")
  25 + @Size(max = 50, message = "邮箱长度不能超过50个字符")
  26 + private String email;
  27 +
  28 + @ApiModelProperty(value = "手机号码", example = "15601691300")
  29 + @Size(max = 11, message = "手机号码长度不能超过11个字符")
  30 + private String mobile;
  31 +
  32 + @ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SysSexEnum 枚举类")
  33 + private Integer sex;
  34 +
  35 + @ApiModelProperty(value = "用户头像", example = "http://www.iocoder.cn/xxx.png")
  36 + private String avatar;
  37 +
  38 + @ApiModelProperty(value = "旧密码", required = true, example = "123456")
  39 + private String oldPassword;
  40 +
  41 + @ApiModelProperty(value = "新密码", required = true, example = "654321")
  42 + private String newPassword;
  43 +
  44 +}
... ...
src/main/java/cn/iocoder/dashboard/modules/system/convert/auth/SysAuthConvert.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.system.convert.auth;
3 3 import cn.iocoder.dashboard.framework.security.core.LoginUser;
4 4 import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthMenuRespVO;
5 5 import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthPermissionInfoRespVO;
  6 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
6 7 import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysMenuDO;
7 8 import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO;
8 9 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
... ... @@ -13,26 +14,33 @@ import org.mapstruct.Mapping;
13 14 import org.mapstruct.factory.Mappers;
14 15 import org.slf4j.LoggerFactory;
15 16  
16   -import java.util.*;
  17 +import java.util.ArrayList;
  18 +import java.util.Comparator;
  19 +import java.util.LinkedHashMap;
  20 +import java.util.List;
  21 +import java.util.Map;
17 22  
18 23 @Mapper
19 24 public interface SysAuthConvert {
20 25  
21 26 SysAuthConvert INSTANCE = Mappers.getMapper(SysAuthConvert.class);
22 27  
23   - @Mapping(source = "updateTime", target = "updateTime", ignore = true) // 字段相同,但是含义不同,忽略
  28 + @Mapping(source = "updateTime", target = "updateTime", ignore = true)
  29 + // 字段相同,但是含义不同,忽略
24 30 LoginUser convert(SysUserDO bean);
25 31  
26 32 default SysAuthPermissionInfoRespVO convert(SysUserDO user, List<SysRoleDO> roleList, List<SysMenuDO> menuList) {
27 33 return SysAuthPermissionInfoRespVO.builder()
28   - .user(SysAuthPermissionInfoRespVO.UserVO.builder().nickname(user.getNickname()).avatar(user.getAvatar()).build())
29   - .roles(CollectionUtils.convertSet(roleList, SysRoleDO::getCode))
30   - .permissions(CollectionUtils.convertSet(menuList, SysMenuDO::getPermission))
31   - .build();
  34 + .user(SysAuthPermissionInfoRespVO.UserVO.builder().nickname(user.getNickname()).avatar(user.getAvatar()).build())
  35 + .roles(CollectionUtils.convertSet(roleList, SysRoleDO::getCode))
  36 + .permissions(CollectionUtils.convertSet(menuList, SysMenuDO::getPermission))
  37 + .build();
32 38 }
33 39  
34 40 SysAuthMenuRespVO convertTreeNode(SysMenuDO menu);
35 41  
  42 + LoginUser convert(SysUserProfileUpdateReqVO reqVO);
  43 +
36 44 /**
37 45 * 将菜单列表,构建成菜单树
38 46 *
... ... @@ -47,12 +55,12 @@ public interface SysAuthConvert {
47 55 Map<Long, SysAuthMenuRespVO> treeNodeMap = new LinkedHashMap<>();
48 56 menuList.forEach(menu -> treeNodeMap.put(menu.getId(), SysAuthConvert.INSTANCE.convertTreeNode(menu)));
49 57 // 处理父子关系
50   - treeNodeMap.values().stream().filter(node -> !node.getParentId().equals(MenuIdEnum.ROOT.getId())).forEach((childNode) -> {
  58 + treeNodeMap.values().stream().filter(node -> !node.getParentId().equals(MenuIdEnum.ROOT.getId())).forEach(childNode -> {
51 59 // 获得父节点
52 60 SysAuthMenuRespVO parentNode = treeNodeMap.get(childNode.getParentId());
53 61 if (parentNode == null) {
54 62 LoggerFactory.getLogger(getClass()).error("[buildRouterTree][resource({}) 找不到父资源({})]",
55   - childNode.getId(), childNode.getParentId());
  63 + childNode.getId(), childNode.getParentId());
56 64 return;
57 65 }
58 66 // 将自己添加到父节点中
... ...
src/main/java/cn/iocoder/dashboard/modules/system/convert/user/SysUserConvert.java
1 1 package cn.iocoder.dashboard.modules.system.convert.user;
2 2  
3   -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
  3 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;
  4 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExcelVO;
  5 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO;
  6 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageItemRespVO;
  7 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileRespVO;
  8 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
  9 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
4 10 import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
  11 +import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO;
5 12 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
6 13 import org.mapstruct.Mapper;
7 14 import org.mapstruct.factory.Mappers;
... ... @@ -23,4 +30,12 @@ public interface SysUserConvert {
23 30  
24 31 SysUserDO convert(SysUserImportExcelVO bean);
25 32  
  33 + SysUserProfileRespVO convert03(SysUserDO bean);
  34 +
  35 + SysUserProfileRespVO.Role convert(SysRoleDO bean);
  36 +
  37 + SysUserDO convert(SysUserProfileUpdateReqVO bean);
  38 +
  39 +
  40 +
26 41 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java
... ... @@ -40,6 +40,7 @@ public interface SysErrorCodeConstants {
40 40 ErrorCode USER_EMAIL_EXISTS = new ErrorCode(1002004002, "邮箱已经存在");
41 41 ErrorCode USER_NOT_EXISTS = new ErrorCode(1002004003, "用户不存在");
42 42 ErrorCode USER_IMPORT_LIST_IS_EMPTY = new ErrorCode(1002004004, "导入用户数据不能为空!");
  43 + ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1002004005, "用户密码校验失败");
43 44  
44 45 // ========== 部门模块 1002005000 ==========
45 46 ErrorCode DEPT_NAME_DUPLICATE = new ErrorCode(1002004001, "已经存在该名字的部门");
... ... @@ -74,5 +75,7 @@ public interface SysErrorCodeConstants {
74 75  
75 76 // ========== 文件 1002009000 ==========
76 77 ErrorCode FILE_PATH_EXISTS = new ErrorCode(1002009001, "文件路径已经存在");
  78 + ErrorCode FILE_UPLOAD_FAILED = new ErrorCode(1002009002, "文件上传失败");
  79 + ErrorCode FILE_IS_EMPTY= new ErrorCode(1002009003, "文件为空");
77 80  
78 81 }
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysMenuServiceImpl.java
... ... @@ -206,7 +206,7 @@ public class SysMenuServiceImpl implements SysMenuService {
206 206 *
207 207 * @param menuId 菜单编号
208 208 */
209   - @Transactional
  209 + @Transactional(rollbackFor = Exception.class)
210 210 public void deleteMenu(Long menuId) {
211 211 // 校验更新的菜单是否存在
212 212 if (menuMapper.selectById(menuId) == null) {
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysPermissionServiceImpl.java
... ... @@ -176,7 +176,7 @@ public class SysPermissionServiceImpl implements SysPermissionService {
176 176 }
177 177  
178 178 @Override
179   - @Transactional
  179 + @Transactional(rollbackFor = Exception.class)
180 180 public void assignRoleMenu(Long roleId, Set<Long> menuIds) {
181 181 // 获得角色拥有菜单编号
182 182 Set<Long> dbMenuIds = CollectionUtils.convertSet(roleMenuMapper.selectListByRoleId(roleId),
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysRoleServiceImpl.java
... ... @@ -174,7 +174,7 @@ public class SysRoleServiceImpl implements SysRoleService {
174 174 }
175 175  
176 176 @Override
177   - @Transactional
  177 + @Transactional(rollbackFor = Exception.class)
178 178 public void deleteRole(Long id) {
179 179 // 校验是否可以更新
180 180 this.checkUpdateRole(id);
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserService.java
... ... @@ -2,10 +2,17 @@ package cn.iocoder.dashboard.modules.system.service.user;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.iocoder.dashboard.common.pojo.PageResult;
5   -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
  5 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;
  6 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExportReqVO;
  7 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO;
  8 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportRespVO;
  9 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
  10 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
  11 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
6 12 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
7 13 import cn.iocoder.dashboard.util.collection.CollectionUtils;
8 14  
  15 +import java.io.InputStream;
9 16 import java.util.Collection;
10 17 import java.util.HashMap;
11 18 import java.util.List;
... ... @@ -103,6 +110,14 @@ public interface SysUserService {
103 110 void updateUser(SysUserUpdateReqVO reqVO);
104 111  
105 112 /**
  113 + * 修改用户个人信息
  114 + *
  115 + * @param reqVO 用户个人信息
  116 + * @return 修改结果
  117 + */
  118 + void updateUserProfile(SysUserProfileUpdateReqVO reqVO);
  119 +
  120 + /**
106 121 * 删除用户
107 122 *
108 123 * @param id 用户编号
... ... @@ -112,7 +127,7 @@ public interface SysUserService {
112 127 /**
113 128 * 修改密码
114 129 *
115   - * @param id 用户编号
  130 + * @param id 用户编号
116 131 * @param password 密码
117 132 */
118 133 void updateUserPassword(Long id, String password);
... ... @@ -120,7 +135,7 @@ public interface SysUserService {
120 135 /**
121 136 * 修改密码
122 137 *
123   - * @param id 用户编号
  138 + * @param id 用户编号
124 139 * @param status 状态
125 140 */
126 141 void updateUserStatus(Long id, Integer status);
... ... @@ -128,12 +143,20 @@ public interface SysUserService {
128 143 /**
129 144 * 批量导入用户
130 145 *
131   - * @param importUsers 导入用户列表
  146 + * @param importUsers 导入用户列表
132 147 * @param isUpdateSupport 是否支持更新
133 148 * @return 导入结果
134 149 */
135 150 SysUserImportRespVO importUsers(List<SysUserImportExcelVO> importUsers, boolean isUpdateSupport);
136 151  
  152 + /**
  153 + * 更新用户头像
  154 + *
  155 + * @param id 用户 id
  156 + * @param avatarFile 头像文件
  157 + */
  158 + void updateAvatar(Long id, InputStream avatarFile);
  159 +
137 160 //
138 161 // /**
139 162 // * 修改用户基本信息
... ...
src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserServiceImpl.java
1 1 package cn.iocoder.dashboard.modules.system.service.user;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.io.IoUtil;
  5 +import cn.hutool.core.util.IdUtil;
4 6 import cn.hutool.core.util.StrUtil;
5 7 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
6 8 import cn.iocoder.dashboard.common.exception.ServiceException;
7 9 import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;
8 10 import cn.iocoder.dashboard.common.pojo.PageResult;
9   -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
  11 +import cn.iocoder.dashboard.modules.infra.service.file.InfFileService;
  12 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;
  13 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExportReqVO;
  14 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO;
  15 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportRespVO;
  16 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;
  17 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserProfileUpdateReqVO;
  18 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO;
10 19 import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
11   -import cn.iocoder.dashboard.modules.system.dal.mysql.user.SysUserMapper;
12 20 import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
13 21 import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO;
14 22 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
  23 +import cn.iocoder.dashboard.modules.system.dal.mysql.user.SysUserMapper;
15 24 import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
16 25 import cn.iocoder.dashboard.modules.system.service.dept.SysPostService;
17 26 import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
... ... @@ -22,7 +31,14 @@ import org.springframework.stereotype.Service;
22 31 import org.springframework.transaction.annotation.Transactional;
23 32  
24 33 import javax.annotation.Resource;
25   -import java.util.*;
  34 +import java.io.InputStream;
  35 +import java.util.ArrayList;
  36 +import java.util.Collection;
  37 +import java.util.Collections;
  38 +import java.util.LinkedHashMap;
  39 +import java.util.List;
  40 +import java.util.Map;
  41 +import java.util.Set;
26 42  
27 43 import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
28 44  
... ... @@ -49,18 +65,8 @@ public class SysUserServiceImpl implements SysUserService {
49 65 @Resource
50 66 private PasswordEncoder passwordEncoder;
51 67  
52   -// /**
53   -// * 根据条件分页查询用户列表
54   -// *
55   -// * @param user 用户信息
56   -// * @return 用户信息集合信息
57   -// */
58   -// @Override
59   -// @DataScope(deptAlias = "d", userAlias = "u")
60   -// public List<SysUser> selectUserList(SysUser user)
61   -// {
62   -// return userMapper.selectUserList(user);
63   -// }
  68 + @Resource
  69 + private InfFileService fileService;
64 70  
65 71 @Override
66 72 public SysUserDO getUserByUserName(String username) {
... ... @@ -108,7 +114,7 @@ public class SysUserServiceImpl implements SysUserService {
108 114 return Collections.emptySet();
109 115 }
110 116 Set<Long> deptIds = CollectionUtils.convertSet(deptService.listDeptsByParentIdFromCache(
111   - deptId, true), SysDeptDO::getId);
  117 + deptId, true), SysDeptDO::getId);
112 118 deptIds.add(deptId); // 包括自身
113 119 return deptIds;
114 120 }
... ... @@ -117,7 +123,7 @@ public class SysUserServiceImpl implements SysUserService {
117 123 public Long createUser(SysUserCreateReqVO reqVO) {
118 124 // 校验正确性
119 125 this.checkCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(),
120   - reqVO.getDeptId(), reqVO.getPostIds());
  126 + reqVO.getDeptId(), reqVO.getPostIds());
121 127 // 插入用户
122 128 SysUserDO user = SysUserConvert.INSTANCE.convert(reqVO);
123 129 user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启
... ... @@ -130,13 +136,32 @@ public class SysUserServiceImpl implements SysUserService {
130 136 public void updateUser(SysUserUpdateReqVO reqVO) {
131 137 // 校验正确性
132 138 this.checkCreateOrUpdate(reqVO.getId(), reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(),
133   - reqVO.getDeptId(), reqVO.getPostIds());
  139 + reqVO.getDeptId(), reqVO.getPostIds());
134 140 // 更新用户
135 141 SysUserDO updateObj = SysUserConvert.INSTANCE.convert(reqVO);
136 142 userMapper.updateById(updateObj);
137 143 }
138 144  
139 145 @Override
  146 + public void updateUserProfile(SysUserProfileUpdateReqVO reqVO) {
  147 + // 校验正确性
  148 + this.checkUserExists(reqVO.getId());
  149 + this.checkEmailUnique(reqVO.getId(), reqVO.getEmail());
  150 + this.checkMobileUnique(reqVO.getId(), reqVO.getMobile());
  151 + // 校验填写密码
  152 + String encode = null;
  153 + if (this.checkOldPassword(reqVO.getId(), reqVO.getOldPassword(), reqVO.getNewPassword())) {
  154 + // 更新密码
  155 + encode = passwordEncoder.encode(reqVO.getNewPassword());
  156 + }
  157 + SysUserDO updateObj = SysUserConvert.INSTANCE.convert(reqVO);
  158 + if (StrUtil.isNotBlank(encode)) {
  159 + updateObj.setPassword(encode);
  160 + }
  161 + userMapper.updateById(updateObj);
  162 + }
  163 +
  164 + @Override
140 165 public void deleteUser(Long id) {
141 166 // 校验用户存在
142 167 this.checkUserExists(id);
... ... @@ -278,19 +303,42 @@ public class SysUserServiceImpl implements SysUserService {
278 303 });
279 304 }
280 305  
  306 + /**
  307 + * 校验旧密码、新密码
  308 + *
  309 + * @param id 用户 id
  310 + * @param oldPassword 旧密码
  311 + * @param newPassword 新密码
  312 + * @return 校验结果
  313 + */
  314 + private boolean checkOldPassword(Long id, String oldPassword, String newPassword) {
  315 + if (id == null || StrUtil.isBlank(oldPassword) || StrUtil.isBlank(newPassword)) {
  316 + return false;
  317 + }
  318 + SysUserDO user = userMapper.selectById(id);
  319 + if (user == null) {
  320 + throw ServiceExceptionUtil.exception(USER_NOT_EXISTS);
  321 + }
  322 +
  323 + if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
  324 + throw ServiceExceptionUtil.exception(USER_PASSWORD_FAILED);
  325 + }
  326 + return true;
  327 + }
  328 +
281 329 @Override
282   - @Transactional // 添加事务,异常则回滚所有导入
  330 + @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
283 331 public SysUserImportRespVO importUsers(List<SysUserImportExcelVO> importUsers, boolean isUpdateSupport) {
284 332 if (CollUtil.isEmpty(importUsers)) {
285 333 throw ServiceExceptionUtil.exception(USER_IMPORT_LIST_IS_EMPTY);
286 334 }
287 335 SysUserImportRespVO respVO = SysUserImportRespVO.builder().createUsernames(new ArrayList<>())
288   - .updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build();
  336 + .updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build();
289 337 importUsers.forEach(importUser -> {
290 338 // 校验,判断是否有不符合的原因
291 339 try {
292 340 checkCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(),
293   - importUser.getDeptId(), null);
  341 + importUser.getDeptId(), null);
294 342 } catch (ServiceException ex) {
295 343 respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage());
296 344 return;
... ... @@ -316,4 +364,16 @@ public class SysUserServiceImpl implements SysUserService {
316 364 return respVO;
317 365 }
318 366  
  367 + @Override
  368 + public void updateAvatar(Long id, InputStream avatarFile) {
  369 + this.checkUserExists(id);
  370 + // 存储文件
  371 + String avatar = fileService.createFile(IdUtil.fastUUID(), IoUtil.readBytes(avatarFile));
  372 + // 更新路径
  373 + SysUserDO sysUserDO = new SysUserDO();
  374 + sysUserDO.setId(id);
  375 + sysUserDO.setAvatar(avatar);
  376 + userMapper.updateById(sysUserDO);
  377 + }
  378 +
319 379 }
... ...
src/main/java/cn/iocoder/dashboard/modules/tool/service/codegen/impl/ToolCodegenServiceImpl.java
... ... @@ -109,7 +109,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
109 109 }
110 110  
111 111 @Override
112   - @Transactional
  112 + @Transactional(rollbackFor = Exception.class)
113 113 public List<Long> createCodegenListFromDB(List<String> tableNames) {
114 114 List<Long> ids = new ArrayList<>(tableNames.size());
115 115 // 遍历添加。虽然效率会低一点,但是没必要做成完全批量,因为不会这么大量
... ... @@ -118,7 +118,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
118 118 }
119 119  
120 120 @Override
121   - @Transactional
  121 + @Transactional(rollbackFor = Exception.class)
122 122 public void updateCodegen(ToolCodegenUpdateReqVO updateReqVO) {
123 123 // 校验是否已经存在
124 124 if (codegenTableMapper.selectById(updateReqVO.getTable().getId()) == null) {
... ... @@ -134,7 +134,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
134 134 }
135 135  
136 136 @Override
137   - @Transactional
  137 + @Transactional(rollbackFor = Exception.class)
138 138 public void syncCodegenFromDB(Long tableId) {
139 139 // 校验是否已经存在
140 140 ToolCodegenTableDO table = codegenTableMapper.selectById(tableId);
... ... @@ -149,7 +149,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
149 149 }
150 150  
151 151 @Override
152   - @Transactional
  152 + @Transactional(rollbackFor = Exception.class)
153 153 public void syncCodegenFromSQL(Long tableId, String sql) {
154 154 // 校验是否已经存在
155 155 ToolCodegenTableDO table = codegenTableMapper.selectById(tableId);
... ... @@ -201,7 +201,7 @@ public class ToolCodegenServiceImpl implements ToolCodegenService {
201 201 }
202 202  
203 203 @Override
204   - @Transactional
  204 + @Transactional(rollbackFor = Exception.class)
205 205 public void deleteCodegen(Long tableId) {
206 206 // 校验是否已经存在
207 207 if (codegenTableMapper.selectById(tableId) == null) {
... ...
src/main/resources/application-dev.yaml
... ... @@ -145,14 +145,14 @@ yudao:
145 145 swagger:
146 146 title: 管理后台
147 147 description: 提供管理员管理的所有功能
148   - version: ${yudao.info.base-package}
  148 + version: ${yudao.info.version}
149 149 base-package: ${yudao.info.base-package}.modules
150 150 captcha:
151 151 timeout: 5m
152 152 width: 160
153 153 height: 60
154 154 file:
155   - base-path: http://127.0.0.1:${server.port}/${yudao.web.api-prefix}/infra/file/get/
  155 + base-path: http://127.0.0.1:${server.port}${yudao.web.api-prefix}/system/file/get/
156 156 codegen:
157 157 base-package: ${yudao.info.base-package}
158 158 db-schemas: ${spring.datasource.name}
... ...
src/main/resources/application-local.yaml
... ... @@ -145,14 +145,14 @@ yudao:
145 145 swagger:
146 146 title: 管理后台
147 147 description: 提供管理员管理的所有功能
148   - version: ${yudao.info.base-package}
  148 + version: ${yudao.info.version}
149 149 base-package: ${yudao.info.base-package}.modules
150 150 captcha:
151 151 timeout: 5m
152 152 width: 160
153 153 height: 60
154 154 file:
155   - base-path: http://127.0.0.1:${server.port}/${yudao.web.api-prefix}/infra/file/get/
  155 + base-path: http://127.0.0.1:${server.port}${yudao.web.api-prefix}/system/file/get/
156 156 codegen:
157 157 base-package: ${yudao.info.base-package}
158 158 db-schemas: ${spring.datasource.name}
... ...