فهرست منبع

优化用户登录功能

reghao 3 سال پیش
والد
کامیت
79f723fcd1

+ 6 - 1
src/api/user/account.js

@@ -5,7 +5,8 @@ const accountApi = {
   selectUsernameApi: '/api/user/account/select/username',
   checkEmailApi: '/api/user/account/check/email',
   verifyCodeApi: '/api/account/verifyCode',
-  registerApi: '/api/account/user/register'
+  registerApi: '/api/account/user/register',
+  resetPasswordApi: '/api/account/user/reset'
 }
 
 export function getBase64Captcha(captchaUrl) {
@@ -32,3 +33,7 @@ export function getVerifyCode(verifyCode) {
 export function register(userRegistry) {
   return $axios.post(accountApi.registerApi, userRegistry)
 }
+
+export function resetPassword(resetPasswordData) {
+  return $axios.post(accountApi.resetPasswordApi, resetPasswordData)
+}

+ 57 - 25
src/components/login-form-mobile.vue

@@ -4,9 +4,9 @@
       <v-col cols="10">
         <v-text-field
           v-model="userLogin.username"
-          placeholder="请输入手机号/邮箱"
-          label="手机号/邮箱"
-          :rules="[() => userLogin.username != null || '手机号/邮箱不能为空']"
+          placeholder="请输入手机号"
+          label="手机号"
+          :rules="[() => userLogin.username != null || '手机号不能为空']"
           clearable
         />
       </v-col>
@@ -17,9 +17,9 @@
           <v-col cols="5">
             <v-text-field
               v-model="userLogin.password"
-              placeholder="请输入验证码"
-              label="验证码"
-              :rules="[() => userLogin.password != null || '验证码不能为空']"
+              placeholder="请输入短信验证码"
+              label="短信验证码"
+              :rules="[() => userLogin.password != null || '短信验证码不能为空']"
               clearable
             />
           </v-col>
@@ -36,7 +36,7 @@
       <v-col cols="5">
         <v-text-field
           v-model="userLogin.captchaCode"
-          placeholder="图形验证码"
+          placeholder="请输入图形验证码"
           label="图形验证码"
           :rules="[() => userLogin.captchaCode != null || '图形验证码不能为空']"
           clearable
@@ -46,6 +46,7 @@
     <v-row justify="center">
       <v-btn color="primary" @click="submitLogin">登录/注册</v-btn>
     </v-row>
+
     <v-snackbar
       v-model="showMessage"
       :top="true"
@@ -70,24 +71,27 @@
 import { randomString, getCaptchaUrl } from '@/utils'
 import { getVerifyCode } from '@/api/user/account'
 import { getPubkey } from '@/api/user/auth'
+import { JSEncrypt } from 'jsencrypt'
 
 export default {
   name: 'Register',
   data() {
     return {
       captchaUrl: '',
-      showMessage: false,
+      captchaBase64: '',
       userLogin: {
         accountType: 1,
-        loginType: 2,
+        loginType: 1,
         username: null,
         password: null,
         captchaCode: null,
         r: null,
-        plat: 'web',
-        showMessage: false,
-        message: ''
-      }
+        plat: 'web'
+      },
+      pubkey: '',
+      pubkeyR: '',
+      showMessage: false,
+      message: ''
     }
   },
   created() {
@@ -96,6 +100,23 @@ export default {
   },
   methods: {
     submitLogin() {
+      this.userLogin.password = this.$options.methods.encryptPassword(this.userLogin.password, this.pubkey, this.pubkeyR)
+      if (this.userLogin.username === '') {
+        this.showMessage = true
+        this.message = '手机号不能为空'
+        return
+      }
+      if (this.userLogin.password === '' || this.userLogin.password === null) {
+        this.showMessage = true
+        this.message = '短信验证码不能为空'
+        return
+      }
+      if (this.userLogin.captchaCode === '') {
+        this.showMessage = true
+        this.message = '图形验证码不能为空'
+        return
+      }
+
       // 将数据返回给父组件
       this.$emit('login', this.userLogin)
     },
@@ -117,22 +138,33 @@ export default {
         console.error(error.message)
       })
     },
+    encryptPassword(password, pubkey, pubkeyR) {
+      var encryptor = new JSEncrypt()
+      encryptor.setPublicKey(pubkey)
+      return encryptor.encrypt(pubkeyR + password)
+    },
     getVerifyCode() {
+      if (this.userLogin.username === null || this.userLogin.username === '') {
+        this.showMessage = true
+        this.message = '请填写手机号'
+        return
+      }
+
       const verifyCodeReq = {}
       verifyCodeReq.receiver = this.userLogin.username
       verifyCodeReq.notifyType = 2
-      getVerifyCode(verifyCodeReq)
-        .then(res => {
-          if (res.code === 0) {
-            this.showMessage = true
-            this.message = '验证码已发送, 请注意查收'
-          } else {
-            console.error(res.msg)
-          }
-        })
-        .catch(error => {
-          console.error(error.message)
-        })
+      getVerifyCode(verifyCodeReq).then(res => {
+        if (res.code === 0) {
+          this.showMessage = true
+          this.message = '验证码已发送, 请注意查收'
+        } else {
+          this.showMessage = true
+          this.message = res.msg
+        }
+      }).catch(error => {
+        this.showMessage = true
+        this.message = error
+      })
     }
   }
 }

