前后端登录注册连接成功

Change-Id: Ib5f9282fe7217b3363e542ce5c4e1c0d32619dcb
diff --git a/src/api/auth.js b/src/api/auth.js
new file mode 100644
index 0000000..a3c672a
--- /dev/null
+++ b/src/api/auth.js
@@ -0,0 +1,62 @@
+import request from './request'

+

+export const authApi = {

+  /**

+   * 用户登录

+   */

+  async login(loginData) {

+    console.log('📤 发送登录数据:', loginData)

+    

+    const requestData = {

+      user: loginData.user,

+      password: loginData.password

+    }

+    

+    return request({

+      url: '/api/auth/login',  // 需要 /api 前缀

+      method: 'post',

+      data: requestData

+    })

+  },

+

+  /**

+   * 用户注册

+   */

+  async register(registerData) {

+    console.log('📤 发送注册数据:', registerData)

+    

+    const requestData = {

+      username: registerData.username,

+      email: registerData.email,

+      password: registerData.password

+    }

+    

+    return request({

+      url: '/api/auth/register',  // 需要 /api 前缀

+      method: 'post',

+      data: requestData

+    })

+  },

+

+  /**

+   * 用户登出

+   */

+  logout() {

+    return request({

+      url: '/api/auth/logout',  // 需要 /api 前缀

+      method: 'post'

+    })

+  },

+

+  /**

+   * 获取登录状态

+   */

+  getStatus() {

+    return request({

+      url: '/api/auth/status',  // 需要 /api 前缀

+      method: 'get'

+    })

+  }

+}

+

+export default authApi
\ No newline at end of file
diff --git a/src/api/index.js b/src/api/index.js
new file mode 100644
index 0000000..6a72540
--- /dev/null
+++ b/src/api/index.js
@@ -0,0 +1,219 @@
+export { authApi } from './auth'

+export { userApi } from './user'

+

+// 默认导出request实例,方便其他地方使用

+export { default as request } from './request'

+

+// ===========================================

+

+// src/store/modules/auth.js - 认证状态管理

+import { authApi } from '@/api/auth'

+import { ElMessage } from 'element-plus'

+

+const state = {

+  // 登录状态

+  isLoggedIn: false,

+  // 用户信息

+  userInfo: null,

+  // Token信息

+  token: null,

+  // 登录加载状态

+  loginLoading: false

+}

+

+const getters = {

+  // 是否已登录

+  isAuthenticated: state => state.isLoggedIn,

+  // 获取用户信息

+  userInfo: state => state.userInfo,

+  // 获取用户名

+  username: state => state.userInfo?.user?.username || '',

+  // 获取用户头像

+  avatar: state => state.userInfo?.user?.avatar || '',

+  // 获取用户组信息

+  userGroup: state => state.userInfo?.user?.group || null,

+  // 登录加载状态

+  loginLoading: state => state.loginLoading

+}

+

+const mutations = {

+  // 设置登录状态

+  SET_LOGIN_STATUS(state, status) {

+    state.isLoggedIn = status

+  },

+  

+  // 设置用户信息

+  SET_USER_INFO(state, userInfo) {

+    state.userInfo = userInfo

+  },

+  

+  // 设置Token

+  SET_TOKEN(state, token) {

+    state.token = token

+  },

+  

+  // 设置登录加载状态

+  SET_LOGIN_LOADING(state, loading) {

+    state.loginLoading = loading

+  },

+  

+  // 清除用户数据

+  CLEAR_USER_DATA(state) {

+    state.isLoggedIn = false

+    state.userInfo = null

+    state.token = null

+    state.loginLoading = false

+  }

+}

+

