| | |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.sinata.appointment.constants.BizErrorCode; |
| | | import com.sinata.appointment.dto.ResetPasswordRequest; |
| | | import com.sinata.appointment.dto.CurrentUserPasswordUpdateRequest; |
| | | import com.sinata.appointment.dto.CurrentUserUpdateRequest; |
| | | import com.sinata.appointment.dto.SysUserCreateRequest; |
| | | import com.sinata.appointment.dto.SysUserDetailVo; |
| | | import com.sinata.appointment.dto.SysUserListVo; |
| | |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class SysUserApplicationService { |
| | | private static final String SUPER_ADMIN_USERNAME = "admin"; |
| | | |
| | | private final SysUserMapper sysUserMapper; |
| | | private final SysRoleMapper sysRoleMapper; |
| | |
| | | |
| | | public SysUserDetailVo getDetail(Long id, String uuid) { |
| | | SysUser u = loadActiveWithUuid(id, uuid); |
| | | return toDetailVo(u); |
| | | } |
| | | |
| | | public SysUserDetailVo getCurrentUserDetail(long currentUserId) { |
| | | SysUser u = loadActive(currentUserId); |
| | | return toDetailVo(u); |
| | | } |
| | | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public SysUserDetailVo updateCurrentUser(long currentUserId, CurrentUserUpdateRequest req) { |
| | | SysUser u = loadActive(currentUserId); |
| | | u.setRealName(trimToNull(req.getRealName())); |
| | | u.setMobile(trimToNull(req.getMobile())); |
| | | u.setAvatarUrl(trimToNull(req.getAvatarUrl())); |
| | | sysUserMapper.updateById(u); |
| | | return toDetailVo(u); |
| | | } |
| | | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void updateCurrentPassword(long currentUserId, CurrentUserPasswordUpdateRequest req) { |
| | | SysUser u = loadActive(currentUserId); |
| | | if (!StringUtils.hasText(req.getOldPassword())) { |
| | | throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "原密码不能为空"); |
| | | } |
| | | if (!bcrypt.matches(req.getOldPassword(), u.getPasswordHash())) { |
| | | throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "原密码不正确"); |
| | | } |
| | | validateStrongPassword(req.getNewPassword()); |
| | | if (!Objects.equals(req.getNewPassword(), req.getNewPasswordConfirm())) { |
| | | throw new BizException(BizErrorCode.PASSWORD_CONFIRM_MISMATCH, "两次输入的新密码不一致"); |
| | | } |
| | | u.setPasswordHash(bcrypt.encode(req.getNewPassword())); |
| | | sysUserMapper.updateById(u); |
| | | } |
| | | |
| | | private SysUserDetailVo toDetailVo(SysUser u) { |
| | | SysUserDetailVo vo = new SysUserDetailVo(); |
| | | vo.setId(u.getId()); |
| | | vo.setUuid(u.getUuid()); |
| | |
| | | vo.setMobile(u.getMobile()); |
| | | vo.setAvatarUrl(u.getAvatarUrl()); |
| | | vo.setStatus(u.getStatus()); |
| | | vo.setRoleIds(listRoleIds(id)); |
| | | vo.setRoleIds(listRoleIds(u.getId())); |
| | | return vo; |
| | | } |
| | | |
| | |
| | | if (exists > 0) { |
| | | throw new BizException(BizErrorCode.DUPLICATE_USERNAME, "登录账号已存在"); |
| | | } |
| | | validateStrongPassword(req.getPassword()); |
| | | validateRoleIds(req.getRoleIds()); |
| | | |
| | | SysUser u = new SysUser(); |
| | |
| | | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void resetPassword(Long id, ResetPasswordRequest req) { |
| | | validateStrongPassword(req.getNewPassword()); |
| | | if (!Objects.equals(req.getNewPassword(), req.getNewPasswordConfirm())) { |
| | | throw new BizException(BizErrorCode.PASSWORD_CONFIRM_MISMATCH, "两次输入的新密码不一致"); |
| | | } |
| | |
| | | throw new BizException(BizErrorCode.USER_SELF_FORBIDDEN, "不能禁用自己的账号"); |
| | | } |
| | | SysUser u = loadActiveWithUuid(id, req.getUuid()); |
| | | if (st == 0 && isSuperAdmin(u)) { |
| | | throw new BizException(BizErrorCode.AUTH_FORBIDDEN, "超级管理员账号不可禁用"); |
| | | } |
| | | u.setStatus(st); |
| | | sysUserMapper.updateById(u); |
| | | if (st == 0) { |
| | |
| | | throw new BizException(BizErrorCode.USER_SELF_FORBIDDEN, "不能删除自己的账号"); |
| | | } |
| | | SysUser u = loadActiveWithUuid(id, uuid); |
| | | if (isSuperAdmin(u)) { |
| | | throw new BizException(BizErrorCode.AUTH_FORBIDDEN, "超级管理员账号不可删除"); |
| | | } |
| | | sysUserRoleMapper.delete( |
| | | new LambdaQueryWrapper<SysUserRole>() |
| | | .eq(SysUserRole::getUserId, id) |
| | |
| | | } |
| | | |
| | | private SysUser loadActiveWithUuid(Long id, String uuid) { |
| | | SysUser u = loadActive(id); |
| | | UuidAssert.match(u, uuid); |
| | | return u; |
| | | } |
| | | |
| | | private SysUser loadActive(Long id) { |
| | | SysUser u = sysUserMapper.selectById(id); |
| | | if (u == null || u.getDelFlag() != null && u.getDelFlag() == 1) { |
| | | throw new BizException(BizErrorCode.RESOURCE_VERIFY_FAILED, "资源不存在或无权访问"); |
| | | } |
| | | UuidAssert.match(u, uuid); |
| | | return u; |
| | | } |
| | | |
| | |
| | | String t = s.trim(); |
| | | return t.isEmpty() ? null : t; |
| | | } |
| | | |
| | | private static boolean isSuperAdmin(SysUser u) { |
| | | return u != null && SUPER_ADMIN_USERNAME.equalsIgnoreCase(u.getUsername()); |
| | | } |
| | | |
| | | private static void validateStrongPassword(String password) { |
| | | if (!StringUtils.hasText(password)) { |
| | | throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "密码不能为空"); |
| | | } |
| | | String value = password.trim(); |
| | | boolean ok = |
| | | value.length() >= 12 |
| | | && value.length() <= 64 |
| | | && value.matches(".*[a-z].*") |
| | | && value.matches(".*[A-Z].*") |
| | | && value.matches(".*[^A-Za-z0-9].*"); |
| | | if (!ok) { |
| | | throw new BizException( |
| | | BizErrorCode.AUTH_INVALID_CREDENTIALS, |
| | | "请输入至少12位含大小写字母、特殊字符的密码"); |
| | | } |
| | | } |
| | | } |