Browse Source

feat:完成邮箱登录

chenjiayao 1 year ago
parent
commit
cd930b3c51

+ 30 - 0
src/apis/auth.ts

@@ -0,0 +1,30 @@
+import axiosInstance from "@/apis/axios.config";
+import { type ILoginUserFrom, type ILoginEmailFrom } from "@/types/user";
+
+const AUTH_PREFIX = "/api/auth"
+
+const authApis = {
+    login: (userForm: ILoginUserFrom) => {
+        return axiosInstance.post(`${AUTH_PREFIX}/login`, {
+            ...userForm
+        })
+    },
+
+    loginByEmail: (userForm: ILoginEmailFrom) => {
+        return axiosInstance.post(`${AUTH_PREFIX}/loginByEmail`, {
+            ...userForm
+        })
+    },
+
+
+    sendLoginVerifyCode: (officialEmail:string) => {
+        return axiosInstance.get(`${AUTH_PREFIX}/loginVerifyCode`, {
+            params: {
+                officialEmail
+            }
+        })
+    },
+
+}
+
+export default authApis

+ 2 - 2
src/apis/axios.config.ts

@@ -1,9 +1,9 @@
 import axios from "axios";
 
 // const BASEURL = 'http://47.111.23.171:8081'
-// const BASEURL = 'http://localhost:8080'
+const BASEURL = 'http://localhost:8080'
 // const BASEURL = 'http://8.130.126.86:8080'
