2024/06/11

伐木工熊大發表於2024-06-11

學習時長:5小時

程式碼行數:230行

部落格數量:1篇

今天主要完成了登入,包括簡訊驗證登入和手機號+密碼登入,密碼在資料庫中經過加密處理,並且完成了登入後資訊的快取。

<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/index/index"
                    });
                }
                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/index/index"
                });
            }
            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>