2024/05/22(团队开发)
之前完成了对应的注册部分,所以今天是要实现登录部分,要实现两种登录方法,一种是直接短信验证登录,一种是短信验证码登录。由于我们之前注册的时候存入数据库时使用了md5加密,所以在验证密码时也许将输入的密码进行md5转换。
应用界面代码:
<template> <view class="login-container"> <!-- 根据登录方式显示不同的表单 --> <view v-if="loginMethod === 'sms'" class="getcodecontainer"> <view class="logo"> <!-- 这里放置你的应用 logo --> <image src="/static/logo.png" class="logo-img" mode="aspectFit" /> </view> <view class="form-group"> <text class="label">手机号:</text> <input type="tel" v-model="phoneNumber" placeholder="请输入手机号" /> </view> <view class="form-group"> <text class="label">验证码:</text> <input type="text" v-model="verificationCode" placeholder="请输入验证码" /> <button @click="getVerificationCode" :disabled="countdown > 0 || phoneNumber.length !== 11 || !isPhoneNumberValid" :class="{ 'code-btn-active': countdown <= 0 }">{{ countdown > 0 ? '重新获取('+ countdown + ' s)' : '获取验证码' }}</button> </view> <button class="login-btn" @click="verificat":disabled="phoneNumber.length !== 11 || verificationCode === ''|| !isPhoneNumberValid">登录</button> </view> <view v-else class="getcodecontainer"> <view class="logo"> <!-- 这里放置你的应用 logo --> <image src="/static/logo.png" class="logo-img" mode="aspectFit" /> </view> <view class="form-group"> <text class="label">手机号:</text> <input type="tel" v-model="phoneNumber" placeholder="请输入手机号" /> </view> <view class="form-group"> <text class="label">密码:</text> <input type="password" v-model="password" placeholder="请输入密码" /> </view> <button class="login-btn" @click="login":disabled="phoneNumber.length !== 11 || password === ''|| !isPhoneNumberValid">登录</button> </view> <!-- 切换登录方式 --> <view class="switch-login-method" @click="toggleLoginMethod"> {{ loginMethod === 'sms' ? '密码登录' : '短信验证码登录' }} </view> <!-- 注册链接 --> <view class="register-link" @click="goToRegisterPage">注册新账号</view> </view> </template> <script> export default { data() { return { phoneNumber: '', verificationCode: '', password: '', countdown: 0, loginMethod: 'sms' // 默认使用短信验证码登录 }; }, computed: { isPhoneNumberValid() { return /^\d{11}$/.test(this.phoneNumber); // 使用正则表达式检验电话号码是否全是数字且长度为11位 }, }, methods: { verificat() {//验证码验证 uni.request({ url:this.$BASE_URL.BASE_URL+"/verifySmsCodeLogin", data:{ phone:this.phoneNumber, code:this.verificationCode }, success: (res) => { console.log(res.data.data) if(res.data.code) { uni.showToast({ title:"登录成功", }); uni.setStorageSync('userInfo', res.data.data); uni.switchTab({ url: "/pages/userinformation/userinformation" }); } else{ uni.showToast({ title:res.data.msg, icon:"none" }); } } }) }, getVerificationCode() {//获取验证码 var self=this // 模拟发送验证码 // 模拟倒计时 this.countdown = 60; // 倒计时时间(秒) const timer = setInterval(() => { if (this.countdown > 0) { this.countdown--; } else { clearInterval(timer); this.countdown = 0; } }, 1000); uni.hideKeyboard() uni.request({ url:this.$BASE_URL.BASE_URL+"/getcode", data:{ phone:self.phoneNumber }, success:(res)=>{ if(res.data.code) { console.log(res.data) uni.showToast({ title:"验证码已发送", }); } else{ uni.showToast({ title:"验证码获取失败", icon: 'error', }) } }, fail: () => { uni.showToast({ title:"验证码获取失败", icon: 'error', }) } }) }, login() { const requestBody = { phone: this.phoneNumber, password: this.password }; uni.request({ url:this.$BASE_URL.BASE_URL+"/login", method: 'POST', data: requestBody, success: (res) => { if(res.data.code) { console.log(res.data.data) uni.showToast({ title:"登录成功", }); uni.setStorageSync('userInfo', res.data.data); uni.switchTab({ url: "/pages/userinformation/userinformation" }); } else{ uni.showToast({ title:res.data.msg, icon: 'none', }) } } }) }, toggleLoginMethod() { // 切换登录方式 this.loginMethod = this.loginMethod === 'sms' ? 'password' : 'sms'; }, goToRegisterPage() { // 跳转到注册页面的逻辑 uni.redirectTo({ url:"/pages/userinformation/register/register" }) } } }; </script> <style scoped> /* 样式可以根据自己的需要进行调整 */ html, body { height: 100%; /* 设置页面高度为100% */ margin: 0; /* 去除页面的默认边距 */ } .login-container { background: linear-gradient(to bottom, #FFFFE0 0%, #87CEEB 250%); /* 使用线性渐变背景 */ height: 700px; /* 让容器充满整个页面 */ padding: 20px; /* 设置内边距 */ border-radius: 10px; /* 设置圆角 */ display: flex; /* 使用 Flex 布局 */ flex-direction: column; /* 垂直布局 */ justify-content: top; /* 内容垂直居中 */ align-items: center; /* 内容水平居中 */ } .switch-login-method { margin-top: 20px; color: #007bff; cursor: pointer; } .register-link { margin-top: 20px; color: #007bff; cursor: pointer; } .error-msg { margin-top: ; color: red; font-size: 12px; } .getcodecontainer { background: linear-gradient(to bottom, #FFFFE0 0%, #87CEEB 250%); /* 使用线性渐变背景 */ height: 45%; /* 让容器充满整个页面 */ padding: 20px; /* 设置内边距 */ border-radius: 10px; /* 设置圆角 */ display: flex; /* 使用 Flex 布局 */ flex-direction: column; /* 垂直布局 */ justify-content: top; /* 内容垂直居中 */ align-items: center; /* 内容水平居中 */ } .logo { margin-bottom: 30px; } .logo-img { width: 100px; height: 100px; border-radius: 50%; } .form-group { margin-bottom: 20px; display: flex; align-items: center; justify-content: center; } .label { font-weight: bold; margin-right: 10px; } input { flex: 1; padding: 10px; border-radius: 5px; font-size: 18px; background-color: rgba(255, 255, 255, 0.3); /* 设置背景为浅白色并透明 */ } .code-btn-active { display: flex; /* 使用 flex 布局 */ align-items: center; /* 垂直居中 */ justify-content: center; /* 水平居中 */ padding: 10px 15px; background-color: #00aaff; color: #ffffff; border: none; border-radius: 5px; cursor: pointer; font-size: 14px; transition: background-color 0.3s; height: 45px ; } button{ display: flex; /* 使用 flex 布局 */ align-items: center; /* 垂直居中 */ justify-content: center; /* 水平居中 */ padding: 10px 15px; background-color: #00aaff; color: #ffffff; border: none; border-radius: 5px; cursor: pointer; font-size: 14px; transition: background-color 0.3s; height: 45px ; } /* 禁用状态下的样式保持不变 */ .button:hover { background-color: #0056b3; height: 45px ; } button:disabled { background-color: #ccc; cursor: not-allowed; height: 45px ; } .login-btn { width: 100%; } /* .countdown { font-size: 12px; color: #888; margin-top: 10px; } */ .code-btn:hover, .login-btn:hover { background-color: rgba(255, 255, 255, 0.8); /* 鼠标悬停时的背景色,这里使用半透明白色 */ } </style>
后端:
controller层:
package com.share.viedo_app.controller; import com.share.viedo_app.pojo.Result; import com.share.viedo_app.pojo.User; import com.share.viedo_app.pojo.UserPrivacy; import com.share.viedo_app.pojo.Video; import com.share.viedo_app.service.UserService; import com.share.viedo_app.util.AliMes; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.web.bind.annotation.*; import java.time.Duration; import java.util.Random; @Slf4j @RestController public class UserController { @Autowired private StringRedisTemplate stringRedisTemplate; @Autowired private UserService userService; @GetMapping("/getcode") public Result getCode(@RequestParam String phone)//发送验证码 { String code = String.valueOf(new Random().nextInt(899999) + 100000); AliMes aliMes=new AliMes(); boolean result=aliMes.sendMes(phone,code); System.out.println(code); if(result) { stringRedisTemplate.opsForValue().set(phone, code, Duration.ofMinutes(5)); System.out.println(result); return Result.success(); } else { return Result.error("短信发送失败"); } } @GetMapping("/verifySmsCode")//验证码验证 public Result verifySmsCode(@RequestParam String phone,@RequestParam String code) { String savedCode = stringRedisTemplate.opsForValue().get(phone); if (savedCode != null && savedCode.equals(code)) { // 验证成功,清除验证码 System.out.println("验证成功"); stringRedisTemplate.delete(phone); return Result.success(); } return Result.error("验证失败,验证码错误或已过期"); } @GetMapping("/verifySmsCodeLogin")//验证码登录 public Result verifySmsCodeLogin(@RequestParam String phone,@RequestParam String code) { String savedCode = stringRedisTemplate.opsForValue().get(phone); if (savedCode != null && savedCode.equals(code)) { // 验证成功,清除验证码 User num=userService.codelogin(phone); stringRedisTemplate.delete(phone); System.out.println("验证成功"); if(num==null) { return Result.error("验证失败,该手机号尚未注册"); } return Result.success(num); } return Result.error("验证失败,验证码错误或已过期"); } @PostMapping("/register")//验证 public Result register(@RequestBody UserPrivacy userPrivacy) { try{ userService.register(userPrivacy); return Result.success(); }catch (Exception e) { return Result.error("该手机号已被注册"); } } @PostMapping("/login")//登录 public Result login(@RequestBody UserPrivacy userPrivacy) { UserPrivacy num=userService.login(userPrivacy); if(num!=null) { User resu=userService.selectByPhone(userPrivacy); return Result.success(resu); } else { return Result.error("手机号或密码错误"); } } }
service层:
package com.share.viedo_app.controller; import com.share.viedo_app.pojo.Result; import com.share.viedo_app.pojo.User; import com.share.viedo_app.pojo.UserPrivacy; import com.share.viedo_app.pojo.Video; import com.share.viedo_app.service.UserService; import com.share.viedo_app.util.AliMes; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.web.bind.annotation.*; import java.time.Duration; import java.util.Random; @Slf4j @RestController public class UserController { @Autowired private StringRedisTemplate stringRedisTemplate; @Autowired private UserService userService; @GetMapping("/getcode") public Result getCode(@RequestParam String phone)//发送验证码 { String code = String.valueOf(new Random().nextInt(899999) + 100000); AliMes aliMes=new AliMes(); boolean result=aliMes.sendMes(phone,code); System.out.println(code); if(result) { stringRedisTemplate.opsForValue().set(phone, code, Duration.ofMinutes(5)); System.out.println(result); return Result.success(); } else { return Result.error("短信发送失败"); } } @GetMapping("/verifySmsCode")//验证码验证 public Result verifySmsCode(@RequestParam String phone,@RequestParam String code) { String savedCode = stringRedisTemplate.opsForValue().get(phone); if (savedCode != null && savedCode.equals(code)) { // 验证成功,清除验证码 System.out.println("验证成功"); stringRedisTemplate.delete(phone); return Result.success(); } return Result.error("验证失败,验证码错误或已过期"); } @GetMapping("/verifySmsCodeLogin")//验证码登录 public Result verifySmsCodeLogin(@RequestParam String phone,@RequestParam String code) { String savedCode = stringRedisTemplate.opsForValue().get(phone); if (savedCode != null && savedCode.equals(code)) { // 验证成功,清除验证码 User num=userService.codelogin(phone); stringRedisTemplate.delete(phone); System.out.println("验证成功"); if(num==null) { return Result.error("验证失败,该手机号尚未注册"); } return Result.success(num); } return Result.error("验证失败,验证码错误或已过期"); } @PostMapping("/register")//验证 public Result register(@RequestBody UserPrivacy userPrivacy) { try{ userService.register(userPrivacy); return Result.success(); }catch (Exception e) { return Result.error("该手机号已被注册"); } } @PostMapping("/login")//登录 public Result login(@RequestBody UserPrivacy userPrivacy) { UserPrivacy num=userService.login(userPrivacy); if(num!=null) { User resu=userService.selectByPhone(userPrivacy); return Result.success(resu); } else { return Result.error("手机号或密码错误"); } } @PostMapping("/updata/user") public Result updataUser(@RequestBody User user) { try { userService.updata(user); return Result.success(); }catch (Exception e) { return Result.error("未知错误"); } } }
mapper层:
package com.share.viedo_app.mapper; import com.share.viedo_app.pojo.User; import com.share.viedo_app.pojo.UserPrivacy; import com.share.viedo_app.service.UserService; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; @Mapper public interface UserMapper { @Insert("insert into userprivacy( phone, password) values (#{phone},MD5(#{password}))") void register(UserPrivacy userPrivacy); @Insert("insert into user(phone,account) values (#{phone},#{phone})") void register1(UserPrivacy userPrivacy); @Select("select id from userprivacy where phone=#{phone} and password=MD5(#{password})") UserPrivacy login(UserPrivacy userPrivacy); @Select("select * from user where phone=#{phone}") User codelogin(String phone); }