Quellcode durchsuchen

理解了 Vuex.Store 的使用,并用 localStorage 替代内存存储数据

reghao vor 4 Jahren
Ursprung
Commit
7a30685723

+ 26 - 0
package-lock.json

@@ -6856,6 +6856,11 @@
         }
       }
     },
+    "js-cookie": {
+      "version": "2.2.0",
+      "resolved": "https://registry.nlark.com/js-cookie/download/js-cookie-2.2.0.tgz?cache=0&sync_timestamp=1630493008410&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fjs-cookie%2Fdownload%2Fjs-cookie-2.2.0.tgz",
+      "integrity": "sha1-Gywnmm7s44ChIWi5JIUmWzWx7/s="
+    },
     "js-message": {
       "version": "1.0.5",
       "resolved": "https://registry.npm.taobao.org/js-message/download/js-message-1.0.5.tgz",
@@ -9907,6 +9912,11 @@
         "rechoir": "^0.6.2"
       }
     },
+    "shvl": {
+      "version": "2.0.3",
+      "resolved": "https://registry.nlark.com/shvl/download/shvl-2.0.3.tgz",
+      "integrity": "sha1-60vTdkT1aEu6H8UsMBDJb7Xmr9E="
+    },
     "signal-exit": {
       "version": "3.0.3",
       "resolved": "https://registry.npm.taobao.org/signal-exit/download/signal-exit-3.0.3.tgz",
@@ -11474,6 +11484,22 @@
       "resolved": "https://registry.npm.taobao.org/vuex/download/vuex-3.5.1.tgz",
       "integrity": "sha1-8bjc6mSbwlJUz09DWAgdv12hiz0="
     },
+    "vuex-persistedstate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.nlark.com/vuex-persistedstate/download/vuex-persistedstate-4.1.0.tgz",
+      "integrity": "sha1-EnFl+F9bRTT7MXCl06i+mBG9KlM=",
+      "requires": {
+        "deepmerge": "^4.2.2",
+        "shvl": "^2.0.3"
+      },
+      "dependencies": {
+        "deepmerge": {
+          "version": "4.2.2",
+          "resolved": "https://registry.npm.taobao.org/deepmerge/download/deepmerge-4.2.2.tgz",
+          "integrity": "sha1-RNLqNnm49NT/ujPwPYZfwee/SVU="
+        }
+      }
+    },
     "watchpack": {
       "version": "1.7.4",
       "resolved": "https://registry.npm.taobao.org/watchpack/download/watchpack-1.7.4.tgz?cache=0&sync_timestamp=1600385436518&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwatchpack%2Fdownload%2Fwatchpack-1.7.4.tgz",

+ 3 - 1
package.json

@@ -20,12 +20,14 @@
     "filepond-plugin-image-preview": "^4.6.4",
     "flv.js": "^1.6.2",
     "hls.js": "^0.14.13",
+    "js-cookie": "2.2.0",
     "vue": "^2.6.12",
     "vue-cookies": "^1.7.4",
     "vue-filepond": "^6.0.3",
     "vue-router": "^3.4.5",
     "vuetify": "^2.3.12",
-    "vuex": "^3.4.0"
+    "vuex": "^3.4.0",
+    "vuex-persistedstate": "^4.1.0"
   },
   "devDependencies": {
     "@vue/cli-plugin-babel": "^4.5.6",

+ 1 - 0
src/api/index.js

@@ -32,6 +32,7 @@ $axios.interceptors.request.use(
     return Promise.reject(error)
   }
 )
