之前完成了對應的註冊部分,所以今天是要實現登入部分,要實現兩種登入方法,一種是直接簡訊驗證登入,一種是簡訊驗證碼登入。由於我們之前註冊的時候存入資料庫時使用了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); }