增加注册功能

This commit is contained in:
qiurunze 2018-12-11 20:31:22 +08:00
parent 959a7ea460
commit 70293b0499
21 changed files with 3225 additions and 14 deletions

View File

@ -36,6 +36,8 @@
--在sql加上判断防止数据边为负数
--数据库加唯一索引防止用户重复购买
--redis预减库存减少数据库访问 内存标记减少redis访问 请求先入队列缓冲异步下单增强用户体验
#### [注册功能 -- 如果有前端的牛人加入修改几个页面那是再好不过了哈哈哈]()
#### [全局异常处理拦截]()
1.定义全局的异常拦截器
2.定义了全局异常类型

View File

@ -0,0 +1,52 @@
package com.geekq.miaosha.controller;
import com.geekq.miaosha.common.resultbean.ResultGeekQ;
import com.geekq.miaosha.domain.MiaoshaUser;
import com.geekq.miaosha.service.MiaoShaUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import static com.geekq.miaosha.common.enums.ResultStatus.RESIGETER_FAIL;
@Controller
@RequestMapping("/user")
public class RegisterController {
private static Logger logger = LoggerFactory.getLogger(RegisterController.class);
@Autowired
private MiaoShaUserService miaoShaUserService;
@RequestMapping("/do_register")
public String registerIndex(){
return "register";
}
/**
* 注册网站
* @param userName
* @param passWord
* @param salt
* @return
*/
@RequestMapping("/register")
@ResponseBody
public ResultGeekQ<String> register(@RequestParam("username") String userName ,
@RequestParam("password") String passWord,
@RequestParam("salt") String salt,HttpServletResponse response ){
ResultGeekQ<String> result = ResultGeekQ.build();
boolean registerInfo = miaoShaUserService.register(response , userName,passWord,salt);
if(!registerInfo){
result.withError(RESIGETER_FAIL.getCode(),RESIGETER_FAIL.getMessage());
return result;
}
return result;
}
}

View File