+const actions = {

+  // 用户登录

+  async login({ commit }, loginData) {

+    try {

+      commit('SET_LOGIN_LOADING', true)

+      

+      const response = await authApi.login(loginData)

+      

+      if (response) {

+        // 保存Token

+        const tokenInfo = response.token

+        if (tokenInfo && tokenInfo.tokenValue) {

+          localStorage.setItem('token', tokenInfo.tokenValue)

+          localStorage.setItem('tokenInfo', JSON.stringify(tokenInfo))

+          commit('SET_TOKEN', tokenInfo)

+        }

+        

+        // 保存用户信息

+        localStorage.setItem('userInfo', JSON.stringify(response))

+        localStorage.setItem('isLoggedIn', 'true')

+        

+        commit('SET_USER_INFO', response)

+        commit('SET_LOGIN_STATUS', true)

+        

+        ElMessage.success('登录成功!')

+        return response

+      }

+    } catch (error) {

+      console.error('登录失败:', error)

+      throw error

+    } finally {

+      commit('SET_LOGIN_LOADING', false)

+    }

+  },

+  

+  // 用户注册

+  async register({ commit }, registerData) {

+    try {

+      commit('SET_LOGIN_LOADING', true)

+      

+      const response = await authApi.register(registerData)

+      

+      if (response) {

+        // 注册成功后自动登录

+        const tokenInfo = response.token

+        if (tokenInfo && tokenInfo.tokenValue) {

+          localStorage.setItem('token', tokenInfo.tokenValue)

+          localStorage.setItem('tokenInfo', JSON.stringify(tokenInfo))

+          commit('SET_TOKEN', tokenInfo)

+        }

+        

+        localStorage.setItem('userInfo', JSON.stringify(response))

+        localStorage.setItem('isLoggedIn', 'true')

+        

+        commit('SET_USER_INFO', response)

+        commit('SET_LOGIN_STATUS', true)

+        

+        ElMessage.success('注册成功!')

+        return response

+      }

+    } catch (error) {

+      console.error('注册失败:', error)

+      throw error

+    } finally {

+      commit('SET_LOGIN_LOADING', false)

+    }

+  },

+  

+  // 用户登出

+  async logout({ commit }) {

+    try {

+      await authApi.logout()

+    } catch (error) {

+      console.error('登出请求失败:', error)

+      // 即使登出请求失败,也要清除本地数据

+    } finally {

+      // 清除本地存储

+      localStorage.removeItem('token')

+      localStorage.removeItem('tokenInfo')

+      localStorage.removeItem('userInfo')

+      localStorage.removeItem('isLoggedIn')

+      

+      // 清除状态

+      commit('CLEAR_USER_DATA')

+      

+      ElMessage.success('已退出登录')

+    }

+  },

+  

+  // 检查登录状态

+  async checkLoginStatus({ commit }) {

+    try {

+      const response = await authApi.getStatus()

+      

+      if (response && response.isLoggedIn && response.user) {

+        // 更新用户信息

+        localStorage.setItem('userInfo', JSON.stringify(response.user))

+        localStorage.setItem('isLoggedIn', 'true')

+        

+        commit('SET_USER_INFO', response.user)

+        commit('SET_LOGIN_STATUS', true)

+        

+        return true

+      } else {

+        // 登录状态无效,清除本地数据

+        commit('CLEAR_USER_DATA')

+        localStorage.removeItem('token')

+        localStorage.removeItem('tokenInfo')

+        localStorage.removeItem('userInfo')

+        localStorage.removeItem('isLoggedIn')

+        

+        return false

+      }

+    } catch (error) {

+      console.error('检查登录状态失败:', error)

+      commit('CLEAR_USER_DATA')

+      return false

+    }

+  },

+  

+  // 从本地存储恢复登录状态

+  restoreLoginState({ commit }) {

+    const isLoggedIn = localStorage.getItem('isLoggedIn') === 'true'

+    const userInfo = localStorage.getItem('userInfo')

+    const tokenInfo = localStorage.getItem('tokenInfo')

+    

+    if (isLoggedIn && userInfo) {

+      try {

+        const parsedUserInfo = JSON.parse(userInfo)

+        const parsedTokenInfo = tokenInfo ? JSON.parse(tokenInfo) : null

+        

+        commit('SET_USER_INFO', parsedUserInfo)

+        commit('SET_TOKEN', parsedTokenInfo)

+        commit('SET_LOGIN_STATUS', true)

+        

+        console.log('✅ 已从本地存储恢复登录状态')

+      } catch (error) {

+        console.error('❌ 恢复登录状态失败:', error)

+        commit('CLEAR_USER_DATA')

+      }

+    }

+  }

+}

+

+export default {

+  namespaced: true,

+  state,

+  getters,

+  mutations,

+  actions

+}
\ No newline at end of file
diff --git a/src/api/request.js b/src/api/request.js
new file mode 100644
index 0000000..dd5aade
--- /dev/null
+++ b/src/api/request.js
@@ -0,0 +1,76 @@
+import axios from 'axios'

+import { ElMessage } from 'element-plus'

+import router from '@/router'

+

+const request = axios.create({

+  // 关键:不要设置baseURL,或者设置为空字符串

+  // 这样请求会发送到当前域名(8080),然后被代理转发到8081

+  baseURL: '',

+  timeout: 10000,

+  headers: {

+    'Content-Type': 'application/json'

+  }

+})

+

