07完善前端系统功能项目开发文档资料文档Word格式.docx
《07完善前端系统功能项目开发文档资料文档Word格式.docx》由会员分享,可在线阅读,更多相关《07完善前端系统功能项目开发文档资料文档Word格式.docx(21页珍藏版)》请在冰豆网上搜索。
![07完善前端系统功能项目开发文档资料文档Word格式.docx](https://file1.bdocx.com/fileroot1/2023-1/3/fe72f5c8-febf-4f25-bba5-75702102b1b7/fe72f5c8-febf-4f25-bba5-75702102b1b71.gif)
/mvc:
在需要登录的controller的method上添加@RequiredLogin注解即可:
注销
在loginController中直接添加一个logout方法:
@RequestMapping("
/logout"
)
publicStringlogout(){
UserContext.setLoginInfo(null);
return"
redirect:
main.do"
;
直接使用redirect:
前缀完成响应的跳转;
绑定手机
绑定手机前端
1,创建一个BitStatesUtils来处理用户的状态码;
/**
*@paramstates所有状态值
*@paramvalue需要判断状态值
*@return是否存在
*/
publicstaticbooleanhasState(longstates,longvalue){
return(states&
value)!
=0;
*@paramstates已有状态值
*@paramvalue需要添加状态值
*@return新的状态值
publicstaticlongaddState(longstates,longvalue){
if(hasState(states,value)){
returnstates;
return(states|value);
*@paramvalue需要删除状态值
publicstaticlongremoveState(longstates,longvalue){
if(!
hasState(states,value)){
returnstates^value;
在该类中创建一个静态值,用于标记用户状态和手机绑定状态;
publicfinalstaticLongOP_BASIC_INFO=1L;
/用户注册成功的标示,及为默认初始状态
publicfinalstaticLongOP_BIND_PHONE=2L<
<
0;
//是否已经绑定了手机号码
修改Userinfo的empty方法,在用户注册的时候需要给用户绑定一个初始状态:
publicstaticUserinfoempty(longid){
Userinfoempty=newUserinfo();
empty.setId(id);
empty.setBitState(BitStatesUtils.OP_BASIC_INFO);
returnempty;
2,给userinfo对象添加一个方法用于判断用户是否已经绑定手机
publicbooleangetHasBindPhone(){
returnBitStatesUtils.hasState(this.bitState,BitStatesUtils.OP_BIND_PHONE);
3,修改personal.ftl,根据用户手机绑定状态显示不同内容:
p>
#ifuserinfo.hasBindPhone>
已认证<
ahref="
#"
>
查看<
/a>
#else>
未绑定<
javascript:
"
马上绑定<
/#if>
/p>
4,创建绑定手机模式窗口
!
--绑定手机模式框-->
#if!
userinfo.hasBindPhone>
divclass="
modalfade"
id="
bindPhoneModal"
tabindex="
-1"
role="
dialog"
aria-labelledby="
exampleModalLabel"
modal-dialog"
document"
modal-content"
modal-header"
buttontype="
button"
class="
close"
data-dismiss="
modal"
aria-label="
Close"
spanaria-hidden="
true"
&
times;
/span>
/button>
h4class="
modal-title"
绑定手机<
/h4>
/div>
modal-body"
formclass="
form-horizontal"
bindForm"
method="
post"
action="
/bindPhone.do"
form-group"
<
labelfor="
phoneNumber"
col-sm-2control-label"
手机号:
/label>
col-sm-4"
inputtype="
text"
form-control"
buttonid="
sendVerifyCode"
btnbtn-primary"
type="
发送验证码<
verifyCode"
验证码:
/form>
modal-footer"
btnbtn-default"
取消<
保存<
5,给绑定连接添加事件,点击绑定后弹出绑定手机模式窗口
if($("
#openBindPhoneModal"
).size()>
0){
$("
).click(function(){
$('
#bindPhoneModal'
).modal('
show'
});
6,给发送验证码添加事件:
$("
#sendVerifyCode"
varphoneNumber=$("
#phoneNumber"
).val();
var_me=$(this);
if(phoneNumber){
_me.attr("
disabled"
true);
$.ajax({
dataType:
json"
type:
data:
{phoneNumber:
phoneNumber},
url:
/sendVerifyCode.do"
success:
function(){
varsec=120;
vartimer=window.setInterval(function(){
sec--;
_me.text(sec+"
秒重新发送"
if(sec==0){
window.clearInterval(timer);
_me.attr("
false);
_me.text("
重新发送验证码"
}
},1000);
});
});
7,后台添加发送短信的方法,在PersonalController中添加方法:
@RequestMapping("
/sendVerifyCode"
@ResponseBody
publicStringsendVerifyCode(Modelmodel){
Logininfocurrent=UserContext.getLoginInfo();
System.out.println("
发送手机验证码"
完成短信发送逻辑
添加一个专门的VerifyCodeServiceImpl用来完成验证码服务,包括验证码发送,验证码验证,验证码时间验证;
首先,在该方法中需要传入本系统的发送短信的相关信息,比如username,password,apikey等内容,这些内容是随时可以配置的,所以我们也采用properties文件的方式,
添加m5c.properties:
m5c.username=xiaomage
m5c.password=1234
m5c.apikey=xiaomage1234
m5c.url=http:
//localhost:
8082/send.do
在applicationContext-core.xml中,要引入多个properties文件,因为要引入多个配置文件,所以我们修改引入配置文件的方式:
--配置属性资源文件-->
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
propertyname="
locations"
list>
value>
classpath:
datasource.properties<
/value>
m5c.properties<
/list>
/property>
ignoreUnresolvablePlaceholders"
value="
systemPropertiesMode"
0"
/bean>
因为我们使用的是全注解方式,所以VerifyCodeServiceImpl是不配置在xml文件中的,那么我们怎么添加属性的值呢?
使用@Value标签:
@Service
publicclassVerifyCodeServiceImplimplementsIVerifyCodeService{
@Value("
${m5c.username}"
privateStringusername;
${m5c.password}"
privateStringpassword;
${m5c.apikey}"
privateStringapikey;
${m5c.url}"
privateStringurl;
实现发送短信的逻辑
@Override
publicvoidsendVerifyCode(StringphoneNumber){
if(this.checkCanSendVerifyCode()){
try{
StringrandCode=UUID.randomUUID().toString().substring(0,4);
HttpURLConnectionconn=(HttpURLConnection)newURL(url).openConnection();
//必须大写
conn.setRequestMethod("
POST"
conn.setDoOutput(true);
StringBuilderparams=newStringBuilder(100).append("
username="
).append(username).append("
password="
).append(password)
.append("
apikey="
).append(apikey).append("
mobile="
).append(phoneNumber).append("
content="
).append("
你的验证码是:
.append(randCode).append("
,有效期3分钟!
conn.getOutputStream().write(params.toString().getBytes());
InputStreamis=conn.getInputStream();
Stringret=StreamUtils.copyToString(is,Charset.forName("
UTF-8"
));
if("
success"
.equals(ret.substring(0,ret.indexOf("
:
)))){
VerifyCodevc=newVerifyCode(phoneNumber,randCode,newDate());
UserContext.setVerifyCode(vc);
}else{
thrownewLogicException("
短信发送失败,平台管理员!
}catch(IOExceptione){
e.printStackTrace();
thrownewLogicException("
其中的checkCanSendVerifyCode方法用于验证当前是否能再次发短信:
privatebooleancheckCanSendVerifyCode(){
Datenow=newDate();
VerifyCodevc=UserContext.getVerifyCode();
if(vc==null){
returntrue;
}else{
DatelastTime=vc.getLastSendTime();
if(DateUtil.getSecondBetween(lastTime,now)>
=120){
returntrue;
returnfalse;
为了让service和web相关API脱离,我们把当前用户发送的验证码信息的存取逻辑都放到了UserContext中:
publicstaticvoidsetVerifyCode(VerifyCodevc){
getRequest().getSession().setAttribute(VERIFYCODE_IN_SESSION,vc);
publicstaticVerifyCodegetVerifyCode(){
return(VerifyCode)getRequest().getSession().getAttribute(VERIFYCODE_IN_SESSION);
测试之前请部署好eloan-mockserver;
完成手机绑定逻辑
在发送完验证码之后,就是用户输入验证码,并点击保存之后的逻辑。
首先修改前端页面,添加提交手机绑定信息:
#bindPhone"
$("
#bindForm"
).ajaxSubmit(function(data){
if(data.success){
$.messager.confirm("
提示"
"
绑定手机成功!
function(){
window.location.reload();
}else{
$.messager.alert("
data.msg);
});
在PersonalController中添加绑定手机方法:
/bindPhone"
publicResultJSONbindPhone(StringphoneNumber,StringverifyCode,Modelmodel){
ResultJSONjson=newResultJSON(true);
try{
this.userInfoService.bindPhone(phoneNumber,verifyCode);
json.setSuccess(true);
}catch(LogicExceptionle){
json.setSuccess(false);
json.setMsg(le.getMessage());
returnjson;
在userInfoService中添加bindPhone方法:
publicvoidbindPhone(StringphoneNumber,StringverifyCode){
if(this.verifyCodeService.checkVerifyCode(phoneNumber,verifyCode)){
Logininfocurrent=UserContext.getLoginInfo();
Userinfoui=this.userInfoMapper.selectByPrimaryKey(current.getId());
if(!
ui.getHasBindPhone()){
ui.addBitState(BitStatesUtils.OP_BIND_PHONE);
ui.setPhoneNumber(phoneNumber);
this.update(ui);
thrownewLogicException("
验证码错误或者过期!
注意,因为我们的userinfo对象需要乐观锁修改,所以我们专门在service中写了一个update方法来处理乐观锁问题:
privatevoidupdate(Userinfoui){
intret=this.userInfoMapper.updateByPrimaryKey(ui);
if(ret==0){
System.out.println("
userinfo对象更新失败"
系统正忙,请稍后再试!
如果多次看到该提示,平台管理员!
为了方便操作,在Userinfo对象中添加一个增加状态的方法:
publicvoidaddBitState(LongnewState){
this.bitState=BitStatesUtils.addState(this.bitState,newState);
在VerifyCodeService中添加检查验证码的方法:
publicbooleancheckVerifyCode(StringphoneNumber,Stringcode){
if(vc!
if(vc.getPhoneNumber().equals(phoneNumber)&
//判断电话号码是否相同
vc.getRandomCode().equals(code)&
//判断验证码是否相同
DateUtil.getSecondBetwee