@ -6,6 +6,9 @@ import org.apache.ibatis.annotations.*;
@Mapper
public interface MiaoShaUserDao {
@Select("select * from miaosha_user where nickname = #{nickname}")
public MiaoshaUser getByNickname(@Param("nickname") String nickname ) ;
@Select("select * from miaosha_user where id = #{id}")
public MiaoshaUser getById(@Param("id") long id ) ;
@ -14,7 +17,8 @@ public interface MiaoShaUserDao {
public void update(MiaoshaUser toBeUpdate);
@Insert("insert into miaosha_user (id , nickname ,password , salt ,head,register_date,last_login_date)value (#{id},#{nickname},#{password},#{salt},#{nickname},#{head},#{register_date},#{last_login_date}) ")
public long insertMiaoShaUser(MiaoshaUser miaoshaUser);
@Insert("insert into miaosha_user (id , nickname ,password , salt ,head,register_date,last_login_date)value (#{id},#{nickname},#{password},#{salt},#{head},#{registerDate},#{lastLoginDate}) ")
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
public void insertMiaoShaUser(MiaoshaUser miaoshaUser);
}

View File

@ -12,6 +12,7 @@ import java.util.Date;
@AllArgsConstructor
@NoArgsConstructor
public class MiaoshaUser {
private Long id;
private String nickname;
private String password;

View File

@ -3,7 +3,7 @@ package com.geekq.miaosha.redis;
public class MiaoShaUserKey extends BasePrefix{
public static final int TOKEN_EXPIRE = 3600 *24*2;
public static MiaoShaUserKey token = new MiaoShaUserKey(TOKEN_EXPIRE,"tk") ;
public static MiaoShaUserKey getById = new MiaoShaUserKey(0, "id");
public static MiaoShaUserKey getByNickName = new MiaoShaUserKey(0, "nickName");
public MiaoShaUserKey(int expireSeconds ,String prefix) {
super(expireSeconds,prefix);

View File

@ -1,5 +1,6 @@
package com.geekq.miaosha.service;
import com.geekq.miaosha.controller.RegisterController;
import com.geekq.miaosha.dao.MiaoShaUserDao;
import com.geekq.miaosha.domain.MiaoshaUser;
import com.geekq.miaosha.exception.GlobleException;
@ -9,18 +10,23 @@ import com.geekq.miaosha.utils.MD5Utils;
import com.geekq.miaosha.utils.UUIDUtil;
import com.geekq.miaosha.vo.LoginVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import static com.geekq.miaosha.common.enums.ResultStatus.*;
@Service
public class MiaoShaUserService {
public static final String COOKIE_NAME_TOKEN = "token" ;
private static Logger logger = LoggerFactory.getLogger(MiaoShaUserService.class);
@Autowired
private MiaoShaUserDao miaoShaUserDao ;
@ -42,39 +48,64 @@ public class MiaoShaUserService {
}
public MiaoshaUser getById(long id) {
public MiaoshaUser getByNickName(String nickName) {
//取缓存
MiaoshaUser user = redisService.get(MiaoShaUserKey.getById, ""+id, MiaoshaUser.class);
MiaoshaUser user = redisService.get(MiaoShaUserKey.getByNickName, ""+nickName, MiaoshaUser.class);
if(user != null) {
return user;
}
//取数据库
user = miaoShaUserDao.getById(id);
user = miaoShaUserDao.getByNickname(nickName);
if(user != null) {
redisService.set(MiaoShaUserKey.getById, ""+id, user);
redisService.set(MiaoShaUserKey.getByNickName, ""+nickName, user);
}
return user;
}
// http://blog.csdn.net/tTU1EvLDeLFq5btqiK/article/details/78693323
public boolean updatePassword(String token, long id, String formPass) {
public boolean updatePassword(String token, String nickName, String formPass) {
//取user
MiaoshaUser user = getById(id);
MiaoshaUser user = getByNickName(nickName);
if(user == null) {
throw new GlobleException(MOBILE_NOT_EXIST);
}
//更新数据库
MiaoshaUser toBeUpdate = new MiaoshaUser();
toBeUpdate.setId(id);
toBeUpdate.setNickname(nickName);
toBeUpdate.setPassword(MD5Utils.formPassToDBPass(formPass, user.getSalt()));
miaoShaUserDao.update(toBeUpdate);
//处理缓存
redisService.delete(MiaoShaUserKey.getById, ""+id);
redisService.delete(MiaoShaUserKey.getByNickName, ""+nickName);
user.setPassword(toBeUpdate.getPassword());
redisService.set(MiaoShaUserKey.token, token, user);
return true;
}
public boolean register(HttpServletResponse response , String userName , String passWord , String salt) {
MiaoshaUser miaoShaUser = new MiaoshaUser();
miaoShaUser.setNickname(userName);
String DBPassWord = MD5Utils.formPassToDBPass(passWord , salt);
miaoShaUser.setPassword(DBPassWord);
miaoShaUser.setRegisterDate(new Date());
miaoShaUser.setSalt(salt);
miaoShaUser.setNickname(userName);
try {
miaoShaUserDao.insertMiaoShaUser(miaoShaUser);
MiaoshaUser user = miaoShaUserDao.getById(miaoShaUser.getId());
if(user == null){
return false;
}
//生成cookie 将session返回游览器 分布式session
String token= UUIDUtil.uuid();
addCookie(response, token, user);
} catch (Exception e) {
logger.error("注册失败",e);
return false;
}
return true;
}
public boolean login(HttpServletResponse response , LoginVo loginVo) {
if(loginVo ==null){
throw new GlobleException(SYSTEM_ERROR);
@ -82,7 +113,7 @@ public class MiaoShaUserService {
String mobile =loginVo.getMobile();
String password =loginVo.getPassword();
MiaoshaUser user = getById(Long.valueOf(mobile));
MiaoshaUser user = getByNickName(mobile);
if(user == null) {
throw new GlobleException(MOBILE_NOT_EXIST);
}
@ -98,7 +129,6 @@ public class MiaoShaUserService {
addCookie(response, token, user);
return true ;
}
private void addCookie(HttpServletResponse response, String token, MiaoshaUser user) {
redisService.set(MiaoShaUserKey.token, token, user);
Cookie cookie = new Cookie(COOKIE_NAME_TOKEN, token);

View File

@ -0,0 +1,180 @@
header{
width: 100%;
height: 50px;
background: #1e1b29;
border-bottom: solid 4px red;
}
.member_wrap{
}
.header_item{
overflow: hidden;
}
.user_menu{
width: 100%;
height: 170px;
padding: 20px 0;
background:url(../img/banner_bg.html) repeat;
}
.header_item{
width: 980px;
margin: 0 auto;
}
.menu_head{
width: 100px;
height: 100px;
border-radius: 100px;
border: solid 3px #fff;
overflow: hidden;
}
.menu_head img{
width: 100%;
height: 100%;
}
.menu_info{
width:840px;
margin-left: 20px;
}
.info_name{
font-size: 18px;
line-height: 40px;
font-weight: bold;
color: #fff;
}
.info_name_box{
margin-top: 10px;
}
.level{
font-size: 14px;
color: #f60;
font-weight: bold;
}
.info_desc{
margin-top: 10px;
font-size: 14px;
color: #FFF;
}
.banner_menu{
width: 980px;
height: 50px;
margin: 20px auto;
background: #fff;
}
.nav_box{
margin-top: 50px;
}
.nav_box ul {
overflow: hidden;
}
.nav_box ul li{
display: block;
padding: 0 20px;
}
.nav_box ul li a{
color: #fff;
font-size: 16px;
}
.nav_box ul li a:hover{
color: red;
}
.login_wrap{
background: url(../img/logo_bg.jpg) no-repeat center;
background-size: 100%;
}
.logo{
width: 500px;
height: 150px;
margin: 0px auto;
background: url(../img/logowz.png) no-repeat center;
}
.login_box{
width: 360px;
background: #FFFFFF;
margin: 0px auto;
}
.login_title{
font-size: 25px;
text-align: center;
color: #FF7F50;
padding: 15px 0;
width: 300px;
margin: 0 auto;
border-bottom: solid 1px #CCCCCC;
}
.form_text_ipt{
width: 300px;
height: 40px;
border: solid 1px #CCCCCC;
margin: 20px auto 0 auto;
background: #FFFFFF;
}
.form_check_ipt{
width: 300px;
margin: 10px auto;
overflow: hidden;
}
.form_text_ipt input{
width: 290px;
height: 30px;
margin: 5px;
border: none;
font-family: "微软雅黑";
font-size: 15px;
color: #666;
}
.check_left label{
cursor: pointer;
}
.check_left label input{
position: relative;
top: 2px;
}
.form_btn{
width: 300px;
height: 40px;
margin: 10px auto;
}
.form_btn button{
width: 100%;
height: 100%;
border: none;
color: #FFFFFF;
font-size: 14px;
background: #FF7F50;
cursor: pointer;
}
.form_reg_btn{
width: 300px;
margin: 0 auto;
font-size: 14px;
color: #666;
}
.other_login{
overflow: hidden;
width: 300px;
height: 80px;
line-height: 80px;
margin: 0px auto;
}
.other_left{
font-size: 14px;
color: #999;
}
.other_right a{
margin:5px;
color:#636363;
}
.other_right a:hover{
color:#AEEEEE;
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,33 @@
/*reset*/
*{padding: 0;margin: 0;}
html, body, body div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, figure, footer, header, menu, nav, section, time, mark, audio, video, details, summary {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font-weight: normal;
vertical-align: baseline;
background: transparent;
}
article, aside, figure, footer, header, nav, section, details, summary {display: block;}
html, body { height: 100%; color: #333; font-size: 12px; font-family: "微软雅黑",MicrosoftYaHei;}
a { text-decoration: none; color: #3cf; -webkit-tap-highlight-color: transparent;}
li{list-style: none;}
table{border-collapse: collapse;}
input {outline: medium none;font-family: "微软雅黑",MicrosoftYaHei;font-size: 14px;}
button{font-family:"微软雅黑",MicrosoftYaHei;}
em {font-style: normal;}
.wrap{max-width: 100%;min-height: 100%;overflow: hidden;margin: 0 auto;background: #ccc;}
.left{float: left;}
.right{float: right;}
.clear{clear:both;}
.red{color: #f60;}
.ececk_warning{
font-size: 13px;
color: red;
width: 300px;
margin: 0 auto;
display: none;
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -0,0 +1,37 @@
$(function(){
//登录输入框效果
$('.form_text_ipt input').focus(function(){
$(this).parent().css({
'box-shadow':'0 0 3px #bbb',
});
});
$('.form_text_ipt input').blur(function(){
$(this).parent().css({
'box-shadow':'none',
});
//$(this).parent().next().hide();
});
//表单验证
$('.form_text_ipt input').bind('input propertychange',function(){
if($(this).val()==""){
$(this).css({
'color':'red',
});
$(this).parent().css({
'border':'solid 1px red',
});
//$(this).parent().next().find('span').html('helow');
$(this).parent().next().show();
}else{
$(this).css({
'color':'#ccc',
});
$(this).parent().css({
'border':'solid 1px #ccc',
});
$(this).parent().next().hide();
}
});
});

View File

@ -0,0 +1,66 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>登录界面</title>
<link rel="stylesheet" href="css/reset.css" />
<link rel="stylesheet" href="css/common.css" />
<link rel="stylesheet" href="css/font-awesome.min.css" />
</head>
<body>
<div class="wrap login_wrap">
<div class="content">
<div class="logo"></div>
<div class="login_box">
<div class="login_form">
<div class="login_title">
登录
</div>
<form action="#" method="post">
<div class="form_text_ipt">
<input name="username" type="text" placeholder="手机号/邮箱">
</div>
<div class="ececk_warning"><span>手机号/邮箱不能为空</span></div>
<div class="form_text_ipt">
<input name="password" type="password" placeholder="密码">
</div>
<div class="ececk_warning"><span>密码不能为空</span></div>
<div class="form_check_ipt">
<div class="left check_left">
<label><input name="" type="checkbox"> 下次自动登录</label>
</div>
<div class="right check_right">
<a href="#">忘记密码</a>
</div>
</div>
<div class="form_btn">
<button type="button" onclick="javascript:window.location.href='#'">登录</button>
</div>
<div class="form_reg_btn">
<span>还没有帐号?</span><a href="register.html">马上注册</a>
</div>
</form>
<div class="other_login">
<div class="left other_left">
<span>其它登录方式</span>
</div>
<div class="right other_right">
<a href="#"><i class="fa fa-qq fa-2x"></i></a>
<a href="#"><i class="fa fa-weixin fa-2x"></i></a>
<a href="#"><i class="fa fa-weibo fa-2x"></i></a>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="js/jquery.min.js" ></script>
<script type="text/javascript" src="js/common.js" ></script>
<div style="text-align:center;">
<p>更多模板:<a href="http://www.mycodes.net/" target="_blank">源码之家</a></p>
</div>
</body>
</html>

View File

@ -48,7 +48,7 @@
<div class="row">
<div class="col-md-5">
<button class="btn btn-primary btn-block" type="reset" onclick="reset()">重置</button>
<button class="btn btn-primary btn-block" onclick="register()">注册</button>
</div>
<div class="col-md-5">
<button class="btn btn-primary btn-block" type="submit" onclick="login()">登录</button>
@ -58,6 +58,10 @@
</form>
</body>
<script>
function register() {
window.location.href='/user/do_register';
}
function login(){
$("#loginForm").validate({
submitHandler:function(form){

View File

@ -0,0 +1,127 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<script type="text/javascript" th:src="@{/js/common1.js}"></script>
<script type="text/javascript" th:src="@{/js/common.js}"></script>
<script type="text/javascript" th:src="@{/js/jquery.min.js}" ></script>
<script type="text/javascript" th:src="@{/layer/layer.js}"></script>
<!-- md5.js -->
<script type="text/javascript" th:src="@{/js/md5.min.js}"></script>
<meta charset="utf-8" />
<title>注册界面</title>
<link rel="stylesheet" th:href="@{/css/reset.css}" />
<link rel="stylesheet" th:href="@{/css/common.css}" />
<link rel="stylesheet" th:href="@{/css/font-awesome.min.css}" />
<script>
$(function() {// 初始化内容
$("#verifyCodeImg").attr("src", "/miaosha/verifyCode?goodsId=1");
$("#verifyCodeImg").show();
});
function refreshVerifyCode(){
$("#verifyCodeImg").attr("src", "/miaosha/verifyCode?goodsId=1");
};
function register_go() {
var username =$("#username").val();
var inputPass = $("#password").val();
var passwordrepeat = $("#repassword").val();
if(inputPass==""||inputPass==null||inputPass == undefined ){
alert("密码不能为空!");
return ;
}
if(username==""||username==null||username == undefined ){
alert("用户名不能为空!");
return ;
}
if(inputPass!=passwordrepeat){
alert("密码不一致!");
}
var salt = g_passsword_salt;
var str = ""+salt.charAt(0)+salt.charAt(2) + inputPass +salt.charAt(5) + salt.charAt(4);
var password = md5(str);
g_showLoading();
$.ajax({
url: "/user/register",
type: "POST",
data:{
username:$("#username").val(),
password: password,
salt:salt
},
success:function(data){
layer.closeAll();
if(data.code == 0){
layer.msg("成功");
window.location.href="/goods/to_list";
}else{
layer.msg(data.message);
}
},
error:function(){
layer.closeAll();
}
});
}
</script>
</head>
<body>
<form name="registerForm" id="registerForm" method="post" >
<div class="wrap login_wrap">
<div class="content">
<div class="logo"></div>
<div class="login_box">
<div class="login_form">
<div class="login_title">
注册
</div>
<form action="#" method="post">
<div class="form_text_ipt">
<input id="username" name="username" type="text" placeholder="手机号" />
</div>
<div class="ececk_warning"><span>手机号/邮箱不能为空</span></div>
<div class="form_text_ipt">
<input id="password" name="password" type="password" placeholder="密码" />
</div>
<div class="ececk_warning"><span>密码不能为空</span></div>
<div class="form_text_ipt">
<input id="repassword" name="repassword" type="password" placeholder="重复密码" />
</div>
<div class="ececk_warning"><span>密码不能为空</span></div>
<div class="form_text_ipt">
<img id="verifyCodeImg" width="80" height="32" src="/miaosha/verifyCode?goodsId=1" type="text" onclick="refreshVerifyCode()" />
</div>
<div class="form_text_ipt">
<input id="verifyCode" name="verifyCode" type="text" placeholder="验证码"/>
</div>
<div class="ececk_warning"><span>验证码不能为空</span></div>
<div class="form_btn">
<button type="button" onclick="register_go()">注册</button>
</div>
<div class="form_reg_btn">
<span>已有帐号?</span><a href="/login/to_login">马上登录</a>
</div>
</form>
<div class="other_login">
<div class="left other_left">
<span>其它登录方式</span>
</div>
<div class="right other_right">
<a href="#"><i class="fa fa-qq fa-2x"></i></a>
<a href="#"><i class="fa fa-weixin fa-2x"></i></a>
<a href="#"><i class="fa fa-weibo fa-2x"></i></a>
</div>
</div>
</div>
</div>
</div>
</div>
<div style="text-align:center;">
<p>秒杀系统登陆--by GeekQ</p>
</div>
</form>
</body>
</html>