refactor: 发送验证码代码重构优化;扩展Spring Security 支持短信验证码;
This commit is contained in:
@@ -22,11 +22,10 @@ import jakarta.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 角色控制层
|
||||
*
|
||||
* @author Ray
|
||||
* @author Ray.Hao
|
||||
* @since 2022/10/16
|
||||
*/
|
||||
@Tag(name = "03.角色接口")
|
||||
@@ -39,9 +38,9 @@ public class RoleController {
|
||||
|
||||
@Operation(summary = "角色分页列表")
|
||||
@GetMapping("/page")
|
||||
@Log( value = "角色分页列表",module = LogModuleEnum.ROLE)
|
||||
@Log(value = "角色分页列表", module = LogModuleEnum.ROLE)
|
||||
public PageResult<RolePageVO> getRolePage(
|
||||
RolePageQuery queryParams
|
||||
RolePageQuery queryParams
|
||||
) {
|
||||
Page<RolePageVO> result = roleService.getRolePage(queryParams);
|
||||
return PageResult.success(result);
|
||||
@@ -83,11 +82,11 @@ public class RoleController {
|
||||
@Operation(summary = "删除角色")
|
||||
@DeleteMapping("/{ids}")
|
||||
@PreAuthorize("@ss.hasPerm('sys:role:delete')")
|
||||
public Result<?> deleteRoles(
|
||||
public Result<Void> deleteRoles(
|
||||
@Parameter(description = "删除角色,多个以英文逗号(,)拼接") @PathVariable String ids
|
||||
) {
|
||||
boolean result = roleService.deleteRoles(ids);
|
||||
return Result.judge(result);
|
||||
roleService.deleteRoles(ids);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Operation(summary = "修改角色状态")
|
||||
@@ -111,11 +110,11 @@ public class RoleController {
|
||||
|
||||
@Operation(summary = "分配菜单(包括按钮权限)给角色")
|
||||
@PutMapping("/{roleId}/menus")
|
||||
public Result<?> assignMenusToRole(
|
||||
public Result<Void> assignMenusToRole(
|
||||
@PathVariable Long roleId,
|
||||
@RequestBody List<Long> menuIds
|
||||
) {
|
||||
boolean result = roleService.assignMenusToRole(roleId, menuIds);
|
||||
return Result.judge(result);
|
||||
roleService.assignMenusToRole(roleId, menuIds);
|
||||
return Result.success();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.youlai.boot.common.annotation.Log;
|
||||
import com.youlai.boot.common.annotation.RepeatSubmit;
|
||||
import com.youlai.boot.system.enums.ContactType;
|
||||
import com.youlai.boot.common.enums.LogModuleEnum;
|
||||
import com.youlai.boot.common.model.Option;
|
||||
import com.youlai.boot.common.result.PageResult;
|
||||
@@ -45,7 +44,7 @@ import java.util.List;
|
||||
/**
|
||||
* 用户控制层
|
||||
*
|
||||
* @author Ray
|
||||
* @author Ray.Hao
|
||||
* @since 2022/10/16
|
||||
*/
|
||||
@Tag(name = "02.用户接口")
|
||||
@@ -203,39 +202,46 @@ public class UserController {
|
||||
@Operation(summary = "修改密码")
|
||||
@PutMapping(value = "/password")
|
||||
public Result<?> changePassword(
|
||||
@RequestBody PasswordChangeForm data
|
||||
@RequestBody PasswordUpdateForm data
|
||||
) {
|
||||
Long currUserId = SecurityUtils.getUserId();
|
||||
boolean result = userService.changePassword(currUserId, data);
|
||||
return Result.judge(result);
|
||||
}
|
||||
|
||||
@Operation(summary = "发送短信/邮箱验证码")
|
||||
@PostMapping(value = "/send-verification-code")
|
||||
public Result<?> sendVerificationCode(
|
||||
@Parameter(description = "联系方式(手机号码或邮箱地址)", required = true) @RequestParam String contact,
|
||||
@Parameter(description = "联系方式类型(Mobile或Email)", required = true) @RequestParam ContactType contactType
|
||||
@Operation(summary = "发送短信验证码(绑定或更换手机号)")
|
||||
@PostMapping(value = "/mobile/code")
|
||||
public Result<?> sendMobileCode(
|
||||
@Parameter(description = "手机号码", required = true) @RequestParam String mobile
|
||||
) {
|
||||
boolean result = userService.sendVerificationCode(contact, contactType);
|
||||
boolean result = userService.sendMobileCode(mobile);
|
||||
return Result.judge(result);
|
||||
}
|
||||
|
||||
@Operation(summary = "个人中心绑定用户手机号")
|
||||
@Operation(summary = "绑定或更换手机号")
|
||||
@PutMapping(value = "/mobile")
|
||||
public Result<?> bindMobile(
|
||||
@RequestBody @Validated MobileBindingForm data
|
||||
public Result<?> bindOrChangeMobile(
|
||||
@RequestBody @Validated MobileUpdateForm data
|
||||
) {
|
||||
boolean result = userService.bindMobile(data);
|
||||
boolean result = userService.bindOrChangeMobile(data);
|
||||
return Result.judge(result);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "个人中心绑定用户邮箱")
|
||||
@PutMapping(value = "/email")
|
||||
public Result<?> bindEmail(
|
||||
@RequestBody @Validated EmailBindingForm data
|
||||
@Operation(summary = "发送邮箱验证码(绑定或更换邮箱)")
|
||||
@PostMapping(value = "/email/code")
|
||||
public Result<Void> sendEmailCode(
|
||||
@Parameter(description = "邮箱地址", required = true) @RequestParam String email
|
||||
) {
|
||||
boolean result = userService.bindEmail(data);
|
||||
userService.sendEmailCode(email);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Operation(summary = "绑定或更换邮箱")
|
||||
@PutMapping(value = "/email")
|
||||
public Result<?> bindOrChangeEmail(
|
||||
@RequestBody @Validated EmailUpdateForm data
|
||||
) {
|
||||
boolean result = userService.bindOrChangeEmail(data);
|
||||
return Result.judge(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,9 @@ public interface RoleConverter {
|
||||
@Mapping(target = "value", source = "id"),
|
||||
@Mapping(target = "label", source = "name")
|
||||
})
|
||||
Option<Long> entity2Option(Role role);
|
||||
Option<Long> toOption(Role role);
|
||||
|
||||
List<Option<Long>> entities2Options(List<Role> roles);
|
||||
List<Option<Long>> toOptions(List<Role> roles);
|
||||
|
||||
Role toEntity(RoleForm roleForm);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.youlai.boot.system.converter;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.youlai.boot.common.model.Option;
|
||||
import com.youlai.boot.system.model.entity.User;
|
||||
import com.youlai.boot.system.model.vo.UserInfoVO;
|
||||
import com.youlai.boot.system.model.vo.UserPageVO;
|
||||
@@ -14,10 +15,12 @@ import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Mappings;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户对象转换器
|
||||
*
|
||||
* @author haoxr
|
||||
* @author Ray.Hao
|
||||
* @since 2022/6/8
|
||||
*/
|
||||
@Mapper(componentModel = "spring")
|
||||
@@ -43,4 +46,12 @@ public interface UserConverter {
|
||||
UserProfileVO toProfileVO(UserBO bo);
|
||||
|
||||
User toEntity(UserProfileForm formData);
|
||||
|
||||
@Mappings({
|
||||
@Mapping(target = "label", source = "nickname"),
|
||||
@Mapping(target = "value", source = "id")
|
||||
})
|
||||
Option<String> toOption(User entity);
|
||||
|
||||
List<Option<String>> toOptions(List<User> list);
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
package com.youlai.boot.system.enums;
|
||||
|
||||
/**
|
||||
* 联系方式类型
|
||||
*
|
||||
* @author Ray
|
||||
* @since 2.10.0
|
||||
*/
|
||||
public enum ContactType {
|
||||
/**
|
||||
* 手机
|
||||
*/
|
||||
MOBILE,
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
EMAIL
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import lombok.Getter;
|
||||
/**
|
||||
* 字典编码枚举
|
||||
*
|
||||
* @author Ray
|
||||
* @author Ray.Hao
|
||||
* @since 2024/10/30
|
||||
*/
|
||||
@Getter
|
||||
|
||||
@@ -7,7 +7,7 @@ import lombok.Getter;
|
||||
/**
|
||||
* 菜单类型枚举
|
||||
*
|
||||
* @author haoxr
|
||||
* @author Ray.Hao
|
||||
* @since 2022/4/23 9:36
|
||||
*/
|
||||
@Getter
|
||||
|
||||
@@ -7,7 +7,7 @@ import lombok.Getter;
|
||||
/**
|
||||
* 通告发布状态枚举
|
||||
*
|
||||
* @author haoxr
|
||||
* @author Ray.Hao
|
||||
* @since 2024/10/14
|
||||
*/
|
||||
@Getter
|
||||
|
||||
@@ -7,8 +7,8 @@ import lombok.Getter;
|
||||
/**
|
||||
* 通知目标类型枚举
|
||||
*
|
||||
* @author haoxr
|
||||
* @since 2022/10/14
|
||||
* @author Ray.Hao
|
||||
* @since 2024/10/14
|
||||
*/
|
||||
@Getter
|
||||
@Schema(enumAsRef = true)
|
||||
|
||||
@@ -4,14 +4,14 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 绑定邮箱表单
|
||||
* 修改邮箱表单
|
||||
*
|
||||
* @author Ray.Hao
|
||||
* @since 2024/8/19
|
||||
*/
|
||||
@Schema(description = "绑定邮箱表单")
|
||||
@Schema(description = "修改邮箱表单")
|
||||
@Data
|
||||
public class EmailBindingForm {
|
||||
public class EmailUpdateForm {
|
||||
|
||||
@Schema(description = "邮箱")
|
||||
private String email;
|
||||
@@ -4,14 +4,14 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 绑定手机表单
|
||||
* 修改手机表单
|
||||
*
|
||||
* @author Ray
|
||||
* @author Ray.Hao
|
||||
* @since 2024/8/19
|
||||
*/
|
||||
@Schema(description = "绑定手机表单")
|
||||
@Schema(description = "修改手机表单")
|
||||
@Data
|
||||
public class MobileBindingForm {
|
||||
public class MobileUpdateForm {
|
||||
|
||||
@Schema(description = "手机号码")
|
||||
private String mobile;
|
||||
@@ -6,12 +6,12 @@ import lombok.Data;
|
||||
/**
|
||||
* 修改密码表单
|
||||
*
|
||||
* @author Ray
|
||||
* @author Ray.Hao
|
||||
* @since 2024/8/13
|
||||
*/
|
||||
@Schema(description = "修改密码表单")
|
||||
@Data
|
||||
public class PasswordChangeForm {
|
||||
public class PasswordUpdateForm {
|
||||
|
||||
@Schema(description = "原密码")
|
||||
private String oldPassword;
|
||||
@@ -64,10 +64,8 @@ public interface RoleService extends IService<Role> {
|
||||
* 批量删除角色
|
||||
*
|
||||
* @param ids 角色ID,多个使用英文逗号(,)分割
|
||||
* @return
|
||||
*/
|
||||
boolean deleteRoles(String ids);
|
||||
|
||||
void deleteRoles(String ids);
|
||||
|
||||
/**
|
||||
* 获取角色的菜单ID集合
|
||||
@@ -77,15 +75,13 @@ public interface RoleService extends IService<Role> {
|
||||
*/
|
||||
List<Long> getRoleMenuIds(Long roleId);
|
||||
|
||||
|
||||
/**
|
||||
* 修改角色的资源权限
|
||||
*
|
||||
* @param roleId
|
||||
* @param menuIds
|
||||
* @return
|
||||
* @param roleId 角色ID
|
||||
* @param menuIds 菜单ID集合
|
||||
*/
|
||||
boolean assignMenusToRole(Long roleId, List<Long> menuIds);
|
||||
void assignMenusToRole(Long roleId, List<Long> menuIds);
|
||||
|
||||
/**
|
||||
* 获取最大范围的数据权限
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package com.youlai.boot.system.service;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.youlai.boot.system.enums.ContactType;
|
||||
import com.youlai.boot.common.model.Option;
|
||||
import com.youlai.boot.system.model.dto.UserAuthInfo;
|
||||
import com.youlai.boot.system.model.dto.UserExportDTO;
|
||||
@@ -27,16 +25,15 @@ public interface UserService extends IService<User> {
|
||||
/**
|
||||
* 用户分页列表
|
||||
*
|
||||
* @return
|
||||
* @return {@link IPage<UserPageVO>} 用户分页列表
|
||||
*/
|
||||
IPage<UserPageVO> getUserPage(UserPageQuery queryParams);
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户表单数据
|
||||
*
|
||||
* @param userId
|
||||
* @return
|
||||
* @param userId 用户ID
|
||||
* @return {@link UserForm} 用户表单数据
|
||||
*/
|
||||
UserForm getUserFormData(Long userId);
|
||||
|
||||
@@ -45,7 +42,7 @@ public interface UserService extends IService<User> {
|
||||
* 新增用户
|
||||
*
|
||||
* @param userForm 用户表单对象
|
||||
* @return
|
||||
* @return {@link Boolean} 是否新增成功
|
||||
*/
|
||||
boolean saveUser(UserForm userForm);
|
||||
|
||||
@@ -54,7 +51,7 @@ public interface UserService extends IService<User> {
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param userForm 用户表单对象
|
||||
* @return
|
||||
* @return {@link Boolean} 是否修改成功
|
||||
*/
|
||||
boolean updateUser(Long userId, UserForm userForm);
|
||||
|
||||
@@ -63,7 +60,7 @@ public interface UserService extends IService<User> {
|
||||
* 删除用户
|
||||
*
|
||||
* @param idsStr 用户ID,多个以英文逗号(,)分割
|
||||
* @return
|
||||
* @return {@link Boolean} 是否删除成功
|
||||
*/
|
||||
boolean deleteUsers(String idsStr);
|
||||
|
||||
@@ -82,7 +79,7 @@ public interface UserService extends IService<User> {
|
||||
* 获取导出用户列表
|
||||
*
|
||||
* @param queryParams 查询参数
|
||||
* @return
|
||||
* @return {@link List<UserExportDTO>} 导出用户列表
|
||||
*/
|
||||
List<UserExportDTO> listExportUsers(UserPageQuery queryParams);
|
||||
|
||||
@@ -90,14 +87,14 @@ public interface UserService extends IService<User> {
|
||||
/**
|
||||
* 获取登录用户信息
|
||||
*
|
||||
* @return
|
||||
* @return {@link UserInfoVO} 登录用户信息
|
||||
*/
|
||||
UserInfoVO getCurrentUserInfo();
|
||||
|
||||
/**
|
||||
* 获取个人中心用户信息
|
||||
*
|
||||
* @return
|
||||
* @return {@link UserProfileVO} 个人中心用户信息
|
||||
*/
|
||||
UserProfileVO getUserProfile(Long userId);
|
||||
|
||||
@@ -105,7 +102,7 @@ public interface UserService extends IService<User> {
|
||||
* 修改个人中心用户信息
|
||||
*
|
||||
* @param formData 表单数据
|
||||
* @return
|
||||
* @return {@link Boolean} 是否修改成功
|
||||
*/
|
||||
boolean updateUserProfile(UserProfileForm formData);
|
||||
|
||||
@@ -114,43 +111,49 @@ public interface UserService extends IService<User> {
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param data 修改密码表单数据
|
||||
* @return
|
||||
* @return {@link Boolean} 是否修改成功
|
||||
*/
|
||||
boolean changePassword(Long userId, PasswordChangeForm data);
|
||||
boolean changePassword(Long userId, PasswordUpdateForm data);
|
||||
|
||||
/**
|
||||
* 重置用户密码
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param password 重置后的密码
|
||||
* @return
|
||||
* @return {@link Boolean} 是否重置成功
|
||||
*/
|
||||
boolean resetPassword(Long userId, String password);
|
||||
|
||||
/**
|
||||
* 发送验证码
|
||||
* 发送短信验证码(绑定或更换手机号)
|
||||
*
|
||||
* @param contact 联系方式
|
||||
* @param type 联系方式类型
|
||||
* @return
|
||||
* @param mobile 手机号
|
||||
* @return {@link Boolean} 是否发送成功
|
||||
*/
|
||||
boolean sendVerificationCode(String contact, ContactType type);
|
||||
boolean sendMobileCode(String mobile);
|
||||
|
||||
/**
|
||||
* 修改当前用户手机号
|
||||
*
|
||||
* @param data 表单数据
|
||||
* @return
|
||||
* @return {@link Boolean} 是否修改成功
|
||||
*/
|
||||
boolean bindMobile(MobileBindingForm data);
|
||||
boolean bindOrChangeMobile(MobileUpdateForm data);
|
||||
|
||||
/**
|
||||
* 修改当前用户邮箱
|
||||
* 发送邮箱验证码(绑定或更换邮箱)
|
||||
*
|
||||
* @param email 邮箱
|
||||
*/
|
||||
void sendEmailCode(String email);
|
||||
|
||||
/**
|
||||
* 绑定或更换邮箱
|
||||
*
|
||||
* @param data 表单数据
|
||||
* @return {@link Boolean} 是否绑定成功
|
||||
*/
|
||||
boolean bindEmail(EmailBindingForm data);
|
||||
boolean bindOrChangeEmail(EmailUpdateForm data);
|
||||
|
||||
/**
|
||||
* 获取用户选项列表
|
||||
@@ -182,4 +185,6 @@ public interface UserService extends IService<User> {
|
||||
* @return {@link UserAuthInfo}
|
||||
*/
|
||||
UserAuthInfo getUserAuthInfoByMobile(String mobile);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.youlai.boot.common.exception.BusinessException;
|
||||
import com.youlai.boot.system.converter.RoleConverter;
|
||||
import com.youlai.boot.system.mapper.RoleMapper;
|
||||
import com.youlai.boot.system.model.entity.Role;
|
||||
@@ -88,7 +89,7 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
|
||||
);
|
||||
|
||||
// 实体转换
|
||||
return roleConverter.entities2Options(roleList);
|
||||
return roleConverter.toOptions(roleList);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,7 +158,9 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
|
||||
public boolean updateRoleStatus(Long roleId, Integer status) {
|
||||
|
||||
Role role = this.getById(roleId);
|
||||
Assert.isTrue(role != null, "角色不存在");
|
||||
if (role == null) {
|
||||
throw new BusinessException("角色不存在");
|
||||
}
|
||||
|
||||
role.setStatus(status);
|
||||
boolean result = this.updateById(role);
|
||||
@@ -172,10 +175,9 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
|
||||
* 批量删除角色
|
||||
*
|
||||
* @param ids 角色ID,多个使用英文逗号(,)分割
|
||||
* @return {@link Boolean}
|
||||
*/
|
||||
@Override
|
||||
public boolean deleteRoles(String ids) {
|
||||
public void deleteRoles(String ids) {
|
||||
Assert.isTrue(StrUtil.isNotBlank(ids), "删除的角色ID不能为空");
|
||||
List<Long> roleIds = Arrays.stream(ids.split(","))
|
||||
.map(Long::parseLong)
|
||||
@@ -195,7 +197,6 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
|
||||
roleMenuService.refreshRolePermsCache(role.getCode());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,15 +215,15 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
|
||||
*
|
||||
* @param roleId 角色ID
|
||||
* @param menuIds 菜单ID集合
|
||||
* @return {@link Boolean}
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
@CacheEvict(cacheNames = "menu", key = "'routes'")
|
||||
public boolean assignMenusToRole(Long roleId, List<Long> menuIds) {
|
||||
public void assignMenusToRole(Long roleId, List<Long> menuIds) {
|
||||
Role role = this.getById(roleId);
|
||||
Assert.isTrue(role != null, "角色不存在");
|
||||
|
||||
if (role == null) {
|
||||
throw new RuntimeException("角色不存在");
|
||||
}
|
||||
// 删除角色菜单
|
||||
roleMenuService.remove(
|
||||
new LambdaQueryWrapper<RoleMenu>()
|
||||
@@ -239,8 +240,6 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
|
||||
|
||||
// 刷新角色的权限缓存
|
||||
roleMenuService.refreshRolePermsCache(role.getCode());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,14 +11,13 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.youlai.boot.common.constant.RedisConstants;
|
||||
import com.youlai.boot.common.constant.SystemConstants;
|
||||
import com.youlai.boot.core.security.manager.TokenManager;
|
||||
import com.youlai.boot.system.enums.ContactType;
|
||||
import com.youlai.boot.common.model.Option;
|
||||
import com.youlai.boot.shared.mail.service.MailService;
|
||||
import com.youlai.boot.shared.sms.enums.SmsTypeEnum;
|
||||
import com.youlai.boot.shared.sms.service.SmsService;
|
||||
import com.youlai.boot.system.model.entity.User;
|
||||
import com.youlai.boot.system.model.entity.UserRole;
|
||||
import com.youlai.boot.system.model.form.*;
|
||||
import com.youlai.boot.config.property.AliyunSmsProperties;
|
||||
import com.youlai.boot.system.converter.UserConverter;
|
||||
import com.youlai.boot.common.exception.BusinessException;
|
||||
import com.youlai.boot.system.model.vo.UserProfileVO;
|
||||
@@ -40,17 +39,14 @@ import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 用户业务实现类
|
||||
*
|
||||
* @author haoxr
|
||||
* @author Ray.Hao
|
||||
* @since 2022/1/14
|
||||
*/
|
||||
@Service
|
||||
@@ -69,8 +65,6 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
|
||||
private final MailService mailService;
|
||||
|
||||
private final AliyunSmsProperties aliyunSmsProperties;
|
||||
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
|
||||
private final TokenManager tokenManager;
|
||||
@@ -101,7 +95,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
* 获取用户表单数据
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return
|
||||
* @return {@link UserForm} 用户表单数据
|
||||
*/
|
||||
@Override
|
||||
public UserForm getUserFormData(Long userId) {
|
||||
@@ -112,7 +106,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
* 新增用户
|
||||
*
|
||||
* @param userForm 用户表单对象
|
||||
* @return
|
||||
* @return true|false
|
||||
*/
|
||||
@Override
|
||||
public boolean saveUser(UserForm userForm) {
|
||||
@@ -144,7 +138,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param userForm 用户表单对象
|
||||
* @return
|
||||
* @return true|false
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
@@ -206,7 +200,6 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
return userAuthInfo;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据 openid 获取用户认证信息
|
||||
*
|
||||
@@ -225,7 +218,6 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
return userAuthInfo;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据手机号获取用户认证信息
|
||||
*
|
||||
@@ -235,8 +227,13 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
@Override
|
||||
public UserAuthInfo getUserAuthInfoByMobile(String mobile) {
|
||||
UserAuthInfo userAuthInfo = this.baseMapper.getUserAuthInfoByMobile(mobile);
|
||||
|
||||
return null;
|
||||
if (userAuthInfo != null) {
|
||||
Set<String> roles = userAuthInfo.getRoles();
|
||||
// 获取最大范围的数据权限
|
||||
Integer dataScope = roleService.getMaximumDataScope(roles);
|
||||
userAuthInfo.setDataScope(dataScope);
|
||||
}
|
||||
return userAuthInfo;
|
||||
}
|
||||
|
||||
|
||||
@@ -319,7 +316,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
* 获取个人中心用户信息
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @return
|
||||
* @return {@link UserProfileVO} 个人中心用户信息
|
||||
*/
|
||||
@Override
|
||||
public UserProfileVO getUserProfile(Long userId) {
|
||||
@@ -331,7 +328,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
* 修改个人中心用户信息
|
||||
*
|
||||
* @param formData 表单数据
|
||||
* @return
|
||||
* @return true|false
|
||||
*/
|
||||
@Override
|
||||
public boolean updateUserProfile(UserProfileForm formData) {
|
||||
@@ -347,10 +344,10 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param data 密码修改表单数据
|
||||
* @return
|
||||
* @return true|false
|
||||
*/
|
||||
@Override
|
||||
public boolean changePassword(Long userId, PasswordChangeForm data) {
|
||||
public boolean changePassword(Long userId, PasswordUpdateForm data) {
|
||||
|
||||
User user = this.getById(userId);
|
||||
if (user == null) {
|
||||
@@ -387,7 +384,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param password 密码重置表单数据
|
||||
* @return
|
||||
* @return true|false
|
||||
*/
|
||||
@Override
|
||||
public boolean resetPassword(Long userId, String password) {
|
||||
@@ -398,47 +395,38 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送验证码
|
||||
* 发送短信验证码(绑定或更换手机号)
|
||||
*
|
||||
* @param contact 联系方式 手机号/邮箱
|
||||
* @param type 联系方式类型 {@link ContactType}
|
||||
* @return
|
||||
* @param mobile 手机号
|
||||
* @return true|false
|
||||
*/
|
||||
@Override
|
||||
public boolean sendVerificationCode(String contact, ContactType type) {
|
||||
public boolean sendMobileCode(String mobile) {
|
||||
|
||||
// 随机生成4位验证码
|
||||
String code = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
|
||||
// 发送验证码
|
||||
// String code = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
|
||||
// TODO 为了方便测试,验证码固定为 1234,实际开发中在配置了厂商短信服务后,可以使用上面的随机验证码
|
||||
String code = "1234";
|
||||
|
||||
String verificationCodePrefix = null;
|
||||
switch (type) {
|
||||
case MOBILE:
|
||||
// 获取修改密码的模板code
|
||||
String changePasswordSmsTemplateCode = aliyunSmsProperties.getTemplateCodes().get("changePassword");
|
||||
smsService.sendSms(contact, changePasswordSmsTemplateCode, "[{\"code\":\"" + code + "\"}]");
|
||||
verificationCodePrefix = RedisConstants.MOBILE_VERIFICATION_CODE_PREFIX;
|
||||
break;
|
||||
case EMAIL:
|
||||
mailService.sendMail(contact, "验证码", "您的验证码是:" + code);
|
||||
verificationCodePrefix = RedisConstants.EMAIL_VERIFICATION_CODE_PREFIX;
|
||||
break;
|
||||
default:
|
||||
throw new BusinessException("不支持的联系方式类型");
|
||||
Map<String, String> templateParams = new HashMap<>();
|
||||
templateParams.put("code", code);
|
||||
boolean result = smsService.sendSms(mobile, SmsTypeEnum.CHANGE_MOBILE, templateParams);
|
||||
if (result) {
|
||||
// 缓存验证码,5分钟有效,用于更换手机号校验
|
||||
String redisCacheKey = RedisConstants.SMS_CHANGE_CODE_PREFIX + mobile;
|
||||
redisTemplate.opsForValue().set(redisCacheKey, code, 5, TimeUnit.MINUTES);
|
||||
}
|
||||
// 存入 redis 用于校验, 5分钟有效
|
||||
redisTemplate.opsForValue().set(verificationCodePrefix + contact, code, 5, TimeUnit.MINUTES);
|
||||
return true;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改当前用户手机号码
|
||||
* 绑定或更换手机号
|
||||
*
|
||||
* @param form 表单数据
|
||||
* @return
|
||||
* @return true|false
|
||||
*/
|
||||
@Override
|
||||
public boolean bindMobile(MobileBindingForm form) {
|
||||
public boolean bindOrChangeMobile(MobileUpdateForm form) {
|
||||
|
||||
Long currentUserId = SecurityUtils.getUserId();
|
||||
User currentUser = this.getById(currentUserId);
|
||||
|
||||
@@ -447,13 +435,13 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
}
|
||||
|
||||
// 校验验证码
|
||||
String inputVerificationCode = form.getCode();
|
||||
String inputVerifyCode = form.getCode();
|
||||
String mobile = form.getMobile();
|
||||
|
||||
String redisCacheKey = RedisConstants.MOBILE_VERIFICATION_CODE_PREFIX + mobile;
|
||||
String cachedVerificationCode = redisTemplate.opsForValue().get(redisCacheKey);
|
||||
String redisCacheKey = RedisConstants.SMS_CHANGE_CODE_PREFIX + mobile;
|
||||
String cachedVerifyCode = redisTemplate.opsForValue().get(redisCacheKey);
|
||||
|
||||
if (!inputVerificationCode.equals(cachedVerificationCode)) {
|
||||
if (!inputVerifyCode.equals(cachedVerifyCode)) {
|
||||
throw new BusinessException("验证码错误");
|
||||
}
|
||||
|
||||
@@ -465,6 +453,24 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送邮箱验证码(绑定或更换邮箱)
|
||||
*
|
||||
* @param email 邮箱
|
||||
*/
|
||||
@Override
|
||||
public void sendEmailCode(String email) {
|
||||
|
||||
// String code = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
|
||||
// TODO 为了方便测试,验证码固定为 1234,实际开发中在配置了邮箱服务后,可以使用上面的随机验证码
|
||||
String code = "1234";
|
||||
|
||||
mailService.sendMail(email, "邮箱验证码", "您的验证码为:" + code + ",请在5分钟内使用");
|
||||
// 缓存验证码,5分钟有效,用于更换邮箱校验
|
||||
String redisCacheKey = RedisConstants.EMAIL_CHANGE_CODE_PREFIX + email;
|
||||
redisTemplate.opsForValue().set(redisCacheKey, code, 5, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改当前用户邮箱
|
||||
*
|
||||
@@ -472,7 +478,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
* @return true|false
|
||||
*/
|
||||
@Override
|
||||
public boolean bindEmail(EmailBindingForm form) {
|
||||
public boolean bindOrChangeEmail(EmailUpdateForm form) {
|
||||
|
||||
Long currentUserId = SecurityUtils.getUserId();
|
||||
|
||||
User currentUser = this.getById(currentUserId);
|
||||
@@ -480,14 +487,15 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
throw new BusinessException("用户不存在");
|
||||
}
|
||||
|
||||
// 校验验证码
|
||||
String inputVerificationCode = form.getCode();
|
||||
String email = form.getEmail();
|
||||
// 获取前端输入的验证码
|
||||
String inputVerifyCode = form.getCode();
|
||||
|
||||
String redisCacheKey = RedisConstants.EMAIL_VERIFICATION_CODE_PREFIX + email;
|
||||
// 获取缓存的验证码
|
||||
String email = form.getEmail();
|
||||
String redisCacheKey = RedisConstants.EMAIL_CHANGE_CODE_PREFIX + email;
|
||||
String cachedVerifyCode = redisTemplate.opsForValue().get(redisCacheKey);
|
||||
|
||||
if (!inputVerificationCode.equals(cachedVerifyCode)) {
|
||||
if (!inputVerifyCode.equals(cachedVerifyCode)) {
|
||||
throw new BusinessException("验证码错误");
|
||||
}
|
||||
|
||||
@@ -506,11 +514,10 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
*/
|
||||
@Override
|
||||
public List<Option<String>> listUserOptions() {
|
||||
List<User> list = this.list();
|
||||
if (CollectionUtil.isNotEmpty(list)) {
|
||||
return list.stream().map(user -> new Option<>(user.getId().toString(), user.getNickname())).collect(Collectors.toList());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
List<User> list = this.list(new LambdaQueryWrapper<User>()
|
||||
.eq(User::getStatus, 1)
|
||||
);
|
||||
return userConverter.toOptions(list);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user