增加了找回密码功能
This commit is contained in:
parent
197c32aff6
commit
78ee5ed462
@ -23,6 +23,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -64,6 +66,14 @@ public class LoginController implements CommunityConstant {
|
|||||||
return "site/login";
|
return "site/login";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进入重置密码界面
|
||||||
|
*/
|
||||||
|
@GetMapping("/resetPwd")
|
||||||
|
public String getResetPwdPage() {
|
||||||
|
return "site/reset-pwd";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册用户
|
* 注册用户
|
||||||
* @param model
|
* @param model
|
||||||
@ -144,6 +154,27 @@ public class LoginController implements CommunityConstant {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证用户输入的图片验证码是否和redis中存入的是否相等
|
||||||
|
*
|
||||||
|
* @param kaptchaOwner 从 cookie 中取出的 kaptchaOwner
|
||||||
|
* @param checkCode 用户输入的图片验证码
|
||||||
|
* @return 失败则返回原因, 验证成功返回 "",
|
||||||
|
*/
|
||||||
|
private String checkKaptchaCode(String kaptchaOwner, String checkCode) {
|
||||||
|
if (StringUtils.isBlank(checkCode)) {
|
||||||
|
return "未发现输入的图片验证码";
|
||||||
|
}
|
||||||
|
String redisKey = RedisKeyUtil.getKaptchaKey(kaptchaOwner);
|
||||||
|
String kaptchaValue = (String) redisTemplate.opsForValue().get(redisKey);
|
||||||
|
if (StringUtils.isBlank(kaptchaValue)) {
|
||||||
|
return "图片验证码过期";
|
||||||
|
} else if (!kaptchaValue.equalsIgnoreCase(checkCode)) {
|
||||||
|
return "图片验证码错误";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户登录
|
* 用户登录
|
||||||
* @param username 用户名
|
* @param username 用户名
|
||||||
@ -206,4 +237,89 @@ public class LoginController implements CommunityConstant {
|
|||||||
return "redirect:/login";
|
return "redirect:/login";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置密码
|
||||||
|
*/
|
||||||
|
@PostMapping("/resetPwd")
|
||||||
|
@ResponseBody
|
||||||
|
public Map<String, Object> resetPwd(@RequestParam("username") String username,
|
||||||
|
@RequestParam("password") String password,
|
||||||
|
@RequestParam("emailVerifyCode") String emailVerifyCode,
|
||||||
|
@RequestParam("kaptchaCode") String kaptcha,
|
||||||
|
Model model,
|
||||||
|
@CookieValue("kaptchaOwner") String kaptchaOwner) {
|
||||||
|
Map<String, Object> map = new HashMap<>(4);
|
||||||
|
// 检查图片验证码
|
||||||
|
String kaptchaCheckRst = checkKaptchaCode(kaptchaOwner, kaptcha);
|
||||||
|
if (StringUtils.isNotBlank(kaptchaCheckRst)) {
|
||||||
|
map.put("status", "1");
|
||||||
|
map.put("errMsg", kaptchaCheckRst);
|
||||||
|
}
|
||||||
|
// 检查邮件验证码
|
||||||
|
String emailVerifyCodeCheckRst = checkRedisResetPwdEmailCode(username, emailVerifyCode);
|
||||||
|
if (StringUtils.isNotBlank(emailVerifyCodeCheckRst)) {
|
||||||
|
map.put("status", "1");
|
||||||
|
map.put("errMsg", emailVerifyCodeCheckRst);
|
||||||
|
}
|
||||||
|
// 执行重置密码操作
|
||||||
|
Map<String, Object> stringObjectMap = userService.doResetPwd(username, password);
|
||||||
|
String usernameMsg = (String) stringObjectMap.get("errMsg");
|
||||||
|
if (StringUtils.isBlank(usernameMsg)) {
|
||||||
|
map.put("status", "0");
|
||||||
|
map.put("msg", "重置密码成功!");
|
||||||
|
map.put("target", "/login");
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送邮件验证码(用于重置密码)
|
||||||
|
*
|
||||||
|
* @param kaptchaOwner 从 cookie 中取出的 kaptchaOwner
|
||||||
|
* @param kaptcha 用户输入的图片验证码
|
||||||
|
* @param username 用户输入的需要找回的账号
|
||||||
|
*/
|
||||||
|
@PostMapping("/sendEmailCodeForResetPwd")
|
||||||
|
@ResponseBody
|
||||||
|
public Map<String, Object> sendEmailCodeForResetPwd(Model model, @CookieValue("kaptchaOwner") String kaptchaOwner,
|
||||||
|
@RequestParam("kaptcha") String kaptcha,
|
||||||
|
@RequestParam("username") String username) {
|
||||||
|
Map<String, Object> map = new HashMap<>(3);
|
||||||
|
// 检查图片验证码
|
||||||
|
String kaptchaCheckRst = checkKaptchaCode(kaptchaOwner, kaptcha);
|
||||||
|
if (StringUtils.isNotBlank(kaptchaCheckRst)) {
|
||||||
|
map.put("status", "1");
|
||||||
|
map.put("errMsg", kaptchaCheckRst);
|
||||||
|
}
|
||||||
|
Map<String, Object> stringObjectMap = userService.doSendEmailCode4ResetPwd(username);
|
||||||
|
String usernameMsg = (String) stringObjectMap.get("errMsg");
|
||||||
|
if (StringUtils.isBlank(usernameMsg)) {
|
||||||
|
map.put("status", "0");
|
||||||
|
map.put("msg", "已经往您的邮箱发送了一封验证码邮件, 请查收!");
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查 邮件 验证码
|
||||||
|
*
|
||||||
|
* @param username 用户名
|
||||||
|
* @param checkCode 用户输入的图片验证码
|
||||||
|
* @return 验证成功 返回"", 失败则返回原因
|
||||||
|
*/
|
||||||
|
private String checkRedisResetPwdEmailCode(String username, String checkCode) {
|
||||||
|
if (StringUtils.isBlank(checkCode)) {
|
||||||
|
return "未发现输入的邮件验证码";
|
||||||
|
}
|
||||||
|
final String redisKey = "EmailCode4ResetPwd:" + username;
|
||||||
|
String emailVerifyCodeInRedis = (String) redisTemplate.opsForValue().get(redisKey);
|
||||||
|
if (StringUtils.isBlank(emailVerifyCodeInRedis)) {
|
||||||
|
return "邮件验证码已过期";
|
||||||
|
} else if (!emailVerifyCodeInRedis.equalsIgnoreCase(checkCode)) {
|
||||||
|
return "邮件验证码错误";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -318,4 +318,69 @@ public class UserService implements CommunityConstant {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送邮箱验证码
|
||||||
|
* @param account 账户名, 目前是用户名
|
||||||
|
*
|
||||||
|
* @return Map<String, Object> 返回错误提示消息,如果返回的 map 为空,则说明发送验证码成功
|
||||||
|
*/
|
||||||
|
public Map<String, Object> doSendEmailCode4ResetPwd(String account) {
|
||||||
|
Map<String, Object> map = new HashMap<>(2);
|
||||||
|
User user = userMapper.selectByName(account);
|
||||||
|
if (user == null) {
|
||||||
|
map.put("errMsg", "未发现账号");
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
final String email = user.getEmail();
|
||||||
|
if (StringUtils.isBlank(email)) {
|
||||||
|
map.put("errMsg", "该账号未绑定邮箱");
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成6位验证码
|
||||||
|
String randomCode = CommunityUtil.getRandomCode(6);
|
||||||
|
// 给注册用户发送激活邮件
|
||||||
|
Context context = new Context();
|
||||||
|
context.setVariable("email", "您的验证码是 " + randomCode);
|
||||||
|
// http://localhost:8080/echo/activation/用户id/激活码
|
||||||
|
String url = domain + contextPath + "/activation/" + user.getId() + "/" + user.getActivationCode();
|
||||||
|
context.setVariable("url", url);
|
||||||
|
String content = templateEngine.process("/mail/activation", context);
|
||||||
|
mailClient.sendMail(email,"重置 Echo 账号密码", content);
|
||||||
|
|
||||||
|
final String redisKey = "EmailCode4ResetPwd:" + account;
|
||||||
|
|
||||||
|
redisTemplate.opsForValue().set(redisKey, randomCode, 600, TimeUnit.SECONDS);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送邮箱验证码
|
||||||
|
* @param account 账户名, 目前是用户名
|
||||||
|
*
|
||||||
|
* @return Map<String, Object> 返回错误提示消息,如果返回的 map 为空,则说明发送验证码成功
|
||||||
|
*/
|
||||||
|
public Map<String, Object> doResetPwd(String account, String password) {
|
||||||
|
Map<String, Object> map = new HashMap<>(2);
|
||||||
|
if (StringUtils.isBlank(password)) {
|
||||||
|
map.put("errMsg", "密码不能为空");
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
User user = userMapper.selectByName(account);
|
||||||
|
if (user == null) {
|
||||||
|
map.put("errMsg", "未发现账号");
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
final String passwordEncode = CommunityUtil.md5(password + user.getSalt());
|
||||||
|
int i = userMapper.updatePassword(user.getId(), passwordEncode);
|
||||||
|
if (i <= 0) {
|
||||||
|
map.put("errMsg", "修改数据库密码错误");
|
||||||
|
} else {
|
||||||
|
clearCache(user.getId());
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package com.greate.community.util;
|
package com.greate.community.util;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import org.apache.commons.lang3.RandomUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.springframework.util.DigestUtils;
|
import org.springframework.util.DigestUtils;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -69,6 +71,20 @@ public class CommunityUtil {
|
|||||||
return json.toJSONString();
|
return json.toJSONString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成指定位数的数字随机数, 最高不超过 9 位
|
||||||
|
*
|
||||||
|
* @param length
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getRandomCode(int length) {
|
||||||
|
Validate.isTrue(length <= 9 && length > 0, "生成数字随机数长度范围应该在 1~9 内, 参数 length : %s", length);
|
||||||
|
int floor = (int) Math.pow(10, length - 1);
|
||||||
|
int codeNum = RandomUtils.nextInt(floor, floor * 10);
|
||||||
|
return Integer.toString(codeNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试
|
* 测试
|
||||||
* @param args
|
* @param args
|
||||||
|
165
src/main/resources/static/js/reset-pwd.js
Normal file
165
src/main/resources/static/js/reset-pwd.js
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
var CONTEXT_PATH = "";
|
||||||
|
|
||||||
|
//V2 static
|
||||||
|
String.format = function () {
|
||||||
|
if (arguments.length == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let str = arguments[0];
|
||||||
|
for (let i = 1; i < arguments.length; i++) {
|
||||||
|
let re = new RegExp('\\{' + i + '\\}', 'gm');
|
||||||
|
str = str.replace(re, arguments[i]);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.fn.parseForm=function(){
|
||||||
|
let serializeObj={};
|
||||||
|
let array=this.serializeArray();
|
||||||
|
let str=this.serialize();
|
||||||
|
$(array).each(function(){
|
||||||
|
if(serializeObj[this.name]){
|
||||||
|
if($.isArray(serializeObj[this.name])){
|
||||||
|
serializeObj[this.name].push(this.value);
|
||||||
|
}else{
|
||||||
|
serializeObj[this.name]=[serializeObj[this.name],this.value];
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
serializeObj[this.name]=this.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return serializeObj;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
$(function(){
|
||||||
|
$("#resetPwd").click(function(){
|
||||||
|
if (check_data()) {
|
||||||
|
$.ajax({
|
||||||
|
type : "post",
|
||||||
|
url : '/resetPwd',
|
||||||
|
data : $('#resetPwdForm').parseForm(),
|
||||||
|
success : function (result) {
|
||||||
|
if (result) {
|
||||||
|
if (result.status === '1') {
|
||||||
|
console.log('重置密码失败');
|
||||||
|
console.log(result.errMsg);
|
||||||
|
} else if (result.status === '0') {
|
||||||
|
console.log('重置密码成功');
|
||||||
|
if (result.msg) {
|
||||||
|
alert(result.msg);
|
||||||
|
location.href='/login';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
$("input").focus(clear_error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function check_data() {
|
||||||
|
if (!$("#password").val()) {
|
||||||
|
$("#password").addClass("is-invalid");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!$("#confirm-password").val().trim()) {
|
||||||
|
$("#confirm-password").addClass("is-invalid");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!$("#username").val()) {
|
||||||
|
$("#username").addClass("is-invalid");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!$("#kaptchaCode").val().trim()) {
|
||||||
|
$("#kaptchaCode").addClass("is-invalid");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!$("#emailVerifyCode").val().trim()) {
|
||||||
|
$("#emailVerifyCode").addClass("is-invalid");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var pwd1 = $("#password").val();
|
||||||
|
var pwd2 = $("#confirm-password").val();
|
||||||
|
if(pwd1 !== pwd2) {
|
||||||
|
$("#confirm-password").addClass("is-invalid");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear_error() {
|
||||||
|
$(this).removeClass("is-invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
function refresh_kaptcha() {
|
||||||
|
var path = CONTEXT_PATH + "/kaptcha?p=" + Math.random();
|
||||||
|
$("#kaptcha").attr("src", path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送邮箱验证码功能
|
||||||
|
function sendEmailCodeForResetPwd() {
|
||||||
|
var kaptchaCode = ($('#kaptchaCode').val() || '').trim();
|
||||||
|
var username = ($('#username').val() || '').trim();
|
||||||
|
if (kaptchaCode && username) {
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url:"/sendEmailCodeForResetPwd",
|
||||||
|
data: {
|
||||||
|
username: username,
|
||||||
|
kaptcha: kaptchaCode
|
||||||
|
},
|
||||||
|
success:function(result){
|
||||||
|
if (result) {
|
||||||
|
if (result.status === '1') {
|
||||||
|
console.log('发送邮箱验证码失败');
|
||||||
|
alert(result.errMsg);
|
||||||
|
} else if (result.status === '0') {
|
||||||
|
console.log('发送邮箱验证码成功');
|
||||||
|
var div = $($('#hideDiv')[0]);
|
||||||
|
var clear = disableForAWhile(div, div);
|
||||||
|
alert(result.msg);
|
||||||
|
} else {
|
||||||
|
console.log(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('请输入完整的请求数据')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 倒计时
|
||||||
|
// hideDiv 和 secondTextDiv 选择器, 仅仅支持jquery选择器的第一个元素
|
||||||
|
function disableForAWhile(hideDiv, secondTextDiv, time, str, style) {
|
||||||
|
// 备份
|
||||||
|
let tmpHtml = hideDiv[0].outerHTML;
|
||||||
|
let secondHtml = secondTextDiv[0].outerHTML;
|
||||||
|
time = time || 60;
|
||||||
|
str = str || '重新发送({1})';
|
||||||
|
style = style || {'pointer-events': 'none', 'cursor': 'not-allowed'};
|
||||||
|
hideDiv.css(style);
|
||||||
|
// clear function
|
||||||
|
secondTextDiv.text(String.format(str, time--));
|
||||||
|
let clear = function (id) {
|
||||||
|
clearInterval(id);
|
||||||
|
hideDiv[0].outerHTML = tmpHtml;
|
||||||
|
secondTextDiv[0].outerHTML = secondHtml;
|
||||||
|
};
|
||||||
|
let innerId = setInterval(() => {
|
||||||
|
secondTextDiv.text(String.format(str, time--));
|
||||||
|
if (time <= 0) {
|
||||||
|
clear(innerId);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
return {
|
||||||
|
clear: () => {
|
||||||
|
clear(innerId)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -57,7 +57,7 @@
|
|||||||
<input type="checkbox" id="rememberMe" name="rememberMe"
|
<input type="checkbox" id="rememberMe" name="rememberMe"
|
||||||
th:checked="${rememberMe}">
|
th:checked="${rememberMe}">
|
||||||
<label class="form-check-label" for="rememberMe">记住我</label>
|
<label class="form-check-label" for="rememberMe">记住我</label>
|
||||||
<a href="forget.html" class="text-danger float-right">忘记密码?</a>
|
<a href="resetPwd" class="text-danger float-right">忘记密码?</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row mt-4">
|
<div class="form-group row mt-4">
|
||||||
|
106
src/main/resources/templates/site/reset-pwd.html
Normal file
106
src/main/resources/templates/site/reset-pwd.html
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<link rel="icon" type="shortcut icon" th:href="@{/img/favicon.ico}"/>
|
||||||
|
<link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap.min.css}"/>
|
||||||
|
<link rel="stylesheet" type="text/css" th:href="@{/css/global.css}"/>
|
||||||
|
<link rel="stylesheet" type="text/css" th:href="@{/css/login.css}"/>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.3.0/font/bootstrap-icons.css">
|
||||||
|
<title>Echo - 注册</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="nk-container">
|
||||||
|
<!-- 头部 -->
|
||||||
|
<header class="bg-dark sticky-top" th:replace="index::header"></header>
|
||||||
|
|
||||||
|
<!-- 内容 -->
|
||||||
|
<div class="main">
|
||||||
|
<div class="container pl-5 pr-5 pt-3 pb-3 mt-3 mb-3">
|
||||||
|
<h3 class="text-center text-info border-bottom pb-3">重置 密码</h3>
|
||||||
|
<form class="mt-5" id="resetPwdForm">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="username" class="col-sm-2 col-form-label text-right">账号或邮箱:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="text" id="username"
|
||||||
|
th:class="|form-control ${usernameMsg!=null ? 'is-invalid' : ''}|"
|
||||||
|
th:value="${user!=null ? user.username : ''}"
|
||||||
|
name="username" placeholder="请输入您的账号或绑定的邮箱!" required>
|
||||||
|
<!--错误提示消息, 当 上面的 input class = is-invalid 时显示-->
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
请输入请输入您的账号或绑定的邮箱
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row mt-4">
|
||||||
|
<label for="password" class="col-sm-2 col-form-label text-right">新密码:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="password" id="password"
|
||||||
|
th:class="|form-control ${passwordMsg!=null ? 'is-invalid' : ''}|"
|
||||||
|
th:value="${user!=null ? user.password : ''}"
|
||||||
|
name="password" placeholder="请输入新密码!" required>
|
||||||
|
<!--错误提示消息-->
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
请输入新密码
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row mt-4">
|
||||||
|
<label for="confirm-password" class="col-sm-2 col-form-label text-right">确认新密码:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input type="password" class="form-control" id="confirm-password"
|
||||||
|
th:value="${user!=null ? user.password : ''}"
|
||||||
|
placeholder="请再次输入新密码!" required>
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
请确任两次密码是否匹配
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row mt-4">
|
||||||
|
<label for="kaptchaCode" class="col-sm-2 col-form-label text-right">验证码:</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input type="text" th:class="|form-control ${codeMsg != null ? 'is-invalid' : ''}|"
|
||||||
|
id="kaptchaCode" name="kaptchaCode" placeholder="请输入验证码!">
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
请输入图片验证码
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<a href="javascript:refresh_kaptcha();" class="font-size-12 align-bottom">
|
||||||
|
<img th:src="@{/kaptcha}" id = "kaptcha" style="width:100px;height:40px;" class="mr-2"/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row mt-4">
|
||||||
|
<label for="emailVerifyCode" class="col-sm-2 col-form-label text-right">邮箱验证码:</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input type="text" class="form-control" id="emailVerifyCode" name="emailVerifyCode" placeholder="请输入邮箱验证码!">
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
请输入邮箱验证码
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<a id="hideDiv" href="javascript:sendEmailCodeForResetPwd();" class="btn btn-info form-control">获取邮箱验证码</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row mt-4">
|
||||||
|
<div class="col-sm-2"></div>
|
||||||
|
<div class="col-sm-10 text-center">
|
||||||
|
<button type="button" id="resetPwd" class="btn btn-info text-white form-control">重置密码</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 尾部 -->
|
||||||
|
<footer class="bg-dark" th:replace="index::footer"></footer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script th:src="@{/js/jquery-3.1.0.min.js}"></script>
|
||||||
|
<script th:src="@{/js/popper.min.js}"></script>
|
||||||
|
<script th:src="@{/js/bootstrap.min.js}"></script>
|
||||||
|
<script th:src="@{/js/reset-pwd.js}"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
x
Reference in New Issue
Block a user