p2p手机绑定
本文工具类 http://www.cnblogs.com/jokerq/p/8590498.html
1.需求分析

2.设计分析

3.前台页面(freemarker)
<script type="text/javascript">
$(function(){
if($("#showBindPhoneModal").size()>0){
//点击立刻绑定,弹出模式窗口
$("#showBindPhoneModal").click(function(){
$("#bindPhoneForm")[0].reset();
$("#bindPhoneModal").modal("show");
});
//给发送短信按钮添加时间
$("#sendVerifyCode").click(function(){
var _this=$(this);
_this.attr("disabled",true);
//1,发送一个Ajax请求;
$.ajax({
url:"/sendVerifyCode.do",
dataType:"json",
type:"POST",
data:{phoneNumber:$("#phoneNumber").val()},
success:function(data){
if(data.success){
var sec=90;
var timer=window.setInterval(function(){
sec--;
if(sec>0){
_this.text(sec+"秒重新发送");
}else{
//去掉定时器
window.clearInterval(timer);
_this.text("重新发送验证码");
_this.attr("disabled",false);
}
},1000);
}else{
$.messager.popup(data.msg);
_this.attr("disabled",false);
}
}
});
}); //给提交绑定窗口按钮添加事件
$("#bindPhoneForm").ajaxForm(function(data){
if(data.success){
window.location.reload();
}else{
$.messager.popup(data.msg);
}
});
$("#bindPhone").click(function(){
$("#bindPhoneForm").submit();
});
}; })
</script>
<div class="col-sm-4">
<div class="el-accoun-auth">
<div class="el-accoun-auth-left">
<img src="data:images/shouji.jpg" />
</div>
<div class="el-accoun-auth-right">
<h5>手机认证</h5>
<#if userinfo.isBindPhone >
<p>
已认证
<a href="#">查看</a>
</p>
<#else>
<p>
未认证
<a href="javascript:;" id="showBindPhoneModal">立刻绑定</a><!--弹出模态框-->
</p>
</#if>
</div>
<div class="clearfix"></div>
<p class="info">可以收到系统操作信息,并增加使用安全性</p>
</div>
</div>
<#if !userinfo.isBindPhone>
<div class="modal fade" id="bindPhoneModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="exampleModalLabel">绑定手机</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" id="bindPhoneForm" method="post" action="/bindPhone.do">
<div class="form-group">
<label for="phoneNumber" class="col-sm-2 control-label">手机号:</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="phoneNumber" name="phoneNumber" />
<button id="sendVerifyCode" class="btn btn-primary" type="button" autocomplate="off">发送验证码</button>
</div>
</div>
<div class="form-group">
<label for="verifyCode" class="col-sm-2 control-label">验证码:</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="verifyCode" name="verifyCode" />
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="bindPhone">保存</button>
</div>
</div>
</div>
</div>
</#if>
4.发送验证码Controller
package com.xmg.p2p.base.controller; 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.ResponseBody; import com.xmg.p2p.base.service.IVerifyCodeService;
import com.xmg.p2p.base.service.impl.VerifyCodeServiceImpl;
import com.xmg.p2p.base.util.JSONResult; /**
* 验证码相关Controller
* @author Administrator
*
*/
@Controller
public class VerifyCodeController { @Autowired
private IVerifyCodeService verifyCodeService; @RequestMapping("/sendVerifyCode")
@ResponseBody
public JSONResult sendVerifyCode(String phoneNumber){
JSONResult json = new JSONResult();
try {
verifyCodeService.sendVerifyCode(phoneNumber);
} catch (RuntimeException e) {
json.setMsg(e.getMessage());
json.setSuccess(false);
}
return json;
} }
5.发送验证码ServiceImpl
package com.xmg.p2p.base.service.impl; import java.util.Date;
import java.util.UUID; import org.springframework.stereotype.Service; import com.xmg.p2p.base.service.IVerifyCodeService;
import com.xmg.p2p.base.util.DateUtil;
import com.xmg.p2p.base.util.UserContext;
import com.xmg.p2p.base.vo.VerifyCodeVO; @Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
@Value("${sms.username}")
private String username;
@Value("${sms.password}")
private String password;
@Value("${sms.apikey}")
private String apiKey;
@Value("${sms.url}")
private String url;
@Override
public void sendVerifyCode(String phoneNumber) {
//判断当前是否能够发送短信
//从Session中获取最后一次发送短信的事件
VerifyCodeVO vc = UserContext.getCurrentVerifyCode();
if (vc==null || DateUtil.secondsBetween(new Date(), vc.getLastSendTime()) > 90) {
//正常发送验证码短信
//生成一个验证码
String verifyCode = UUID.randomUUID().toString().substring(0,4);
//发送短信
//System.out.println("给手机 "+phoneNumber+"发送验证码:"+verifyCode);
//通过URL 得到一个HTTPURLConnetion连接对象
try {
//创建一个URL对象
URL url = new URL(this.url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//拼接POST请求的内容
StringBuilder content = new StringBuilder(100)
.append("username=").append(username)
.append("&password=").append(password)
.append("&apikey=").append(apiKey)
.append("&mobile=").append(phoneNumber)
.append("&content=")
.append("验证码是:").append(verifyCode).append(",请在5分钟内使用");
//发送post请求,POST或者GET一定要大写
conn.setRequestMethod("POST");
//设置POST请求是有请求体的
conn.setDoOutput(true);
//写入post请求体
conn.getOutputStream().write(content.toString().getBytes());
//得到响应流(其实就已经发送了)
String response = StreamUtils.copyToString(conn.getInputStream(), Charset.forName("UTF-8"));
if (response.startsWith("success:")) {
//发送成功
//把手机号码 验证码 发送时间 装配到Vo中 并保存到session
vc = new VerifyCodeVO();
vc.setLastSendTime(new Date());
vc.setPhoneNumber(phoneNumber);
vc.setVerifyCode(verifyCode);
UserContext.putVerifyCode(vc);
}else {
//发送失败
throw new RuntimeException();
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("短信发送失败");
}
}else {
throw new RuntimeException("发送过于频繁");
}
}
@Override
public boolean verify(String phoneNumber, String verifyCode) {
VerifyCodeVO vc = UserContext.getCurrentVerifyCode();
if (vc!=null //发送了验证码
&& vc.getPhoneNumber().equals(phoneNumber)//手机号
&& vc.getVerifyCode().equalsIgnoreCase(verifyCode)//验证码
&& DateUtil.secondsBetween(new Date(), vc.getLastSendTime()) <= BidConst.VERIFYCODE_VAILDATE_SECOND //验证码时间小于5分钟
) {
return true;
}
return false;
}
}
(发送短信给短信网关需要写配置文件指定信息)
sms.username=xmg
sms.password=1111
sms.apikey=1111
#模拟短信网关
sms.url=http://localhost:8082/send.do
6.存放验证码相关内容的vo
package com.xmg.p2p.base.vo; import java.util.Date; import lombok.Getter;
/**
* 存放验证码相关内容 这个对象时放在Session中的
*
* @author Administrator
*
*/ public class VerifyCodeVO {
private String verifyCode;//验证码
private String phoneNumber;//发送验证码的手机号
private Date lastSendTime;//最后成功发送验证码的时间
public String getVerifyCode() {
return verifyCode;
}
public void setVerifyCode(String verifyCode) {
this.verifyCode = verifyCode;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public Date getLastSendTime() {
return lastSendTime;
}
public void setLastSendTime(Date lastSendTime) {
this.lastSendTime = lastSendTime;
} }
7.提交绑定窗口Controller
package com.xmg.p2p.base.controller; import javax.jws.WebParam.Mode; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import com.xmg.p2p.base.domain.Logininfo;
import com.xmg.p2p.base.service.IAccountService;
import com.xmg.p2p.base.service.IUserinfoService;
import com.xmg.p2p.base.util.JSONResult;
import com.xmg.p2p.base.util.RequireLogin;
import com.xmg.p2p.base.util.UserContext; @Controller
public class PersonalController { @Autowired
private IUserinfoService userinfoService; @RequestMapping("bindPhone")
@ResponseBody
public JSONResult bindPhone(String phoneNumber,String verifyCode){
JSONResult json = new JSONResult();
try {
userinfoService.bindPhone(phoneNumber,verifyCode);
} catch (RuntimeException e) {
json.setSuccess(false);
json.setMsg(e.getMessage());
}
return json;
}
}
8.提交绑定窗口serviceImpl
package com.xmg.p2p.base.service.impl; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.xmg.p2p.base.domain.Userinfo;
import com.xmg.p2p.base.mapper.UserinfoMapper;
import com.xmg.p2p.base.service.IUserinfoService;
import com.xmg.p2p.base.service.IVerifyCodeService;
import com.xmg.p2p.base.util.BitStatesUtils;
import com.xmg.p2p.base.util.UserContext; @Service
public class UserinfoServiceImpl implements IUserinfoService { @Autowired
private UserinfoMapper userinfoMapper; @Autowired
private IVerifyCodeService verifyCodeService; @Override
public void update(Userinfo userinfo) {
int ret = userinfoMapper.updateByPrimaryKey(userinfo);
if (ret == 0) {
throw new RuntimeException("乐观锁失败,Userinfo:"+userinfo.getId());
}
}
@Override
public void bindPhone(String phoneNumber, String verifyCode) {
//如果用户没有绑定验证码
Userinfo current = get(UserContext.getCurrent().getId());
if (!current.getIsBindPhone()) {
//验证验证码合法
boolean ret = this.verifyCodeService.verify(phoneNumber,verifyCode);//在VerifyCodeServiceImpl中新加方法
if (ret) {
//如果合法 给用户绑定手机
//current.setBitState(BitStatesUtils.addState(current.getBitState(), BitStatesUtils.OP_BIND_PHONE));
current.addState(BitStatesUtils.OP_BIND_PHONE);//上行过于复杂 在Userinfo中添加方法进行此处简化
this.update(current);
}else {
//否则抛出异常
throw new RuntimeException("绑定手机失败!"); } } } }
(domain Userinfo类)
package com.xmg.p2p.base.domain; import com.alibaba.druid.support.logging.Log;
import com.xmg.p2p.base.util.BitStatesUtils; import lombok.Getter;
import lombok.Setter; /**
* 用户相关信息
* @author Administrator
*
*/
@Getter
@Setter
public class Userinfo extends BaseDomain {
/**
* UserInfo:
属性名称 属性类型 属性说明
Version Int 版本号,用作乐观锁
bitState Long 用户状态值
realName String 用户实名值(冗余数据)
idNumber String 用户身份证号(冗余数据)
phoneNumber String 用户电话
incomeGrade SystemDictionaryItem 收入
Marriage SystemDictionaryItem 婚姻情况
kidCount SystemDictionaryItem 子女情况
educationBackground SystemDictionaryItem 学历
houseCondition SystemDictionaryItem 住房条件
*/
private int version; //版本号
private long bitState;//用户状态吗
private String realName;
private String idNumber;
private String phoneNumber;
private SystemDictionaryItem incomeGrade;//收入
private SystemDictionaryItem marriage;//
private SystemDictionaryItem kidCount;//
private SystemDictionaryItem educationBackground;//
private SystemDictionaryItem houseCondition;// public void addState(long state){
this.setBitState(BitStatesUtils.addState(this.getBitState(),state));
} // 判断是否已经绑定了手机
public boolean getIsBindPhone() {
return BitStatesUtils.hasState(this.bitState,
BitStatesUtils.OP_BIND_PHONE);
} // 判断是否已经绑定看了银行卡
public boolean getIsBindBank() {
return BitStatesUtils.hasState(this.bitState,
BitStatesUtils.OP_HAS_BIND_BANK);
} // 判断是否已经绑定了邮箱
public boolean getIsBindEmail() {
return BitStatesUtils.hasState(this.bitState,
BitStatesUtils.OP_BIND_EMAIL);
} // 添加绑定的状态码
public void addState(Long state) {
bitState = BitStatesUtils.addState(this.bitState, state);
}
// 移除状态码
public void removeState(Long state) {
bitState = BitStatesUtils.removeState(this.bitState, state);
} // 判断用户是否已经填写了基本资料
public boolean getIsBasicInfo() {
return BitStatesUtils.hasState(this.bitState,
BitStatesUtils.OP_BASIC_INFO);
} // 判断用户是否已经实名认证
public boolean getIsRealAuth() {
return BitStatesUtils.hasState(this.bitState,
BitStatesUtils.OP_REAL_AUTH);
} // 判断用户是否已经视频认证
public boolean getIsVedioAuth() {
return BitStatesUtils.hasState(this.bitState,
BitStatesUtils.OP_VEDIO_AUTH);
}
// 判断用户是否已经有一个借款在审核流程中
public boolean getHasBidRequestInProcess() {
return BitStatesUtils.hasState(this.bitState,
BitStatesUtils.OP_HAS_BIDREQUEST_PROCESS);
}
// 判断用户是否已经有一个提现在审核流程中
public boolean getHasWithdrawInProcess() {
return BitStatesUtils.hasState(this.bitState,
BitStatesUtils.OP_HAS_WITHDRAW_PROCESS);
}
}
p2p手机绑定的更多相关文章
- 余额宝 vs. P2P网贷,谁更有生命力?
余额宝跟P2P网贷作为一个理财方式,要说谁更有生命力,那就必须从以下几个方面说起,一是收益性,二是风险性,三是流动性,下面从这几个方面来对比一下余额宝跟P2P网贷. 首先是收益性,作为投资理财者,第一 ...
- 分享“12306 P2P平台”创业Idea
结合云平台抢票,社区,P2P等性质,实施供求抢票平台,能有效提高和整合抢票市场,抢票优势以杜绝黄牛,给散户提供更有利的抢票途径.本在11月计划实施,后去搞比特币,故分享摘要集思广益. 背景 ...
- Socket编程实践(3) 多连接服务器实现与简单P2P聊天程序例程
SO_REUSEADDR选项 在上一篇文章的最后我们贴出了一个简单的C/S通信的例程.在该例程序中,使用"Ctrl+c"结束通信后,服务器是无法立即重启的,如果尝试重启服务器,将被 ...
- R可视化lend_club 全球最大的P2P平台数据75W条
lend_club 全球最大的P2P平台2007~2012年贷款数据百度云下载. 此文章基于R语言做简单分析. rm(list=ls()) #清除变量 gc() #释放内存 step1 考虑到后续分析 ...
- 浅谈P2P金融
自从李总理开发互联网大会,提出“互联网+”,好像与互联网相在的所有事情都火起来了.上至80岁的老头,下至十多岁的孩童,都知道了这个词“互联网+”.虽然大家可能对”互联网+“的概念都只是一支半解,但是像 ...
- 王宝强新片P2P风波持续发酵,互金真的前途未卜?
王宝强离婚风波还未完全结束,一波未平一波又起,新片又引来话题爆点,其自导自演的电影<大闹天竺>陷P2P平台集资的新闻占据各大媒体头条. 该P2P平台为湖北武汉一家P2P互联网金融理财平台& ...
- p2p tcp nat 原理图+源码(原创)
现今网上p2p的 udp nat穿透 文章 多如牛毛, p2p tcp nat的文章寥寥无几 ,up主研究了几天 终于有所收获,特来向大家分享,请大家多多支持! 1.首先你要有台外网服务器 或者 电信 ...
- p2p网贷平台设计简析
以我之前主持开发的一个商业产品:p2p网贷为例进行分析.整个的概况,可以参见:www.huixinp2p.com(目的只会技术交流) 界面可以直接参考前期博客:http://www.cnblogs.c ...
- 迅雷9、迅雷极速版之迅雷P2P加速:流量吸血鬼?为什么你装了迅雷之后电脑会感觉很卡很卡?
原文地址:http://www.whosmall.com/post/90 关闭极速版迅雷ThunderPlatform.exe进程 ThunderPlatform.exe目的:利用P2P技术进行用户间 ...
随机推荐
- Java多线程实现异步调用
在Java平台,实现异步调用的角色有如下三个角色:调用者. 提货单 .真实数据,一个调用者在调用耗时操作,不能立即返回数据时,先返回一个提货单 .然后在过一断时间后凭提货单来获取真正的数据.去蛋糕店买 ...
- Nginx安装、配置和使用
Nginx 1. 什么是nginx 是一个使用c语言开发的高性能的http服务器及反向代理服务器. Nginx是一款高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器. ...
- OS之内存管理 ---基本的内存管理策略(二)
分段 基本方法 分段就是基于用户视图的内存管理方案.逻辑地址空间是由一组段构成的,每个段都有名称和长度.地址指定了段名称和段内偏移.因此用户通过两个量来指定地址:段名称和段偏移. 为了简单,进行对段的 ...
- selenium IDE的基本命令
waitForText.verifyText和asserText命令 waitForText语句在测试执行时用来判断某些文本是否存在界面中.若界面上显示了指定文本,测试程序会继续执行:若等待一段时间后 ...
- XP系统安装VS2010失败的解决方法
今天装了一个双系统,但是在XP系统上安装VS2010的时候就出现了下面的错误 于是在网上搜索各种资源,查看错误日志,网上说是office2007的原因,我也抱着试试看的态度去卸载了,可是卸载后却发现还 ...
- 使用Maven命令行快速创建项目骨架(archetype)
> mvn archetype:generate 接下来就会输出一些列带索引变化的archetype项可供我们选择,然后提示我们选择一个编号,可以直接回车选择默认的编号(392),然后就跟着 ...
- python中map()函数
map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回. map()是 Python 内 ...
- puppet的使用:puppet的hello world
这个例子完成将master节点上的一个文件放至agent节点上的功能 创建要传输的文件 echo "helloWorld" > /etc/puppet/modules/pup ...
- 初学者必知的Python中优雅的用法 分类: Python 2015-05-11 15:02 782人阅读 评论(0) 收藏
本文由 伯乐在线 - 淘小米 翻译,Daetalus 校稿.未经许可,禁止转载!英文出处:freepythontips.wordpress.com.欢迎加入翻译小组. Hi 朋友们.由于我最近都比较忙 ...
- 【数组】Next Permutation
题目: Implement next permutation, which rearranges numbers into the lexicographically next greater per ...