瑞吉外卖(移动端登录)注意事项
1.ReferenceError: sendMsgApi is not defined" (found in )
写的时候出现了一个叫做Error in v-on handler: “ReferenceError: sendMsgApi is not defined” (found in )的错误
解决方法:清除浏览器缓存
原因:
我们之前已经运行过一次脚本了
缓存的旧脚本:浏览器可能缓存了旧的脚本文件,这些文件中可能没有定义 sendMsgApi
函数。当清除缓存后,浏览器会重新下载最新的脚本文件,其中包含了正确的 sendMsgApi
函数定义。
2.关于从后端接收验证码的这个
1…前端页面,先看页面
<div id="login" v-loading="loading">
<div class="divHead">登录</div>
<div class="divContainer">
<el-input placeholder=" 请输入手机号码" v-model="form.phone" maxlength='20'/></el-input>
<div class="divSplit"></div>
<el-input placeholder=" 请输入验证码" v-model="form.code" maxlength='20'/></el-input>
<span @click='getCode'>获取验证码</span>
</div>
<div class="divMsg" v-if="msgFlag">手机号输入不正确,请重新输入</div>
<el-button type="primary" :class="{btnSubmit:1===1,btnNoPhone:!form.phone,btnPhone:form.phone}" @click="btnLogin">登录</el-button>
</div>
进入getcode
getCode(){
this.form.code = ''
const regex = /^(13[0-9]{9})|(15[0-9]{9})|(17[0-9]{9})|(18[0-9]{9})|(19[0-9]{9})$/;
if (regex.test(this.form.phone)) {
this.msgFlag = false
sendMsgApi({phone: this.form.phone})
}else{
this.msgFlag = true
}
},
注意这行代码我们是将生成的代码进行了一个封装的,而不是让前端自己直接显示在页面上
sendMsgApi({phone: this.form.phone})
关于sendMsgApi,就是返回一个ajax请求,然后带着路径,方法,数据
function sendMsgApi(data) {
return $axios({
'url': '/user/sendMsg',
'method': 'post',
data
})
}
还有值得注意的是这里 sessionStorage.setItem(“userPhone”,this.form.phone),这里我们只有手机号
async btnLogin(){
if(this.form.phone && this.form.code){
this.loading = true
const res = await loginApi(this.form)
this.loading = false
if(res.code === 1){
sessionStorage.setItem("userPhone",this.form.phone)
window.requestAnimationFrame(()=>{
window.location.href= '/front/index.html'
})
}else{
this.$notify({ type:'warning', message:res.msg});
}
}else{
this.$notify({ type:'warning', message:'请输入手机号码'});
}
}
2.后端
@PostMapping("/sendMsg")
public R<String> sendMsg(@RequestBody User user, HttpSession session){
//获取手机号
String phone = user.getPhone();
log.info("电话{}",phone);
if(StringUtils.isNotEmpty(phone)){
//生成随机的4位验证码
String code = ValidateCodeUtils.generateValidateCode(4).toString();
log.info("code={}",code);
//调用阿里云提供的短信服务API完成发送短信
//SMSUtils.sendMessage("瑞吉外卖","",phone,code);
//需要将生成的验证码保存到Session
session.setAttribute(phone,code);
return R.success("手机验证码短信发送成功");
}
return R.error("短信发送失败");
}
3.一起把登录的代码写了
3.1看请求
前端页面点击登录然后跳转到这个方法
async btnLogin(){
if(this.form.phone && this.form.code){ //判断一下
this.loading = true //加载动画
const res = await loginApi(this.form) //登录操作
this.loading = false //关闭加载动画
if(res.code === 1){ //接受到后端的响应码,判断是不是新用户
sessionStorage.setItem("userPhone",this.form.phone) //存储
window.requestAnimationFrame(()=>{
// 使用 requestAnimationFrame 确保页面渲染完成后执行跳转
window.location.href= '/front/index.html'
})
}else{
this.$notify({ type:'warning', message:res.msg});
//报错信息
}
}else{
this.$notify({ type:'warning', message:'请输入手机号码'});
//手机号有误
}
}
function loginApi(data) {
return $axios({
'url': '/user/login',
'method': 'post',
data
})
}
后端代码
没啥需要注意的
@PostMapping("/login")
public R<User> login(@RequestBody Map map,HttpSession session){
//先获取手机号
String phone = map.get("phone").toString();
//获取验证码
String code1 = map.get("code").toString();
//将code保存下来 ,然后与提交的进行对比
Object codeSession = session.getAttribute(phone);
if(codeSession != null && codeSession.equals(code1)){
//比对成功就相当于是登录成功
//查看里面user的表里面是否有这个,没有就注册一个
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getPhone,phone);
User user = userService.getOne(queryWrapper);
if(user == null){
user = new User();
user.setPhone(phone);
user.setStatus(1);
userService.save(user);
}
session.setAttribute("user",user.getId());
return R.success(user);
}
return R.error("登录失败");
}
hone);
user.setStatus(1);
userService.save(user);
}
session.setAttribute("user",user.getId());
return R.success(user);
}
return R.error("登录失败");
}