fix: 删除用户mobile字段,使用username替代手机号

master
wangrunpu 1 month ago
parent 1fd2c588a7
commit 09cef02a87

@ -83,7 +83,7 @@ public class IotDeviceMessageController {
@PostMapping("/send")
@Operation(summary = "发送消息", description = "可用于设备模拟")
@PreAuthorize("@ss.hasPermission('iot:device:message-end')")
@PreAuthorize("@ss.hasPermission('iot:device:message-send')")
public CommonResult<Boolean> sendDeviceMessage(@Valid @RequestBody IotDeviceMessageSendReqVO sendReqVO) {
deviceMessageService.sendDeviceMessage(BeanUtils.toBean(sendReqVO, IotDeviceMessage.class));
return success(true);

@ -27,4 +27,7 @@ public class AuthLoginRespVO {
@Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime expiresTime;
@Schema(description = "租户id", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
private Long tenantId;
}

@ -19,7 +19,7 @@ public class DustCompanyinfoPageReqVO extends PageParam {
@Schema(description = "营业状态", example = "1")
private String businessStatus;
@Schema(description = "生经营方式")
@Schema(description = "生经营方式")
private String productionMode;
@Schema(description = "行政隶属关系")

@ -29,8 +29,8 @@ public class DustCompanyinfoRespVO {
@DictFormat("business_status") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private String businessStatus;
@Schema(description = "生经营方式", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty(value = "生经营方式", converter = DictConvert.class)
@Schema(description = "生经营方式", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty(value = "生经营方式", converter = DictConvert.class)
@DictFormat("production_mode") // TODO 代码优化:建议设置到对应的 DictTypeConstants 枚举类中
private String productionMode;

@ -21,8 +21,8 @@ public class DustCompanyinfoSaveReqVO {
@NotEmpty(message = "营业状态不能为空")
private String businessStatus;
@Schema(description = "生经营方式", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "生经营方式不能为空")
@Schema(description = "生经营方式", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "生经营方式不能为空")
private String productionMode;
@Schema(description = "行政隶属关系", requiredMode = Schema.RequiredMode.REQUIRED)

@ -29,6 +29,7 @@ public class TenantSaveReqVO {
private String contactName;
@Schema(description = "联系手机", example = "15601691300")
@NotNull(message = "联系手机不能为空")
private String contactMobile;
@Schema(description = "租户状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ -53,19 +54,17 @@ public class TenantSaveReqVO {
// ========== 仅【创建】时,需要传递的字段 ==========
@Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao")
@Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户账号由 数字、字母 组成")
@Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符")
private String username;
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
private String password;
@AssertTrue(message = "用户账号、密码不能为空")
@AssertTrue(message = "手机号、密码不能为空")
@JsonIgnore
public boolean isUsernameValid() {
return id != null // 修改时,不需要传递
|| (ObjectUtil.isAllNotEmpty(username, password)); // 新增时,必须都传递 username、password
|| (ObjectUtil.isAllNotEmpty(contactMobile, password)); // 新增时,必须都传递 username、password
}
}

@ -156,9 +156,9 @@ public class UserController {
public void importTemplate(HttpServletResponse response) throws IOException {
// 手动创建导出 demo
List<UserImportExcelVO> list = Arrays.asList(
UserImportExcelVO.builder().username("yunai").deptId(1L).email("yunai@iocoder.cn").mobile("15601691300")
UserImportExcelVO.builder().username("15601691301").deptId(1L).email("yunai@iocoder.cn")
.nickname("芋道").status(CommonStatusEnum.ENABLE.getStatus()).sex(SexEnum.MALE.getSex()).build(),
UserImportExcelVO.builder().username("yuanma").deptId(2L).email("yuanma@iocoder.cn").mobile("15601701300")
UserImportExcelVO.builder().username("15601701300").deptId(2L).email("yuanma@iocoder.cn")
.nickname("源码").status(CommonStatusEnum.DISABLE.getStatus()).sex(SexEnum.FEMALE.getSex()).build()
);
// 输出

@ -24,7 +24,7 @@ public class UserProfileUpdateReqVO {
@Schema(description = "手机号码", example = "15601691300")
@Length(min = 11, max = 11, message = "手机号长度必须 11 位")
private String mobile;
private String username;
@Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1")
private Integer sex;

@ -18,7 +18,7 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
public class UserImportExcelVO {
@ExcelProperty("登录名称")
@ExcelProperty("手机号码")
private String username;
@ExcelProperty("用户名称")
@ -30,9 +30,6 @@ public class UserImportExcelVO {
@ExcelProperty("用户邮箱")
private String email;
@ExcelProperty("手机号码")
private String mobile;
@ExcelProperty(value = "用户性别", converter = DictConvert.class)
@DictFormat(DictTypeConstants.USER_SEX)
private Integer sex;

@ -21,11 +21,10 @@ public class UserSaveReqVO {
@Schema(description = "用户编号", example = "1024")
private Long id;
@Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao")
@Schema(description = "手机号码", requiredMode = Schema.RequiredMode.REQUIRED, example = "15601691300")
@NotBlank(message = "用户账号不能为空")
@Pattern(regexp = "^[a-zA-Z0-9]+$", message = "用户账号由 数字、字母 组成")
@Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符")
@DiffLogField(name = "用户账号")
@Mobile
@DiffLogField(name = "手机号码")
private String username;
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
@ -51,11 +50,6 @@ public class UserSaveReqVO {
@DiffLogField(name = "用户邮箱")
private String email;
@Schema(description = "手机号码", example = "15601691300")
@Mobile
@DiffLogField(name = "手机号码")
private String mobile;
@Schema(description = "用户性别,参见 SexEnum 枚举类", example = "1")
@DiffLogField(name = "用户性别", function = SexParseFunction.NAME)
private Integer sex;

@ -17,9 +17,9 @@ public interface TenantConvert {
default UserSaveReqVO convert02(TenantSaveReqVO bean) {
UserSaveReqVO reqVO = new UserSaveReqVO();
reqVO.setUsername(bean.getUsername());
reqVO.setUsername(bean.getContactMobile());
reqVO.setPassword(bean.getPassword());
reqVO.setNickname(bean.getContactName()).setMobile(bean.getContactMobile());
reqVO.setNickname(bean.getContactName());
return reqVO;
}

@ -38,7 +38,7 @@ public class DustCompanyinfoDO extends BaseDO {
*/
private String businessStatus;
/**
*
*
*
* {@link TODO production_mode }
*/

@ -64,10 +64,6 @@ public class AdminUserDO extends TenantBaseDO {
*
*/
private String email;
/**
*
*/
private String mobile;
/**
*
*

@ -21,14 +21,9 @@ public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {
return selectOne(AdminUserDO::getEmail, email);
}
default AdminUserDO selectByMobile(String mobile) {
return selectOne(AdminUserDO::getMobile, mobile);
}
default PageResult<AdminUserDO> selectPage(UserPageReqVO reqVO, Collection<Long> deptIds, Collection<Long> userIds) {
return selectPage(reqVO, new LambdaQueryWrapperX<AdminUserDO>()
.likeIfPresent(AdminUserDO::getUsername, reqVO.getUsername())
.likeIfPresent(AdminUserDO::getMobile, reqVO.getMobile())
.eqIfPresent(AdminUserDO::getStatus, reqVO.getStatus())
.betweenIfPresent(AdminUserDO::getCreateTime, reqVO.getCreateTime())
.inIfPresent(AdminUserDO::getDeptId, deptIds)

@ -42,10 +42,10 @@ public class AdminUserParseFunction implements IParseFunction {
}
// 返回格式 芋道源码(13888888888)
String nickname = user.getNickname();
if (StrUtil.isEmpty(user.getMobile())) {
if (StrUtil.isEmpty(user.getUsername())) {
return nickname;
}
return StrUtil.format("{}({})", nickname, user.getMobile());
return StrUtil.format("{}({})", nickname, user.getUsername());
}
}

@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO;
import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
@ -112,6 +113,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
socialUserService.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(),
reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState()));
}
if (ObjectUtil.isNull(TenantContextHolder.getTenantId())) TenantContextHolder.setTenantId(user.getTenantId());
// 创建 Token 令牌,记录登录日志
return createTokenAfterLoginSuccess(user.getId(), reqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME);
}
@ -127,7 +129,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
}
// 登录场景,验证是否存在
if (userService.getUserByMobile(reqVO.getMobile()) == null) {
if (userService.getUserByUsername(reqVO.getMobile()) == null) {
throw exception(AUTH_MOBILE_NOT_EXISTS);
}
// 发送验证码
@ -140,7 +142,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
smsCodeApi.useSmsCode(AuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.ADMIN_MEMBER_LOGIN.getScene(), getClientIP())).checkError();
// 获得用户信息
AdminUserDO user = userService.getUserByMobile(reqVO.getMobile());
AdminUserDO user = userService.getUserByUsername(reqVO.getMobile());
if (user == null) {
throw exception(USER_NOT_EXISTS);
}
@ -289,7 +291,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
@Override
@Transactional(rollbackFor = Exception.class)
public void resetPassword(AuthResetPasswordReqVO reqVO) {
AdminUserDO userByMobile = userService.getUserByMobile(reqVO.getMobile());
AdminUserDO userByMobile = userService.getUserByUsername(reqVO.getMobile());
if (userByMobile == null) {
throw exception(USER_MOBILE_NOT_EXISTS);
}

@ -60,7 +60,7 @@ public class SmsSendServiceImpl implements SmsSendService {
if (StrUtil.isEmpty(mobile)) {
AdminUserDO user = adminUserService.getUser(userId);
if (user != null) {
mobile = user.getMobile();
mobile = user.getUsername();
}
}
// 执行发送

@ -20,6 +20,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantMapper;
import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum;
import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum;
@ -102,6 +103,8 @@ public class TenantServiceImpl implements TenantService {
validTenantNameDuplicate(createReqVO.getName(), null);
// 校验租户域名是否重复
validTenantWebsiteDuplicate(createReqVO.getWebsites(), null);
// 校验租户管理员账号是否重复
validAdminDuplicate(createReqVO);
// 校验套餐被禁用
TenantPackageDO tenantPackage = tenantPackageService.validTenantPackage(createReqVO.getPackageId());
@ -189,6 +192,14 @@ public class TenantServiceImpl implements TenantService {
});
}
private void validAdminDuplicate(TenantSaveReqVO createReqVO) {
TenantUtils.executeIgnore(() -> {
AdminUserDO userByUsername = userService.getUserByUsername(createReqVO.getUsername());
if (ObjectUtil.isNotNull(userByUsername))
throw exception(USER_MOBILE_EXISTS, userByUsername.getUsername());
});
}
@Override
@DSTransactional
public void updateTenantRoleMenu(Long tenantId, Set<Long> menuIds) {

@ -110,14 +110,6 @@ public interface AdminUserService {
*/
AdminUserDO getUserByUsername(String username);
/**
*
*
* @param mobile
* @return
*/
AdminUserDO getUserByMobile(String mobile);
/**
*
*

@ -12,6 +12,7 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils;
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
import cn.iocoder.yudao.module.infra.api.config.ConfigApi;
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.AuthRegisterReqVO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO;
@ -101,7 +102,7 @@ public class AdminUserServiceImpl implements AdminUserService {
});
// 1.2 校验正确性
validateUserForCreateOrUpdate(null, createReqVO.getUsername(),
createReqVO.getMobile(), createReqVO.getEmail(), createReqVO.getDeptId(), createReqVO.getPostIds());
createReqVO.getEmail(), createReqVO.getDeptId(), createReqVO.getPostIds());
// 2.1 插入用户
AdminUserDO user = BeanUtils.toBean(createReqVO, AdminUserDO.class);
user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启
@ -132,7 +133,7 @@ public class AdminUserServiceImpl implements AdminUserService {
}
});
// 1.3 校验正确性
validateUserForCreateOrUpdate(null, registerReqVO.getUsername(), null, null, null, null);
validateUserForCreateOrUpdate(null, registerReqVO.getUsername(), null, null, null);
// 2. 插入用户
AdminUserDO user = BeanUtils.toBean(registerReqVO, AdminUserDO.class);
@ -150,7 +151,7 @@ public class AdminUserServiceImpl implements AdminUserService {
updateReqVO.setPassword(null); // 特殊:此处不更新密码
// 1. 校验正确性
AdminUserDO oldUser = validateUserForCreateOrUpdate(updateReqVO.getId(), updateReqVO.getUsername(),
updateReqVO.getMobile(), updateReqVO.getEmail(), updateReqVO.getDeptId(), updateReqVO.getPostIds());
updateReqVO.getEmail(), updateReqVO.getDeptId(), updateReqVO.getPostIds());
// 2.1 更新用户
AdminUserDO updateObj = BeanUtils.toBean(updateReqVO, AdminUserDO.class);
@ -190,7 +191,7 @@ public class AdminUserServiceImpl implements AdminUserService {
// 校验正确性
validateUserExists(id);
validateEmailUnique(id, reqVO.getEmail());
validateMobileUnique(id, reqVO.getMobile());
validateUsernameUnique(id, reqVO.getUsername());
// 执行更新
userMapper.updateById(BeanUtils.toBean(reqVO, AdminUserDO.class).setId(id));
}
@ -276,11 +277,6 @@ public class AdminUserServiceImpl implements AdminUserService {
return userMapper.selectByUsername(username);
}
@Override
public AdminUserDO getUserByMobile(String mobile) {
return userMapper.selectByMobile(mobile);
}
@Override
public PageResult<AdminUserDO> getUserPage(UserPageReqVO reqVO) {
// 如果有角色编号,查询角色对应的用户编号
@ -366,7 +362,7 @@ public class AdminUserServiceImpl implements AdminUserService {
return deptIds;
}
private AdminUserDO validateUserForCreateOrUpdate(Long id, String username, String mobile, String email,
private AdminUserDO validateUserForCreateOrUpdate(Long id, String username, String email,
Long deptId, Set<Long> postIds) {
// 关闭数据权限,避免因为没有数据权限,查询不到数据,进而导致唯一校验不正确
return DataPermissionUtils.executeIgnore(() -> {
@ -374,8 +370,6 @@ public class AdminUserServiceImpl implements AdminUserService {
AdminUserDO user = validateUserExists(id);
// 校验用户名唯一
validateUsernameUnique(id, username);
// 校验手机号唯一
validateMobileUnique(id, mobile);
// 校验邮箱唯一
validateEmailUnique(id, email);
// 校验部门处于开启状态
@ -400,56 +394,62 @@ public class AdminUserServiceImpl implements AdminUserService {
@VisibleForTesting
void validateUsernameUnique(Long id, String username) {
if (StrUtil.isBlank(username)) {
return;
}
AdminUserDO user = userMapper.selectByUsername(username);
if (user == null) {
return;
}
// 如果 id 为空,说明不用比较是否为相同 id 的用户
if (id == null) {
throw exception(USER_USERNAME_EXISTS);
}
if (!user.getId().equals(id)) {
throw exception(USER_USERNAME_EXISTS);
}
TenantUtils.executeIgnore(() -> {
if (StrUtil.isBlank(username)) {
return;
}
AdminUserDO user = userMapper.selectByUsername(username);
if (user == null) {
return;
}
// 如果 id 为空,说明不用比较是否为相同 id 的用户
if (id == null) {
throw exception(USER_USERNAME_EXISTS);
}
if (!user.getId().equals(id)) {
throw exception(USER_USERNAME_EXISTS);
}
});
}
@VisibleForTesting
void validateEmailUnique(Long id, String email) {
if (StrUtil.isBlank(email)) {
return;
}
AdminUserDO user = userMapper.selectByEmail(email);
if (user == null) {
return;
}
// 如果 id 为空,说明不用比较是否为相同 id 的用户
if (id == null) {
throw exception(USER_EMAIL_EXISTS);
}
if (!user.getId().equals(id)) {
throw exception(USER_EMAIL_EXISTS);
}
TenantUtils.executeIgnore(() -> {
if (StrUtil.isBlank(email)) {
return;
}
AdminUserDO user = userMapper.selectByEmail(email);
if (user == null) {
return;
}
// 如果 id 为空,说明不用比较是否为相同 id 的用户
if (id == null) {
throw exception(USER_EMAIL_EXISTS);
}
if (!user.getId().equals(id)) {
throw exception(USER_EMAIL_EXISTS);
}
});
}
@VisibleForTesting
void validateMobileUnique(Long id, String mobile) {
if (StrUtil.isBlank(mobile)) {
return;
}
AdminUserDO user = userMapper.selectByMobile(mobile);
if (user == null) {
return;
}
// 如果 id 为空,说明不用比较是否为相同 id 的用户
if (id == null) {
throw exception(USER_MOBILE_EXISTS);
}
if (!user.getId().equals(id)) {
throw exception(USER_MOBILE_EXISTS);
}
TenantUtils.executeIgnore(() ->{
if (StrUtil.isBlank(mobile)) {
return;
}
AdminUserDO user = userMapper.selectByUsername(mobile);
if (user == null) {
return;
}
// 如果 id 为空,说明不用比较是否为相同 id 的用户
if (id == null) {
throw exception(USER_MOBILE_EXISTS);
}
if (!user.getId().equals(id)) {
throw exception(USER_MOBILE_EXISTS);
}
});
}
/**
@ -494,7 +494,7 @@ public class AdminUserServiceImpl implements AdminUserService {
}
// 2.1.2 校验,判断是否有不符合的原因
try {
validateUserForCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(),
validateUserForCreateOrUpdate(null, importUser.getUsername(), importUser.getEmail(),
importUser.getDeptId(), null);
} catch (ServiceException ex) {
respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage());

@ -174,6 +174,7 @@ yudao:
tenant: # 多租户相关配置项
enable: true
ignore-urls:
- /admin-api/system/auth/login
ignore-visit-urls:
- /admin-api/system/user/profile/**
- /admin-api/system/auth/**

Loading…
Cancel
Save