mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-11-04 10:57:10 +08:00 
			
		
		
		
	新增:新增修改邮箱功能,并优化部分以往代码(引入 spring-boot-starter-mail 用于发送邮件验证码)
This commit is contained in:
		@@ -1,136 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.auth.config.properties;
 | 
			
		||||
 | 
			
		||||
import java.awt.*;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.Getter;
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
 | 
			
		||||
import org.springframework.boot.context.properties.ConfigurationProperties;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
 | 
			
		||||
import com.wf.captcha.*;
 | 
			
		||||
import com.wf.captcha.base.Captcha;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.util.ReflectUtil;
 | 
			
		||||
import cn.hutool.core.util.StrUtil;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 验证码配置属性
 | 
			
		||||
 *
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 2022/12/11 13:35
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@Component
 | 
			
		||||
@ConfigurationProperties(prefix = "captcha")
 | 
			
		||||
public class CaptchaProperties {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 类型
 | 
			
		||||
     */
 | 
			
		||||
    private CaptchaTypeEnum type;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 缓存键的前缀
 | 
			
		||||
     */
 | 
			
		||||
    private String keyPrefix;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 过期时间
 | 
			
		||||
     */
 | 
			
		||||
    private Long expirationInMinutes = 2L;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 内容长度
 | 
			
		||||
     */
 | 
			
		||||
    private int length = 4;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 宽度
 | 
			
		||||
     */
 | 
			
		||||
    private int width = 111;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 高度
 | 
			
		||||
     */
 | 
			
		||||
    private int height = 36;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 字体
 | 
			
		||||
     */
 | 
			
		||||
    private String fontName;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 字体大小
 | 
			
		||||
     */
 | 
			
		||||
    private int fontSize = 25;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取验证码对象
 | 
			
		||||
     *
 | 
			
		||||
     * @return 验证码对象
 | 
			
		||||
     */
 | 
			
		||||
    public Captcha getCaptcha() {
 | 
			
		||||
        Captcha captcha = ReflectUtil.newInstance(type.getClazz(), this.width, this.height);
 | 
			
		||||
        captcha.setLen(length);
 | 
			
		||||
        if (StrUtil.isNotBlank(this.fontName)) {
 | 
			
		||||
            captcha.setFont(new Font(this.fontName, Font.PLAIN, this.fontSize));
 | 
			
		||||
        }
 | 
			
		||||
        return captcha;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 验证码类型枚举
 | 
			
		||||
     */
 | 
			
		||||
    @Getter
 | 
			
		||||
    @RequiredArgsConstructor
 | 
			
		||||
    public enum CaptchaTypeEnum {
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 算术
 | 
			
		||||
         */
 | 
			
		||||
        ARITHMETIC(ArithmeticCaptcha.class),
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 中文
 | 
			
		||||
         */
 | 
			
		||||
        CHINESE(ChineseCaptcha.class),
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 中文闪图
 | 
			
		||||
         */
 | 
			
		||||
        CHINESE_GIF(ChineseGifCaptcha.class),
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 闪图
 | 
			
		||||
         */
 | 
			
		||||
        GIF(GifCaptcha.class),
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 特殊类型
 | 
			
		||||
         */
 | 
			
		||||
        SPEC(SpecCaptcha.class),;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * 验证码字节码类型
 | 
			
		||||
         */
 | 
			
		||||
        private final Class<? extends Captcha> clazz;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,50 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.auth.model.vo;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import lombok.experimental.Accessors;
 | 
			
		||||
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 验证码信息
 | 
			
		||||
 *
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 2022/12/11 13:55
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@Accessors(chain = true)
 | 
			
		||||
@Schema(description = "验证码信息")
 | 
			
		||||
public class CaptchaVO implements Serializable {
 | 
			
		||||
 | 
			
		||||
    private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 验证码标识
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "验证码标识")
 | 
			
		||||
    private String uuid;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 验证码图片(Base64编码,带图片格式:data:image/gif;base64)
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "验证码图片(Base64编码,带图片格式:data:image/gif;base64)")
 | 
			
		||||
    private String img;
 | 
			
		||||
}
 | 
			