+ 21 - 21
src/components/register-form.vue

@@ -1,6 +1,6 @@
 <template>
   <div>
-    <!--<v-row justify="center">
+    <v-row justify="center">
       <v-col cols="10">
         <v-text-field
           v-model="userRegistry.username"
@@ -12,7 +12,7 @@
           @blur="selectUsername"
         />
       </v-col>
-    </v-row>-->
+    </v-row>
     <v-row justify="center">
       <v-col cols="10">
         <v-text-field
@@ -59,15 +59,15 @@
     </v-row>
     <v-row justify="center">
       <v-col cols="5">
-        <img :src="captchaUrl" alt="验证码" title="点击刷新" style="cursor:pointer;" @click="getCaptcha">
+        <img :src="captchaUrl" alt="图形验证码" title="点击刷新" style="cursor:pointer;" @click="getCaptcha">
         <!--<img :src="captchaBase64" alt="验证码" title="点击刷新" style="cursor:pointer;" @click="getCaptcha">-->
       </v-col>
       <v-col cols="5">
         <v-text-field
           v-model="userRegistry.captchaCode"
-          placeholder="验证码"
-          label="验证码"
-          :rules="[() => userRegistry.captchaCode != null || '验证码不能为空']"
+          placeholder="图形验证码"
+          label="图形验证码"
+          :rules="[() => userRegistry.captchaCode != null || '图形验证码不能为空']"
           clearable
         />
       </v-col>