-const BASEURL = 'https://air.seec.seecoder.cn/'
+// const BASEURL = 'https://air.seec.seecoder.cn/'
 
 const axiosInstance = axios.create({
     baseURL: BASEURL,

+ 2 - 0
src/apis/index.ts

@@ -1,3 +1,4 @@
+import authApis from "./auth";
 import userApis from "@/apis/user";
 import testApis from "@/apis/test";
 import editorApis from "@/apis/editor";
@@ -10,6 +11,7 @@ import fileApis from "@/apis/file";
 
 
 const apis = {
+    ...authApis,
     ...userApis,
     ...testApis,
     ...editorApis,

+ 0 - 6
src/apis/user.ts

@@ -5,12 +5,6 @@ import type {UserRegisterDTO, UserUpdateDTO} from "@/types/dto";
 const USER_PREFIX = "/api/user"
 
 const userApis = {
-    login: (userForm: ILoginUserFrom) => {
-        return axiosInstance.post(`${USER_PREFIX}/login`, {
-            ...userForm
-        })
-    },
-
     findUserById: (id:number) => {
         return axiosInstance.get(`${USER_PREFIX}`, {
             params: {

+ 1 - 1
src/layout/Header/Header.vue

@@ -43,8 +43,8 @@
         </div>
         <template #dropdown>
           <el-dropdown-menu>
-            <el-dropdown-item command="logout">退出登录</el-dropdown-item>
             <el-dropdown-item command="profile">个人资料</el-dropdown-item>
+            <el-dropdown-item command="logout">退出登录</el-dropdown-item>
           </el-dropdown-menu>
         </template>
       </el-dropdown>

+ 5 - 0
src/types/user.ts

@@ -17,3 +17,8 @@ export interface ILoginUserFrom {
     officialNumber: string;
     password: string;
 }
+
+export interface ILoginEmailFrom {
+    officialEmail: string;
+    verifyCode: string;
+}

+ 70 - 14
src/views/LoginPage/component/Login.vue

@@ -27,12 +27,8 @@
                 v-model="data.code"
                 placeholder="请输入验证码"
             >
-              <template #append>
-                <el-button
-                    :class="isStart? '' : 'code-button-active'"
-                    @click="getCode"
-                    :disabled="isStart"
-                >
+              <template #suffix>
+                <el-button type="text" @click="getCode" :disabled="isStart">
                   {{ isStart ? countdown : '获取验证码' }}
                 </el-button>
               </template>
@@ -50,14 +46,14 @@
         <el-form-item>
           <el-button class="login-button" @click="handleLogin">用户登录</el-button>
         </el-form-item>
-        <div class="sign" @click="onClickSign">去注册?</div>
+        <div class="sign" @click="onClickSign">注册账号</div>
       </el-form>
     </div>
   </div>
 </template>
 
 <script lang="ts" setup>
-  import { ref, reactive,defineProps } from 'vue';
+  import { ref, reactive, defineProps } from 'vue';
   import { useStore } from '@/store';
   import useApis from '@/apis';
   import router from "@/router";
@@ -108,27 +104,59 @@
       { required: true, message: props.isCode ? '验证码不能为空' : '密码不能为空', trigger: 'blur' },
     ],
   });
-
-  // 这个功能实现了吗? 
+ 
   const getCode = () => {
     start();
     props.onCode?.();
-    // console.log('获取验证码');
+    
+    console.log('获取验证码');
+    apis.sendLoginVerifyCode(data.officialNumber)
+    .then((res: any) => {
+      if (res.data.code === 200) {
+        ElMessage({
+        message: '验证码发送成功,请前往您的邮箱查看',
+          type: 'success',
+        })
+      } else {
+        ElMessage({
+          message: '验证码发送失败' + res.data.msg,
+          // message: '验证码发送失败',
+          type: 'error',
+        })
+      }
+    })
+    .catch((err: any) => {
+      ElMessage({
+        message: '验证码发送失败',
+        type: 'error',
+      })
+      console.log(err)
+    })
+    .finally(() => {
+    });
   };
 
   let assignmentId = ref(1)
   const handleLogin = () => {
+    if(!props.isCode) {
+      login()
+    } else {
+      loginByEmail()
+    }
+  };
+
+  const login = () => {
     apis.login({
       officialNumber: data.officialNumber,
       password: data.password
     }).then((_res:any) => {
       const data = _res.data.data
+      console.log(_res.data)
       if (_res.data.code === 200) {
         store.setUser(data);
         store.setToken(data?.token)
         localStorage.setItem('Authorization', data?.token);
         localStorage.setItem('User', data);
-        // router.push("/")
         router.push(`/home`)
       } else if(_res.data.code === 400){
         ElMessage({
@@ -142,8 +170,36 @@
         type: 'error',
       })
       console.log("登陆失败", _err)
-    })
-  };
+    })    
+  }
+
+  const loginByEmail = () => {
+    apis.loginByEmail({
+      officialEmail: data.officialNumber,
+      verifyCode: data.code
+    }).then((_res:any) => {
+      const data = _res.data.data
+      if (_res.data.code === 200) {
+        store.setUser(data);
+        store.setToken(data?.token)
+        localStorage.setItem('Authorization', data?.token);
+        localStorage.setItem('User', data);
+        router.push(`/home`)
+      } else if(_res.data.code === 400){
+        ElMessage({
+          message: '邮箱或验证码错误' + _res.data.msg,
+          type: 'error',
+        })
+      }
+    }).catch((_err:any) => {
+      ElMessage({
+        message: '网络错误',
+        type: 'error',
+      })
+      console.log("登陆失败", _err)
+    })    
+  } 
+
   const onClickSign = () => {
     router.push('/register');
   };

+ 13 - 11
src/views/LoginPage/component/Register.vue

@@ -11,9 +11,10 @@
         欢迎注册 SEEAI 平台账号
       </div>
       <!--角色-->
-      <el-form :rules="userRules" :model="userRegisterDTO" ref="formRef" :size="formSize">
-        <el-form-item label="账号角色" prop="role">
-          <el-select v-model="userRegisterDTO.role" placeholder="请选择注册账号的角色,注意角色选定无法修改">
+      <el-form label-position="right" label-width="65px" :rules="userRules" :model="userRegisterDTO" ref="formRef" :size="formSize">
+
+        <el-form-item label="角色" prop="role">
+          <el-select v-model="userRegisterDTO.role" placeholder="请选择注册账号的角色">
             <el-option v-for="item in roleOptions" :key="item.value" :label="item.label" :value="item.value"
               :disabled="item.disabled" />
           </el-select>
@@ -26,7 +27,7 @@
 
         <!--学号-->
         <el-form-item label="学号" prop="officialNumber">
-          <el-input v-model="userRegisterDTO.officialNumber" placeholder="请输入您的南大学号或工号"></el-input>
+          <el-input v-model="userRegisterDTO.officialNumber" placeholder="请输入南大学号或工号"></el-input>
         </el-form-item>
 
         <!--邮箱-->
@@ -40,13 +41,13 @@
         </el-form-item>
 
         <!--输入验证码-->
-        <!--TODO:发送验证码按钮和输入框在一起,参考登录界面-->
-        <div class="verify-code">
-          <el-form-item label="验证码" prop="verifyCode" class="form-item">
-            <el-input v-model="userRegisterDTO.verifyCode" placeholder="输入验证码"></el-input>
+          <el-form-item label="验证码" prop="verifyCode">
+            <el-input v-model="userRegisterDTO.verifyCode" placeholder="输入验证码">
+              <template #suffix>
+                <el-button type="text" @click="sendVerifyCode">获取动态码</el-button>
+              </template>
+            </el-input>
           </el-form-item>
-          <el-button @click="sendVerifyCode" class="button">发送验证码</el-button>
-        </div>
 
         <div style="display: flex; justify-content: center; align-items: center;">
           <el-button @click="register(formRef)" class="login-button">注册</el-button>
@@ -189,7 +190,8 @@ const sendVerifyCode = () => {
         })
       } else {
         ElMessage({
-          message: '验证码发送失败: ' + res.data.msg,
+          // message: '验证码发送失败' + res.data.msg,
+          message: '验证码发送失败',
           type: 'error',
         })
       }

+ 0 - 1
src/views/LoginPage/component/index.scss

@@ -14,7 +14,6 @@
 
       &:hover {
         color: #fff;
-        //background-color: rgba(var(--main-color), 0.9);
         background-color: rgba(#1677ff, 0.5);
       }
     }

+ 33 - 27
src/views/Profile.vue

@@ -31,33 +31,36 @@
           <template #extra>
             <el-button type="primary" @click="visible=true">修改信息</el-button>
           </template>
+
         <el-descriptions-item
-            :rowspan="2"
-            :width="140"
-            label="Photo"
+            :rowspan="3"
+            :width="120"
+            label="头像"
+            >
+          <el-avatar
             align="center"
-        >
-          <el-image
-              style="width: 100px; height: 100px"
-              :src="user.userAvatar"
-          />
+            style="width: 100px; height: 100px"
+            :src="user.userAvatar"/>
         </el-descriptions-item>
-        <el-descriptions-item label="Name">{{ user.name }}</el-descriptions-item>
-        <el-descriptions-item label="EnglishName">{{ user.englishName }}</el-descriptions-item>
-        <el-descriptions-item label="Gender">{{ user.gender == 'MAN' ? 'man': 'woman' }}</el-descriptions-item>
-        <el-descriptions-item label="Role">
+
+        <el-descriptions-item label="姓名">{{ user.name }}</el-descriptions-item>
+        <!-- <el-descriptions-item label="EnglishName">{{ user.englishName }}</el-descriptions-item>
+        <el-descriptions-item label="Gender">{{ user.gender == 'MAN' ? 'man': 'woman' }}</el-descriptions-item> -->
+        
+        <el-descriptions-item label="角色">
           <template v-if="user.role == 'STUDENT'">
-            <el-tag size="small" >Student</el-tag>
+            <el-tag size="small">学生</el-tag>
           </template>
-          <template v-else>
-            <el-tag size="small" type="error">Teacher</el-tag>
+          <template v-if="user.role == 'TEACHER'">
+            <el-tag size="small" type="error">教师</el-tag>
           </template>
         </el-descriptions-item>
-        <el-descriptions-item label="Birthday">{{ user.birthday }}</el-descriptions-item>
-        <el-descriptions-item label="Phone">{{ user.phone }}</el-descriptions-item>
-        <el-descriptions-item label="OfficialNumber">{{ user.officialNumber }}</el-descriptions-item>
-        <el-descriptions-item label="contentEmail">{{ user.contentEmail }}</el-descriptions-item>
-        <el-descriptions-item label="OfficialEmail">{{ user.officialEmail }}</el-descriptions-item>
+        
+        <!-- <el-descriptions-item label="Birthday">{{ user.birthday }}</el-descriptions-item> -->
+        <el-descriptions-item label="账号">{{ user.officialNumber }}</el-descriptions-item>
+        <!-- <el-descriptions-item label="手机号">{{ user.phone }}</el-descriptions-item> -->
+        <!-- <el-descriptions-item label="contentEmail">{{ user.contentEmail }}</el-descriptions-item> -->
+        <el-descriptions-item label="邮箱">{{ user.officialEmail }}</el-descriptions-item>
       </el-descriptions>
     </el-card>
   </div>
@@ -99,7 +102,7 @@
       <el-form-item label="邮箱" >
         <el-input v-model="user.officialEmail" placeholder="请输入名称" disabled></el-input>
       </el-form-item>
-      <el-form-item label="联系邮箱" >
+      <!-- <el-form-item label="联系邮箱" >
         <el-input v-model="userUpdateDTO.contentEmail" placeholder="请输入名称"></el-input>
       </el-form-item>
       <el-form-item label="英文名" >
@@ -110,13 +113,13 @@
           <el-radio value="MAN">男</el-radio>
           <el-radio value="WOMAN">女</el-radio>
         </el-radio-group>
-      </el-form-item>
-      <el-form-item label="手机号" >
-        <el-input v-model="userUpdateDTO.phone" placeholder="请输入名称"></el-input>
-      </el-form-item>
-      <el-form-item label="生日" >
+      </el-form-item> -->
+      <!-- <el-form-item label="手机号" >
+        <el-input v-model="userUpdateDTO.phone" placeholder="请输入手机号" disabled></el-input>
+      </el-form-item> -->
+      <!-- <el-form-item label="生日" >
         <el-date-picker v-model="userUpdateDTO.birthday" type="date" placeholder="生日" style="width: 180px"/>
-      </el-form-item>
+      </el-form-item> -->
     </el-form>
     <template #footer>
       <div class="dialog-footer">
@@ -166,6 +169,9 @@
           data = processData(data)
           Object.assign(user, data)
           Object.assign(userUpdateDTO, convertIUserToUserUpdateDTO(user))
+          if(user.userAvatar == null) {
+            user.userAvatar = "https://cube.elemecdn.com/e/fd/0fc7d20532fdaf769a25683617711png.png"
+          }
         })
         .catch((err:any) => {
           ElMessage({