		||||
@@ -52,7 +52,7 @@ public class LoginServiceImpl implements LoginService {
 | 
			
		||||
        // 校验
 | 
			
		||||
        ValidationUtils.exIfNull(sysUser, "用户名或密码错误");
 | 
			
		||||
        Long userId = sysUser.getUserId();
 | 
			
		||||
        ValidationUtils.exIfNotEqual(sysUser.getPassword(), SecureUtils.md5Salt(password, userId.toString()),
 | 
			
		||||
        ValidationUtils.exIfNotEqual(SecureUtils.md5Salt(password, userId.toString()), sysUser.getPassword(),
 | 
			
		||||
            "用户名或密码错误");
 | 
			
		||||
        ValidationUtils.exIfEqual(DisEnableStatusEnum.DISABLE, sysUser.getStatus(), "此账号已被禁用,如有疑问,请联系管理员");
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -52,6 +52,6 @@ public class UpdateBasicInfoRequest implements Serializable {
 | 
			
		||||
     * 性别(0未知 1男 2女)
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "性别(0未知 1男 2女)", type = "Integer", allowableValues = {"0", "1", "2"})
 | 
			
		||||
    @NotNull(message = "非法性别")
 | 
			
		||||
    @NotNull(message = "性别非法")
 | 
			
		||||
    private GenderEnum gender;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,66 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package top.charles7c.cnadmin.system.model.request;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
 | 
			
		||||
import javax.validation.constraints.NotBlank;
 | 
			
		||||
import javax.validation.constraints.Pattern;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
 | 
			
		||||
import org.hibernate.validator.constraints.Length;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.lang.RegexPool;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 修改邮箱信息
 | 
			
		||||
 *
 | 
			
		||||
 * @author Charles7c
 | 
			
		||||
 * @since 2023/1/12 20:18
 | 
			
		||||
 */
 | 
			
		||||
@Data
 | 
			
		||||
@Schema(description = "修改邮箱信息")
 | 
			
		||||
public class UpdateEmailRequest implements Serializable {
 | 
			
		||||
 | 
			
		||||
    private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 新邮箱
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "新邮箱")
 | 
			
		||||
    @NotBlank(message = "新邮箱不能为空")
 | 
			
		||||
    @Pattern(regexp = RegexPool.EMAIL, message = "邮箱格式错误")
 | 
			
		||||
    private String newEmail;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 验证码
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "验证码")
 | 
			
		||||
    @NotBlank(message = "验证码不能为空")
 | 
			
		||||
    @Length(max = 6, message = "验证码非法")
 | 
			
		||||
    private String captcha;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 当前密码(加密后)
 | 
			
		||||
     */
 | 
			
		||||
    @Schema(description = "当前密码(加密后)")
 | 
			
		||||
    @NotBlank(message = "当前密码不能为空")
 | 
			
		||||
    private String currentPassword;
 | 
			
		||||
}
 | 
			
		||||
@@ -67,4 +67,16 @@ public interface UserService {
 | 
			
		||||
     *            用户 ID
 | 
			
		||||
     */
 | 
			
		||||
    void updatePassword(String oldPassword, String newPassword, Long userId);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 修改邮箱
 | 
			
		||||
     *
 | 
			
		||||
     * @param newEmail
 | 
			
		||||
     *            新邮箱
 | 
			
		||||
     * @param currentPassword
 | 
			
		||||
     *            当前密码
 | 
			
		||||
     * @param userId
 | 
			
		||||
     *            用户ID
 | 
			
		||||
     */
 | 
			
		||||
    void updateEmail(String newEmail, String currentPassword, Long userId);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -104,7 +104,7 @@ public class UserServiceImpl implements UserService {
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public void updatePassword(String oldPassword, String newPassword, Long userId) {
 | 
			
		||||
        SysUser sysUser = this.getById(userId);
 | 
			
		||||
        ValidationUtils.exIfNotEqual(sysUser.getPassword(), SecureUtils.md5Salt(oldPassword, userId.toString()),
 | 
			
		||||
        ValidationUtils.exIfNotEqual(SecureUtils.md5Salt(oldPassword, userId.toString()), sysUser.getPassword(),
 | 
			
		||||
            "当前密码错误");
 | 
			
		||||
 | 
			
		||||
        // 更新密码和密码重置时间
 | 
			
		||||
@@ -120,6 +120,27 @@ public class UserServiceImpl implements UserService {
 | 
			
		||||
        LoginHelper.updateLoginUser(loginUser);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public void updateEmail(String newEmail, String currentPassword, Long userId) {
 | 
			
		||||
        // 校验
 | 
			
		||||
        SysUser sysUser = this.getById(userId);
 | 
			
		||||
        ValidationUtils.exIfNotEqual(SecureUtils.md5Salt(currentPassword, userId.toString()), sysUser.getPassword(),
 | 
			
		||||
            "当前密码错误");
 | 
			
		||||
        Long count = userMapper.selectCount(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getEmail, newEmail));
 | 
			
		||||
        ValidationUtils.exIfCondition(() -> count > 0, "邮箱已绑定其他账号,请更换其他邮箱");
 | 
			
		||||
        ValidationUtils.exIfEqual(newEmail, sysUser.getEmail(), "新邮箱不能与当前邮箱相同");
 | 
			
		||||
 | 
			
		||||
        // 更新邮箱
 | 
			
		||||
        userMapper.update(null,
 | 
			
		||||
            new LambdaUpdateWrapper<SysUser>().set(SysUser::getEmail, newEmail).eq(SysUser::getUserId, userId));
 | 
			
		||||
 | 
			
		||||
        // 更新登录用户信息
 | 
			
		||||
        LoginUser loginUser = LoginHelper.getLoginUser();
 | 
			
		||||
        loginUser.setEmail(newEmail);
 | 
			
		||||
        LoginHelper.updateLoginUser(loginUser);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据 ID 查询
 | 
			
		||||
     *
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user