@@ -88,7 +88,6 @@ export default {
     return {
       captchaUrl: '',
       captchaBase64: '',
-      showMessage: false,
       userRegistry: {
         regType: 1,
         email: '',
@@ -107,13 +106,16 @@ export default {
       isUsernameExist(this.userRegistry.username)
         .then(res => {
           if (res.code === 0) {
-            console.log(res.msg)
+            this.showMessage = true
+            this.message = res.msg
           } else {
-            alert(res.data)
+            this.showMessage = true
+            this.message = res.data
           }
         })
         .catch(error => {
-          console.error(error.message)
+          this.showMessage = true
+          this.message = error.message
         })
     },
     selectUsername() {
@@ -193,17 +195,15 @@ export default {
       const verifyCodeReq = {}
       verifyCodeReq.receiver = email
       verifyCodeReq.notifyType = 1
-      getVerifyCode(verifyCodeReq)
-        .then(res => {
-          if (res.code === 0) {
-            alert(res.msg)
-          } else {
-            console.error(res.msg)
-          }
-        })
-        .catch(error => {
-          console.error(error.message)
-        })
+      getVerifyCode(verifyCodeReq).then(res => {
+        if (res.code === 0) {
+          alert(res.msg)
+        } else {
+          console.error(res.msg)
+        }
+      }).catch(error => {
+        console.error(error.message)
+      })
     }
   }
 }

+ 213 - 0
src/components/reset-password-form.vue

@@ -0,0 +1,213 @@
+<template>
+  <div>
+    <v-row justify="center">
+      <v-col cols="10">
+        <v-text-field
+          v-model="userRegistry.username"
+          placeholder="请输入用户名"
+          label="用户名"
+          :rules="[() => userRegistry.username != null || '用户名不能为空']"
+          clearable
+          @input="checkUsername"
+          @blur="selectUsername"
+        />
+      </v-col>
+    </v-row>
+    <v-row justify="center">
+      <v-col cols="10">
+        <v-text-field
+          v-model="userRegistry.email"
+          placeholder="请输入邮箱"
+          label="邮箱"
+          :rules="[() => userRegistry.email != null || '邮箱不能为空']"
+          type="email"
+          clearable
+          @blur="checkEmail"
+        />
+      </v-col>
+    </v-row>
+    <v-row justify="center">
+      <v-col cols="10">
+        <v-row justify="center">
+          <v-col cols="5">
+            <v-text-field
+              v-model="userRegistry.regVerifyCode"
+              placeholder="请输入邮件验证码"
+              label="邮件验证码"
+              :rules="[() => userRegistry.regVerifyCode != null || '邮件验证码不能为空']"
+              type="email"
+              clearable
+            />
+          </v-col>
+          <v-col cols="5">
+            <v-btn color="primary" @click="getVerifyCode">获取邮件验证码</v-btn>
+          </v-col>
+        </v-row>
+      </v-col>
+    </v-row>
+    <v-row justify="center">
+      <v-col cols="10">
+        <v-text-field
+          v-model="userRegistry.password"
+          placeholder="请输入密码"
+          label="密码"
+          :rules="[() => userRegistry.password != null || '密码不能为空']"
+          clearable
+          type="password"
+        />
+      </v-col>
+    </v-row>
+    <v-row justify="center">
+      <v-col cols="5">
+        <img :src="captchaUrl" alt="图形验证码" title="点击刷新" style="cursor:pointer;" @click="getCaptcha">
+        <!--<img :src="captchaBase64" alt="验证码" title="点击刷新" style="cursor:pointer;" @click="getCaptcha">-->
+      </v-col>
+      <v-col cols="5">
+        <v-text-field
+          v-model="userRegistry.captchaCode"
+          placeholder="图形验证码"
+          label="图形验证码"
+          :rules="[() => userRegistry.captchaCode != null || '图形验证码不能为空']"
+          clearable
+        />
+      </v-col>
+    </v-row>
+    <v-row justify="center">
+      <v-btn color="primary" @click="submitRegister">注册</v-btn>
+    </v-row>
+  </div>
+</template>
+
+<script>
+import { randomString, getCaptchaUrl } from '@/utils'
+import { getVerifyCode, isUsernameExist, selectUsername, isEmailExist } from '@/api/user/account'
+
+export default {
+  name: 'ResetPasswordForm',
+  data() {
+    return {
+      captchaUrl: '',
+      captchaBase64: '',
+      showMessage: false,
+      userRegistry: {
+        regType: 1,
+        email: '',
+        password: '',
+        regVerifyCode: '',
+        captchaCode: '',
+        r: ''
+      }
+    }
+  },
+  created() {
+    this.getCaptcha()
+  },
+  methods: {
+    checkUsername() {
+      isUsernameExist(this.userRegistry.username)
+        .then(res => {
+          if (res.code === 0) {
+            console.log(res.msg)
+          } else {
+            alert(res.data)
+          }
+        })
+        .catch(error => {
+          console.error(error.message)
+        })
+    },
+    selectUsername() {
+      selectUsername(this.userRegistry.username).then(res => {
+        if (res.code === 0) {
+          console.log(res.msg)
+        } else {
+          alert(res.data)
+        }
+      })
+        .catch(error => {
+          console.error(error.message)
+        })
+    },
+    checkEmail() {
+      const email = this.userRegistry.email
+      if (email === null || email === '') {
+        return
+      }
+
+      isEmailExist(this.userRegistry.email)
+        .then(res => {
+          if (res.code === 0) {
+            console.log(res.msg)
+          } else {
+            alert(res.data)
+          }
+        })
+        .catch(error => {
+          console.error(error.message)
+        })
+    },
+    submitRegister() {
+      var re = /^(([^()[\]\\.,;:\s@\"]+(\.[^()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
+      if (!re.test(this.userRegistry.email)) {
+        console.log('email 字段不符合要求')
+        return
+      } else if (this.userRegistry.password === '' || this.userRegistry.password.length < 6) {
+        console.log('password 字段不符合要求')
+        return
+      } else if (this.userRegistry.captchaCode === '') {
+        alert('captchaCode 或 username 字段不符合要求')
+        return
+      }
+
+      if (this.$store.state.webInfo.openInvitationRegister === 1 && this.userRegistry.invitationCode === '') {
+        console.log('openInvitationRegister 或 invitationCode 字段不符合要求')
+        return
+      }
+      // 返回到父组件
+      this.$emit('register', this.userRegistry)
+    },
+    getCaptcha() {
+      const randomStr = randomString(10)
+      this.userRegistry.r = randomStr
+      // 图片上发送点击事件时,captchaUrl 的值发生变化,然后才去请求后端
+      this.captchaUrl = getCaptchaUrl(randomStr)
+      /* getBase64Captcha(this.captchaUrl)
+        .then(res => {
+          if (res.code === 0) {
+            this.captchaBase64 = 'data:image/jpg;base64,' + res.data
+          } else {
+            alert(res.data)
+          }
+        })
+        .catch(error => {
+          console.error(error.message)
+        })*/
+    },
+    getVerifyCode() {
+      const email = this.userRegistry.email
+      if (email == null || email === '') {
+        alert('请输入邮箱地址')
+        return
+      }
+
+      const verifyCodeReq = {}
+      verifyCodeReq.receiver = email
+      verifyCodeReq.notifyType = 1
+      getVerifyCode(verifyCodeReq)
+        .then(res => {
+          if (res.code === 0) {
+            alert(res.msg)
+          } else {
+            console.error(res.msg)
+          }
+        })
+        .catch(error => {
+          console.error(error.message)
+        })
+    }
+  }
+}
+</script>
+
+<style>
+</style>

+ 1 - 1
src/layout/index.vue

@@ -122,7 +122,7 @@ export default {
           this.$router.push('/')
         }
       }).catch(() => {
-        console.log('用户登录失败')
+        console.log('用户注销失败')
       })
     },
     goToLoginPage() {

+ 19 - 3
src/store/modules/user.js

@@ -1,5 +1,5 @@
 import { login, logout } from '@/api/user/auth'
-import { register } from '@/api/user/account'
+import { register, resetPassword } from '@/api/user/account'
 import { getMyInfo } from '@/api/user/user'
 import { getToken, setToken, removeToken } from '@/utils/auth'
 
@@ -55,6 +55,20 @@ const actions = {
       })
     })
   },