+
 // 响应拦截器
 $axios.interceptors.response.use(
   response => {

+ 5 - 0
src/api/user/account.js

@@ -1,6 +1,7 @@
 import $axios from '../index'
 
 const accountApi = {
+  registerApi: '/api/user/account/register',
   regVerifyCodeApi: '/api/user/account/getcode'
 }
 
@@ -8,3 +9,7 @@ const accountApi = {
 export function getRegVerifyCode(email) {
   return $axios.get(accountApi.regVerifyCodeApi + '?email=' + email)
 }
+
+export function register(email) {
+  return $axios.post(accountApi.registerApi)
+}

+ 16 - 0
src/api/user/auth.js

@@ -0,0 +1,16 @@
+import $axios from '../index'
+
+const authApi = {
+  loginApi: '/api/auth/login',
+  logoutApi: '/api/auth/logout'
+}
+
+// 登录
+export function login(loginData) {
+  return $axios.post(authApi.loginApi, loginData)
+}
+
+// 注销
+export function logout() {
+  return $axios.get(authApi.logoutApi)
+}

+ 5 - 5
src/components/comment/video-comment.vue

@@ -7,16 +7,16 @@
     </v-row>
     <v-row>
       <v-col cols="2" style="padding-top: 0px;">
-        <router-link v-if="this.$store.state.userInfo" :to="`/user/${this.$store.state.userInfo.id}`">
+        <router-link v-if="this.$store.state.user" :to="`/user/${this.$store.state.user.id}`">
           <v-avatar size="62">
             <v-img
-              :src="this.$store.state.userInfo.avatarUrl"
-              :alt="this.$store.state.userInfo.username"
-              :title="this.$store.state.userInfo.username"
+              :src="this.$store.state.user.avatarUrl"
+              :alt="this.$store.state.user.username"
+              :title="this.$store.state.user.username"
             />
           </v-avatar>
         </router-link>
-        <v-avatar v-if="this.$store.state.userInfo == null" size="62">
+        <v-avatar v-if="this.$store.state.user == null" size="62">
           <v-img
             src="/images/head.png"
             alt="头像"

+ 18 - 7
src/components/login-form.vue

@@ -25,7 +25,7 @@
     </v-row>
     <v-row justify="center">
       <v-col cols="5">
-        <img :src="captchaUrl" alt="验证码" title="点击刷新" style="cursor:pointer;" @click="getVerifyImage">
+        <img :src="captchaUrl" alt="验证码" title="点击刷新" style="cursor:pointer;" @click="getCaptcha">
       </v-col>
       <v-col cols="5">
         <v-text-field
@@ -44,43 +44,54 @@
       <v-col cols="7" />
     </v-row>
     <v-row justify="center">
-      <v-btn color="primary" @click="submitLog">登录</v-btn>
+      <v-btn color="primary" @click="submitLogin">登录</v-btn>
     </v-row>
   </div>
 </template>
 
 <script>
+import { randomString, getCaptchaUrl } from '@/utils'
+
 export default {
   name: 'LoginFrom',
   data() {
     return {
-      captchaUrl: '/api/user/account/captcha',
+      captchaUrl: '',
+      r: '',
       username: '',
       password: '',
       captcha: '',
       rememberMe: false
     }
   },
+  created() {
+    this.getCaptcha()
+  },
   methods: {
-    submitLog() {
+    submitLogin() {
       const username = this.username
       const password = this.password
       const captcha = this.captcha
+      const r = this.r
       const rememberMe = this.rememberMe
       const user = {
         username,
         password,
         captcha,
+        r,
         rememberMe
       }
       if (username === '' || password === '' || captcha === '') {
+        alert('captcha 或 username 字段不符合要求')
         return
       }
+      // 将数据返回给父组件
       this.$emit('login', user)
     },
-    getVerifyImage() {
-      // 点击事件发生时,captchaUrl 的值发生变化,然后才去请求后端
-      this.captchaUrl = '/api/user/account/captcha?t=' + new Date().getTime()
+    getCaptcha() {
+      this.r = randomString(10)
+      // 图片上发送点击事件时,captchaUrl 的值发生变化,然后才去请求后端
+      this.captchaUrl = getCaptchaUrl(this.r)
     }
   }
 }

+ 0 - 1
src/components/no-login-show.vue

@@ -29,5 +29,4 @@ export default {
 </script>
 
 <style>
-
 </style>

+ 1 - 1
src/components/player/player.vue

@@ -17,7 +17,7 @@ export default {
     }
   },
   mounted() {
-    const userInfo = this.$store.state.userInfo
+    const userInfo = this.$store.state.user
     if (userInfo != null) {
       this.userId = userInfo.id.toString()
     } else {

+ 18 - 6
src/components/register-from.vue

@@ -89,7 +89,7 @@
     </v-row>-->
     <v-row justify="center">
       <v-col cols="5">
-        <img :src="captchaUrl" alt="验证码" title="点击刷新" style="cursor:pointer;" @click="getVerifyImage">
+        <img :src="captchaUrl" alt="验证码" title="点击刷新" style="cursor:pointer;" @click="getCaptcha">
       </v-col>
       <v-col cols="5">
         <v-text-field
@@ -108,13 +108,15 @@
 </template>
 
 <script>
+import { randomString, getCaptchaUrl } from '@/utils'
 import { getRegVerifyCode } from '@/api/user/account'
 
 export default {
   name: 'Register',
   data() {
     return {
-      captchaUrl: '/api/user/account/captcha',
+      captchaUrl: '',
+      r: '',
       showMessage: false,
       registerUser: {
         regType: 1,
@@ -123,11 +125,19 @@ export default {
         password: '',
         // mobile: '',
         regVerifyCode: '',
-        captcha: ''
+        captcha: '',
+        r: ''
         // invitationCode: ''
+      },
+      verifyCode: {
+        type: '',
+        receiver: ''
       }
     }
   },
+  created() {
+    this.getCaptcha()
+  },
   methods: {
     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,}))$/
@@ -138,7 +148,7 @@ export default {
         console.log('password 字段不符合要求')
         return
       } else if (this.registerUser.captcha === '' || this.registerUser.username === '') {
-        console.log('captcha 或 username 字段不符合要求')
+        alert('captcha 或 username 字段不符合要求')
         return
       }
 
@@ -160,8 +170,10 @@ export default {
       // 返回到父组件
       this.$emit('register', this.registerUser)
     },
-    getVerifyImage() {
-      this.captchaUrl = '/api/user/account/captcha?t=' + new Date().getTime()
+    getCaptcha() {
+      this.r = randomString(10)
+      // 图片上发送点击事件时,captchaUrl 的值发生变化,然后才去请求后端
+      this.captchaUrl = getCaptchaUrl(this.r)
     },
     getVerifyCode() {
       var email = this.registerUser.email

+ 1 - 1
src/components/setting/user-base-setting.vue

@@ -85,7 +85,7 @@ export default {
     }
   },
   created() {
-    this.userInfo = this.$store.state.userInfo
+    this.userInfo = this.$store.state.user
   },
   methods: {
     save() {

+ 1 - 1
src/components/setting/user-head-setting.vue

@@ -80,7 +80,7 @@ export default {
     }
   },
   created() {
-    this.userInfo = this.$store.state.userInfo
+    this.userInfo = this.$store.state.user
   },
   methods: {
     setFile(value) {

+ 1 - 1
src/components/setting/user-login-log.vue

@@ -66,7 +66,7 @@ export default {
     }
   },
   created() {
-    this.userInfo = this.$store.state.userInfo
+    this.userInfo = this.$store.state.user
     this.getLog()
   },
   methods: {

+ 4 - 4
src/components/setting/user-password-setting.vue

@@ -48,7 +48,7 @@
         </v-row>
         <v-row justify="center">
           <v-col cols="5">
-            <v-img :src="captchaUrl" alt="验证码" title="点击刷新" style="cursor:pointer;" max-width="200" @click="getVerifyImage" />
+            <v-img :src="captchaUrl" alt="验证码" title="点击刷新" style="cursor:pointer;" max-width="200" @click="getCaptcha" />
           </v-col>
           <v-col cols="5">
             <v-text-field
@@ -102,7 +102,7 @@ export default {
         verifyCode: ''
       },
       temp: '',
-      captchaUrl: '/api/user/account/captcha',
+      captchaUrl: process.env.VUE_APP_BASE_API + '/api/user/account/captcha',
       showMessage: false,
       message: ''
     }
@@ -110,8 +110,8 @@ export default {
   created() {
   },
   methods: {
-    getVerifyImage() {
-      this.captchaUrl = '/api/user/account/captcha?t=' + new Date().getTime()
+    getCaptcha() {
+      this.captchaUrl = process.env.VUE_APP_BASE_API + '/api/user/account/captcha?t=' + new Date().getTime()
     },
     save() {
       if (this.passoword.oldPassword === '') {

+ 1 - 1
src/components/setting/user-top-image.vue

@@ -80,7 +80,7 @@ export default {
     }
   },
   created() {
-    this.userInfo = this.$store.state.userInfo
+    this.userInfo = this.$store.state.user
   },
   methods: {
     setFile(value) {

+ 2 - 2
src/layout/components/head.vue

@@ -1,5 +1,5 @@
 <template>
-  <v-menu v-if="this.$store.state.userInfo" top offset-y>
+  <v-menu v-if="this.$store.state.user" top offset-y>
     <template v-slot:activator="{ on, attrs }">
       <v-btn
         dark
@@ -55,7 +55,7 @@ export default {
     }
   },
   created() {
-    this.userInfo = this.$store.state.userInfo
+    this.userInfo = this.$store.state.user
   },
   methods: {
     headClick(value) {

+ 5 - 23
src/layout/index.vue

@@ -69,27 +69,10 @@
         </template>
         <span>通知</span>
       </v-tooltip>
-      <!--  登陆后 -->
-      <!-- <v-btn
-        v-if="this.$store.state.userInfo"
-        icon
-        large
-        @click="goToUserHome"
-      >
-        <v-avatar
-          size="32px"
-          item
-        >
-          <v-img
-            :src="this.$store.state.userInfo.avatarUrl"
-            :alt="this.$store.state.userInfo.username"
-            :title="this.$store.state.userInfo.username"
-          /></v-avatar>
-      </v-btn> -->
-      <Head v-if="this.$store.state.userInfo" />
+      <Head v-if="this.$store.state.user" />
       <!-- 未登录 -->
       <v-btn
-        v-if="this.$store.state.userInfo == null"
+        v-if="this.$store.state.user == null"
         outlined
         @click="goToLoginPage"
       >
@@ -129,10 +112,9 @@ export default {
     ]
   }),
   mounted() {
-
   },
   created() {
-    this.userInfo = this.$store.state.userInfo
+    this.userInfo = this.$store.state.user
     this.$vuetify.theme.dark = this.$store.state.darkThemOpen
   },
   methods: {
@@ -183,10 +165,10 @@ export default {
       this.$router.push('/')
     },
     goToUserHome() {
-      if (this.$route.path === '/user/' + this.$store.state.userInfo.id) {
+      if (this.$route.path === '/user/' + this.$store.state.user.id) {
         return
       }
-      this.$router.push('/user/' + this.$store.state.userInfo.id)
+      this.$router.push('/user/' + this.$store.state.user.id)
     }
   }
 }

+ 9 - 0
src/store/getters.js

@@ -0,0 +1,9 @@
+const getters = {
+  userInfo: state => state.user.userInfo,
+  token: state => state.user.token,
+  roles: state => state.user.roles,
+  avatar: state => state.user.avatar,
+  name: state => state.user.name
+}
+
+export default getters

+ 13 - 6
src/store/index.js

@@ -1,9 +1,13 @@
 import Vue from 'vue'
 import Vuex from 'vuex'
+import persistedState from 'vuex-persistedstate'
+import getters from './getters'
+import user from './modules/user'
 
 Vue.use(Vuex)
 
-export default new Vuex.Store({
+// Vuex 中的数据存储在内存中,页面刷新会使数据丢失,使用 persistedState 将其存储在 localStorage 而非内存中
+const store = new Vuex.Store({
   state: {
     webInfo: {
       name: 'HerTube',
@@ -19,11 +23,9 @@ export default new Vuex.Store({
     },
     darkThemOpen: false,
     userInfo: (localStorage.getItem('user') != null &&
-    localStorage.getItem('user') !== 'undefined' &&
-    localStorage.getItem('user') !== '')
-      ? JSON.parse(localStorage.getItem('user')) : null,
+        localStorage.getItem('user') !== 'undefined' &&
+        localStorage.getItem('user') !== '') ? JSON.parse(localStorage.getItem('user')) : null,
     uploadVideoDateTemp: {}
-
   },
   mutations: {
     setUserInfo(state, userInfo) {
@@ -40,5 +42,10 @@ export default new Vuex.Store({
   actions: {
   },
   modules: {
-  }
+    user
+  },
+  getters,
+  plugins: [persistedState()]
 })
+
+export default store

+ 109 - 0
src/store/modules/user.js

@@ -0,0 +1,109 @@
+import { login, logout } from '@/api/user/auth'
+import { register } from '@/api/user/account'
+import { getToken, setToken, removeToken } from '@/utils/auth'
+
+const getDefaultState = () => {
+  return {
+    userInfo: null,
+    token: getToken(),
+    name: '',
+    roles: [],
+    avatar: ''
+  }
+}
+
+const state = getDefaultState()
+
+const mutations = {
+  RESET_STATE: (state) => {
+    Object.assign(state, getDefaultState())
+  },
+  SET_USER_INFO: (state, userInfo) => {
+    state.userInfo = userInfo
+  },
+  SET_TOKEN: (state, token) => {
+    state.token = token
+  },
+  SET_NAME: (state, name) => {
+    state.name = name
+  },
+  SET_ROLES: (state, roles) => {
+    state.roles = roles
+  },
+  SET_AVATAR: (state, avatar) => {
+    state.avatar = avatar
+  }
+}
+
+const actions = {
+  // 用户注册
+  register({ commit }, registerData) {
+    return new Promise((resolve, reject) => {
+      register(registerData).then(res => {
+        if (res.code === 0) {
+          resolve()
+        } else {
+          console.log('用户注册失败')
+        }
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
+  // 用户登录
+  login({ commit }, loginData) {
+    return new Promise((resolve, reject) => {
+      login(loginData).then(res => {
+        if (res.code === 0) {
+          const userInfo = res.data
+          const token = userInfo.token
+
+          commit('SET_USER_INFO', userInfo)
+          commit('SET_TOKEN', token)
+          setToken(token)
+          resolve()
+        } else {
+          console.log('用户登录失败')
+        }
+      }).catch(error => {
+        reject(error)
+      })
+    })
+  },
+  // 获取用户信息
+  getInfo({ commit, state }) {
+    return new Promise((resolve, reject) => {
+      resolve()
+    })
+  },
+  // 用户注销
+  logout({ commit, state }) {
+    return new Promise((resolve, reject) => {
+      logout(state.token).then(() => {
+        console.log('1.用户注销...')
+        removeToken() // must remove  token  first
+        commit('RESET_STATE')
+        resolve()
+      }).catch(error => {
+        reject(error)
+        console.log('注销错误 -> ')
+        console.log(error)
+      })
+    })
+  },
+  // 删除本地存储的 token
+  resetToken({ commit }) {
+    return new Promise(resolve => {
+      removeToken() // must remove  token  first
+      commit('RESET_STATE')
+      resolve()
+    })
+  }
+}
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions
+}

+ 15 - 0
src/utils/auth.js

@@ -0,0 +1,15 @@
+import Cookies from 'js-cookie'
+
+const TokenKey = 'hertube_token'
+
+export function getToken() {
+  return Cookies.get(TokenKey)
+}
+
+export function setToken(token) {
+  return Cookies.set(TokenKey, token)
+}
+
+export function removeToken() {
+  return Cookies.remove(TokenKey)
+}

+ 15 - 0
src/utils/index.js

@@ -0,0 +1,15 @@
+// 获取随机字符串
+export function randomString(len) {
+  len = len || 16
+  var t = '012345678ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz'
+  var a = t.length
+  var res = ''
+  for (var i = 0; i < len; i++) res += t.charAt(Math.floor(Math.random() * a))
+  return res
+}
+
+// 获取 captcha url
+export function getCaptchaUrl(r) {
+  // 图片上发送点击事件时,captchaUrl 的值发生变化,然后才去请求后端
+  return process.env.VUE_APP_BASE_API + '/api/user/account/captcha?r=' + r
+}

+ 115 - 0
src/utils/request.js

@@ -0,0 +1,115 @@
+import axios from 'axios'
+import store from '@/store'
+import router from '@/router'
+import Vue from 'vue'
+import { Message } from 'element-ui' // 引用element-ui的加载和消息提示组件
+
+const $axios = axios.create({
+  // 5 分钟超时
+  timeout: 300000,
+  // 域名
+  baseURL: process.env.VUE_APP_BASE_API,
+  headers: {
+    'Content-Type': 'application/json; charset=UTF-8'
+  }
+})
+Vue.prototype.$http = axios // 并发请求
+// 在全局请求和响应拦截器中添加请求状态
+const loading = null
+
+// 请求拦截器
+$axios.interceptors.request.use(
+  config => {
+    const token = store.getters.token
+    if (token) {
+      // 在请求的 Authorization 首部添加 token
+      config.headers.Authorization = token
+      // config.headers.Authorization = 'Bearer ' + token
+    }
+    return config
+  },
+  error => {
+    return Promise.reject(error)
+  }
+)
+
+// 响应拦截器
+$axios.interceptors.response.use(
+  response => {
+    if (loading) {
+      loading.close()
+    }
+    const code = response.status
+    if ((code >= 200 && code < 300) || code === 304) {
+      return Promise.resolve(response.data)
+    } else {
+      return Promise.reject(response)
+    }
+  },
+  error => {
+    if (loading) {
+      loading.close()
+    }
+    if (error.response) {
+      switch (error.response.status) {
+        case 401:
+          // 返回401 清除token信息并跳转到登陆页面
+          console.log('401 错误...')
+          store.commit('delToken')
+          router.replace({
+            path: '/login',
+            query: {
+              redirect: router.currentRoute.fullPath
+            }
+          })
+          break
+        case 404:
+          Message.error('网络请求不存在')
+          break
+        default:
+          Message.error(error.response.data.message)
+      }
+    } else {
+      // 请求超时或者网络有问题
+      if (error.message.includes('timeout')) {
+        Message.error('请求超时!请检查网络是否正常')
+      } else {
+        Message.error(error.message)
+        Message.error('请求失败,请检查服务器是否已启动')
+      }
+    }
+    return Promise.reject(error)
+  }
+)
+
+// HTTP 请求
+export default {
+  get(url, params) {
+    return $axios({
+      method: 'get',
+      url,
+      params
+    })
+  },
+  post(url, data) {
+    return $axios({
+      method: 'post',
+      url,
+      data: JSON.stringify(data)
+    })
+  },
+  put(url, data) {
+    return $axios({
+      method: 'put',
+      url,
+      data: JSON.stringify(data)
+    })
+  },
+  delete(url, data) {
+    return $axios({
+      method: 'delete',
+      url,
+      data: JSON.stringify(data)
+    })
+  }
+}

+ 19 - 0
src/utils/validate.js

@@ -0,0 +1,19 @@
+/**
+ * 渲染路由时会使用
+ *
+ * @param {string} path
+ * @returns {Boolean}
+ */
+export function isExternal(path) {
+  return /^(https?:|mailto:|tel:)/.test(path)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validUsername(str) {
+  /* const valid_map = ['admin', 'editor']
+  return valid_map.indexOf(str.trim()) >= 0*/
+  return true
+}

+ 1 - 1
src/views/home/history.vue

@@ -1,6 +1,6 @@
 <template>
   <v-container fill-height>
-    <NoLoginShow v-if="this.$store.state.userInfo == null" />
+    <NoLoginShow v-if="this.$store.state.user == null" />
     <div v-else>
       <v-row>
         <v-col>

+ 1 - 1
src/views/home/playlist.vue

@@ -1,6 +1,6 @@
 <template>
   <v-container fill-height>
-    <NoLoginShow v-if="this.$store.state.userInfo == null" />
+    <NoLoginShow v-if="this.$store.state.user == null" />
   </v-container>
 </template>
 

+ 1 - 1
src/views/home/subscribe.vue

@@ -1,6 +1,6 @@
 <template>
   <v-container fill-height>
-    <NoLoginShow v-if="this.$store.state.userInfo == null" />
+    <NoLoginShow v-if="this.$store.state.user == null" />
   </v-container>
 </template>
 

+ 26 - 25
src/views/login.vue

@@ -30,7 +30,7 @@
             </v-row>
             <v-row style="height: 48px" />
             <LoginFrom v-show="showLogin" @login="userLogin" />
-            <RegisterFrom v-show="showLogin === false" @register="register" />
+            <RegisterFrom v-show="showLogin === false" @register="userRegister" />
             <v-row justify="center">
               <v-col cols="5">
                 <v-btn text color="primary">忘记密码</v-btn>
@@ -43,7 +43,6 @@
 
           </v-card>
         </v-col>
-
       </v-row>
       <v-snackbar
         v-model="showMessage"
@@ -68,6 +67,7 @@
 </template>
 
 <script>
+import { register } from '@/api/user/account'
 import LoginFrom from '@/components/login-form.vue'
 import RegisterFrom from '@/components/register-from.vue'
 
@@ -79,7 +79,9 @@ export default {
   },
   data() {
     return {
-      captchaUrl: '/api/user/account/captcha?r=123456',
+      // captchaUrl: process.env.VUE_APP_BASE_API + '/api/user/account/captcha?r=123456',
+      captchaUrl: '',
+      r: '',
       user: {},
       type: '登录',
       moveMessage: '没有账号,创建账号',
@@ -89,34 +91,33 @@ export default {
     }
   },
   created() {
-
   },
   methods: {
     userLogin(value) {
-      fetch(`/api/auth/login`, {
-        headers: {
-          'Content-Type': 'application/json; charset=UTF-8',
-          'X-XSRF-TOKEN': this.$cookies.get('XSRF-TOKEN')
-        },
-        method: 'POST',
-        credentials: 'include',
-        body: JSON.stringify(value)
-      }).then(response => response.json())
-        .then(json => {
-          if (json.code === 0) {
-            const userInfo = json.data
-            console.log(userInfo)
-            // 保存用户信息
-            this.$store.commit('setUserInfo', userInfo)
-            // 跳转到首页
-            this.$router.push('/')
+      // 调用 store/modules/user.js 中的 login 方法
+      this.$store.dispatch('user/login', value).then(() => {
+        // 登录成功后返回到首页
+        this.$router.push('/')
+      }).catch(() => {
+        console.log('用户登录失败')
+      })
+    },
+    userRegister(value) {
+      register(value)
+        .then(res => {
+          if (res.code === 0) {
+            console.log(res)
           } else {
-            this.message = json.message
-            this.showMessage = true
+            this.$notify({
+              title: res.code,
+              message: res.msg,
+              type: 'warning',
+              duration: 500
+            })
           }
         })
-        .catch(e => {
-          return null
+        .catch(error => {
+          this.$message.error(error.message)
         })
     },
     register(value) {

+ 5 - 5
src/views/user/index.vue

@@ -25,7 +25,7 @@
           </h2>
         </v-col>
         <v-col
-          v-if="this.$store.state.userInfo && this.$store.state.userInfo.id === id"
+          v-if="this.$store.state.user && this.$store.state.user.id === id"
           cols="6"
           md="4"
           class="hidden-sm-and-down ml-0 pl-4"
@@ -33,7 +33,7 @@
           <v-btn color="primary" @click="goToSetting">自定义频道</v-btn> <v-btn color="primary" @click="goToStudio">创作中心</v-btn>
         </v-col>
         <v-col
-          v-if="this.$store.state.userInfo == null || this.$store.state.userInfo.id != id"
+          v-if="this.$store.state.user == null || this.$store.state.user.id != id"
           cols="6"
           md="4"
         >
@@ -136,9 +136,9 @@ export default {
   },
   methods: {
     getUserInfo() {
-      // console.log(this.$store.state.userInfo)
-      // if (this.$store.state.userInfo !== null && this.$store.state.userInfo.id === this.id) {
-      //   this.userInfo = this.$store.state.userInfo
+      // console.log(this.$store.state.user)
+      // if (this.$store.state.user !== null && this.$store.state.user.id === this.id) {
+      //   this.userInfo = this.$store.state.user
       //   document.title = this.userInfo.username
       //   return
       // }

+ 3 - 3
src/views/vip/index.vue

@@ -1,6 +1,6 @@
 <template>
   <v-container fill-height>
-    <v-row v-if="this.$store.state.userInfo == null || checkPower.checkVip(this.$store.state.userInfo) === false" justify="center" align="center">
+    <v-row v-if="this.$store.state.user == null || checkPower.checkVip(this.$store.state.user) === false" justify="center" align="center">
       <v-col>
         <v-card
           class="mx-auto"
@@ -31,11 +31,11 @@
             height="200px"
             src="https://cdn.vuetifyjs.com/images/cards/docks.jpg"
           >
-            <v-card-title>你好,尊贵的VIP:  {{ this.$store.state.userInfo.username }}</v-card-title>
+            <v-card-title>你好,尊贵的VIP:  {{ this.$store.state.user.username }}</v-card-title>
           </v-img>
 
           <v-card-text class="text--primary">
-            <div>VIP到期时间: <strong>{{ TimeUtil.renderTime(this.$store.state.userInfo.vipStopTime) }}</strong></div>
+            <div>VIP到期时间: <strong>{{ TimeUtil.renderTime(this.$store.state.user.vipStopTime) }}</strong></div>
             <div>剩余观看次数:<strong> ∞ </strong></div>
           </v-card-text>