+request.interceptors.request.use(

+  config => {

+    const token = localStorage.getItem('token')

+    if (token) {

+      config.headers.Authorization = `Bearer ${token}`

+    }

+    

+    console.log('🚀 发送请求:', config.method?.toUpperCase(), config.url)

+    console.log('📤 请求数据:', config.data)

+    

+    return config

+  },

+  error => {

+    console.error('❌ 请求错误:', error)

+    return Promise.reject(error)

+  }

+)

+

+request.interceptors.response.use(

+  response => {

+    console.log('✅ 响应成功:', response.status, response.data)

+    return response.data

+  },

+  error => {

+    console.error('❌ 响应错误:', error)

+    

+    if (error.response) {

+      const { status, data } = error.response

+      

+      switch (status) {

+        case 401:

+          localStorage.removeItem('token')

+          localStorage.removeItem('isLoggedIn') 

+          localStorage.removeItem('userInfo')

+          ElMessage.error('登录已过期,请重新登录')

+          router.push('/login')

+          break

+        case 403:

+          ElMessage.error('权限不足')

+          break

+        case 404:

+          ElMessage.error('API接口不存在')

+          console.error('❌ 请求的URL:', error.config.url)

+          break

+        case 500:

+          ElMessage.error('服务器内部错误')

+          break

+        default:

+          const errorMessage = data?.message || `请求失败 (${status})`

+          ElMessage.error(errorMessage)

+      }

+    } else if (error.request) {

+      ElMessage.error('无法连接到服务器,请检查网络')

+    } else {

+      ElMessage.error('请求配置错误')

+    }

+    

+    return Promise.reject(error)

+  }

+)

+

+export default request
\ No newline at end of file
diff --git a/src/api/user.js b/src/api/user.js
new file mode 100644
index 0000000..2cfb40c
--- /dev/null
+++ b/src/api/user.js
@@ -0,0 +1,115 @@
+import request from './request'

+

+export const userApi = {

+  /**

+   * 获取当前用户信息

+   * @returns {Promise<Object>} 用户信息

+   */

+  getCurrentUser() {

+    return request({

+      url: '/user/profile',

+      method: 'get'

+    })

+  },

+

+  /**

+   * 更新用户资料

+   * @param {Object} profileData - 用户资料数据

+   * @returns {Promise<Object>} 更新响应

+   */

+  updateProfile(profileData) {

+    return request({

+      url: '/user/profile',

+      method: 'put',

+      data: profileData

+    })

+  },

+

+  /**

+   * 修改密码

+   * @param {Object} passwordData - 密码数据

+   * @param {string} passwordData.currentPassword - 当前密码

+   * @param {string} passwordData.newPassword - 新密码

+   * @returns {Promise<Object>} 修改响应

+   */

+  changePassword(passwordData) {

+    return request({

+      url: '/user/password',

+      method: 'put',

+      data: passwordData

+    })

+  },

+

+  /**

+   * 上传头像

+   * @param {FormData} formData - 包含头像文件的FormData

+   * @returns {Promise<Object>} 上传响应

+   */

+  uploadAvatar(formData) {

+    return request({

+      url: '/user/avatar',

+      method: 'post',

+      data: formData,

+      headers: {

+        'Content-Type': 'multipart/form-data'

+      }

+    })

+  },

+

+  /**

+   * 获取用户统计信息

+   * @returns {Promise<Object>} 统计信息

+   */

+  getUserStats() {

+    return request({

+      url: '/user/stats',

+      method: 'get'

+    })

+  },

+

+  /**

+   * 获取用户活动记录

+   * @param {Object} params - 查询参数

+   * @param {string} params.type - 活动类型

+   * @param {number} params.page - 页码

+   * @param {number} params.size - 每页大小

+   * @returns {Promise<Object>} 活动记录

+   */

+  getUserActivities(params = {}) {

+    return request({

+      url: '/user/activities',

+      method: 'get',

+      params

+    })

+  },

+

+  /**

+   * 获取用户上传的种子

+   * @param {Object} params - 查询参数

+   * @param {number} params.page - 页码

+   * @param {number} params.size - 每页大小

+   * @returns {Promise<Object>} 种子列表

+   */

+  getUserTorrents(params = {}) {

+    return request({

+      url: '/user/torrents',

+      method: 'get',

+      params

+    })

+  },

+

+  /**

+   * 获取登录历史

+   * @param {Object} params - 查询参数

+   * @param {number} params.page - 页码

+   * @param {number} params.size - 每页大小

+   * @returns {Promise<Object>} 登录历史

+   */

+  getLoginHistory(params = {}) {

+    return request({

+      url: '/user/login-history',

+      method: 'get',

+      params

+    })

+  }

+}