+  // 重置密码
+  resetPassword({ commit }, resetPasswordData) {
+    return new Promise((resolve, reject) => {
+      resetPassword(resetPasswordData).then(res => {
+        if (res.code === 0) {
+          resolve()
+        } else {
+          alert(res.data)
+        }
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
   // 用户登录
   login({ commit }, loginData) {
     return new Promise((resolve, reject) => {
@@ -70,15 +84,17 @@ const actions = {
               commit('SET_USER_INFO', userInfo)
               resolve()
             } else {
-              console.log(res.data)
+              reject(res.data)
             }
           }).catch(error => {
             reject(error)
           })
         } else {
-          console.log(res.data)
+          // 登录失败
+          reject(res.data)
         }
       }).catch(error => {
+        // 登录请求错误
         reject(error)
       })
     })

+ 35 - 15
src/views/home/index.vue

@@ -10,6 +10,24 @@
         </v-col>
       </v-row>
     </div>
+
+    <v-snackbar
+      v-model="showMessage"
+      :top="true"
+      :timeout="3000"
+    >
+      {{ message }}
+      <template v-slot:action="{ attrs }">
+        <v-btn
+          color="pink"
+          text
+          v-bind="attrs"
+          @click="showMessage = false"
+        >
+          关闭
+        </v-btn>
+      </template>
+    </v-snackbar>
   </v-container>
 </template>
 
@@ -26,7 +44,9 @@ export default {
     return {
       videoList: [],
       busy: false,
-      page: 1
+      page: 1,
+      showMessage: false,
+      message: ''
     }
   },
   created() {
@@ -40,21 +60,21 @@ export default {
       }, 1000)
     },
     getRecommendVideo(page) {
-      videoRecommend(page)
-        .then(res => {
-          if (res.code === 0) {
-            for (const item of res.data.list) {
-              this.videoList.push(item)
-            }
-            this.page += 1
-            this.busy = false
-          } else {
-            console.error(res.msg)
+      videoRecommend(page).then(res => {
+        if (res.code === 0) {
+          for (const item of res.data.list) {
+            this.videoList.push(item)
           }
-        })
-        .catch(error => {
-          console.error(error.message)
-        })
+          this.page += 1
+          this.busy = false
+        } else {
+          this.showMessage = true
+          this.message = res.msg
+        }
+      }).catch(error => {
+        this.showMessage = true
+        this.message = error
+      })
     }
   }
 }

+ 5 - 5
src/views/login.vue

@@ -21,9 +21,9 @@
               <h1>{{ type }}</h1>
             </v-row>
             <v-row style="height: 48px" />
-            <LoginFormMobile v-show="showLogin" @login="userLogin" />
-            <ResetPasswordForm v-show="pageCode === 2" @login="resetPassword" />
-            <RegisterForm v-show="showLogin === false" @register="userRegister" />
+            <LoginFormMobile v-if="showLogin" @login="userLogin" />
+            <!--            <ResetPasswordForm v-show="pageCode === 2" @login="resetPassword" />-->
+            <RegisterForm v-if="showLogin === false" @register="userRegister" />
             <v-row justify="center">
               <v-col cols="5" style="text-align:left">
                 <v-btn text @click="moveResetPassword">{{ moveResetPasswordMessage }}</v-btn>
@@ -59,14 +59,14 @@
 
 <script>
 import LoginFormMobile from '@/components/login-form-mobile.vue'
-import ResetPasswordForm from '@/components/reset-password-form'
+/* import ResetPasswordForm from '@/components/reset-password-form'*/
 import RegisterForm from '@/components/register-form.vue'
 
 export default {
   name: 'Login',
   components: {
     LoginFormMobile,
-    ResetPasswordForm,
+    /* ResetPasswordForm,*/
     RegisterForm
   },
   data() {