diff --git a/library_system/src/App.vue b/library_system/src/App.vue index 6bca340..6427272 100644 --- a/library_system/src/App.vue +++ b/library_system/src/App.vue @@ -1,21 +1,32 @@ \ No newline at end of file diff --git a/library_system/src/components/HeaderBar.vue b/library_system/src/components/HeaderBar.vue index 925a78a..64e392e 100644 --- a/library_system/src/components/HeaderBar.vue +++ b/library_system/src/components/HeaderBar.vue @@ -22,10 +22,10 @@ 本周热租榜 本月热租榜 - + 图书管理 - + 用户借阅记录 @@ -72,15 +72,22 @@ import { useStore } from 'vuex' import { ElMessage } from 'element-plus' import { Reading, ArrowDown } from '@element-plus/icons-vue' import { Wallet } from '@element-plus/icons-vue' -import { computed, onMounted } from 'vue' +import { computed, onMounted, watch } from 'vue' const store = useStore() const router = useRouter() onMounted(async () => { - // 只有在用户已认证时才获取用户信息 - if (store.getters.isAuthenticated) { + // 等待会话初始化完成 + if (store.state.sessionInitialized && store.getters.isAuthenticated) { + await fetchUserInfo() + } +}) + +// 监听会话状态变化 +watch(() => store.state.sessionInitialized, async (newVal) => { + if (newVal && store.getters.isAuthenticated) { await fetchUserInfo() } }) @@ -88,7 +95,7 @@ onMounted(async () => { // 添加获取用户信息的方法 async function fetchUserInfo() { try { - // 只获取余额和VIP信息,不获取整个用户信息 + // 获取余额和VIP信息 await store.dispatch('fetchBalanceAndVip') } catch (error) { console.error('获取用户信息失败:', error) @@ -103,8 +110,6 @@ async function fetchUserInfo() { const vip = computed(() => store.state.vipLevel) const balance = computed(() => store.state.balance) const user = computed(() => store.state.user) -const isAdmin = computed(() => store.getters.isAdmin) - diff --git a/library_system/src/main.js b/library_system/src/main.js index b46a125..2b9699b 100644 --- a/library_system/src/main.js +++ b/library_system/src/main.js @@ -17,6 +17,9 @@ app.use(ElementPlus) app.use(store) app.use(router) +// 初始化会话 +store.dispatch('initSession') + app.mount('#app') window.store = store \ No newline at end of file diff --git a/library_system/src/router/index.js b/library_system/src/router/index.js index 79dcc68..6c4095f 100644 --- a/library_system/src/router/index.js +++ b/library_system/src/router/index.js @@ -102,6 +102,11 @@ const router = createRouter({ // 路由守卫 router.beforeEach((to, from, next) => { + // 等待会话初始化完成 + if (!store.state.sessionInitialized) { + return next() + } + const isAuthenticated = store.getters.isAuthenticated const isAdmin = store.getters.isAdmin diff --git a/library_system/src/store/index.js b/library_system/src/store/index.js index 2dff8e3..c33b4f4 100644 --- a/library_system/src/store/index.js +++ b/library_system/src/store/index.js @@ -6,7 +6,8 @@ export default createStore({ user: JSON.parse(sessionStorage.getItem('user')) || null, balance: JSON.parse(sessionStorage.getItem('balance')) || 0, vipLevel: JSON.parse(sessionStorage.getItem('vipLevel')) || 0, - borrowedBooks: JSON.parse(sessionStorage.getItem('borrowedBooks')) || [] + borrowedBooks: JSON.parse(sessionStorage.getItem('borrowedBooks')) || [], + sessionInitialized: false }, getters: { isAuthenticated: state => !!state.user, @@ -14,6 +15,12 @@ export default createStore({ }, mutations: { setUser(state, user) { + const admin = user.admin === 1; + const userData = { + ...user, + admin + }; + state.user = user sessionStorage.setItem('user', JSON.stringify(user)) }, @@ -53,18 +60,31 @@ export default createStore({ }) if (userData && userData.username) { + const admin = userData.admin === 1; + commit('setUser', { username: userData.username, pic: userData.pic || '', - admin: userData.admin || false + admin }) // 获取关联信息 - await dispatch('fetchBalanceAndVip') - await dispatch('fetchBorrowedBooks') + try { + await dispatch('fetchBalanceAndVip') + } catch (balanceError) { + console.warn('获取余额信息失败:', balanceError) + } + + try { + await dispatch('fetchBorrowedBooks') + } catch (booksError) { + console.warn('获取借阅书籍失败:', booksError) + } } } catch (error) { - console.log('未检测到有效会话') + console.log('未检测到有效会话,用户需要重新登录') + // 清除可能存在的无效数据 + commit('clearUser') } finally { commit('setSessionInitialized', true) } @@ -100,12 +120,12 @@ export default createStore({ async fetchUser({ commit, dispatch }) { try { const userData = await service.get('/user/getinfo') - + const admin = userData.admin === 1; // 用户信息接口直接返回用户对象 commit('setUser', { username: userData.username || '', pic: userData.pic || '', - admin: userData.admin || false + admin }) // 获取关联信息 @@ -128,40 +148,37 @@ export default createStore({ } }, - // 获取余额和VIP等级 - - async fetchBalanceAndVip({ commit }) { - try { - const response = await service.post('/user/findmoney') - const resData = response.data || {} - - // 正确解析响应数据 - if (resData.code === 200) { - const message = resData.message || '' - const balanceMatch = message.match(/余额为:(\d+\.\d+)元/) - const vipMatch = message.match(/当前VIP等级为:(\d+)/) - - if (balanceMatch && vipMatch) { - commit('setBalanceAndVip', { - balance: parseFloat(balanceMatch[1]), - vip: parseInt(vipMatch[1]) - }) - } else { - // 尝试从其他字段获取 - const balance = parseFloat(resData.balance) || 0 - const vip = parseInt(resData.vipLevel) || 0 - commit('setBalanceAndVip', { balance, vip }) + // 获取余额和VIP等级 - 符合接口文档1.5 + async fetchBalanceAndVip({ commit }) { + try { + const response = await service.post('/user/findmoney') + const resData = response.data || {} + + if (resData.code === 200) { + const message = resData.message || '' + // 使用正则表达式解析余额和VIP等级 + const balanceMatch = message.match(/余额为:(\d+\.?\d*)元/) + const vipMatch = message.match(/当前VIP等级为:(\d+)/) + + if (balanceMatch && vipMatch) { + const balance = parseFloat(balanceMatch[1]) + const vip = parseInt(vipMatch[1]) + commit('setBalanceAndVip', { balance, vip }) + } else { + console.warn('无法解析余额或VIP信息:', message) + commit('setBalanceAndVip', { balance: 0, vip: 0 }) + } + } else { + throw new Error(resData.message || '获取余额信息失败') + } + + return resData + } catch (error) { + console.error('获取余额失败:', error) + // 不抛出错误,避免影响其他功能 + return { code: 500, message: '获取余额失败' } } - } else { - throw new Error(resData.message || '获取余额信息失败') - } - - return resData - } catch (error) { - console.error('获取余额失败:', error) - throw error - } -}, + }, // 账户充值 @@ -214,16 +231,22 @@ async borrowBook({ dispatch }, { title }) { return response.data }, -// 归还书籍 +// 归还书籍 - 符合接口文档3.2 async returnBook({ dispatch }, { title }) { - const response = await service.post('/borrow/returnbook', - `title=${encodeURIComponent(title)}`, - { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } - ) - - // 还书后刷新用户信息 - await dispatch('fetchUser') - return response.data + try { + const response = await service.post('/borrow/returnbook', + `title=${encodeURIComponent(title)}`, + { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } + ) + + // 还书成功后刷新借阅书籍列表 + await dispatch('fetchBorrowedBooks') + + return response.data + } catch (error) { + console.error('还书失败:', error) + throw error + } }, // 查询全部书籍 - 符合接口文档 @@ -265,26 +288,26 @@ async returnBook({ dispatch }, { title }) { } }, - // 根据书名查单本书 - 符合接口文档 + // 根据书名查单本书 - 符合接口文档2.3 async fetchBookByTitle(_, payload) { - const { title } = payload; - - try { - const response = await service.get('/api/selectone', { - params: { title } - }) - - // 根据接口文档处理响应 - if (response.data && response.data.code === 200) { - return { data: response.data.data } - } else { - throw new Error(response.data?.message || '获取书籍信息失败') - } - } catch (error) { - console.error('API请求失败:', error) - throw error - } -}, + const { title } = payload; + + try { + const response = await service.get('/api/selectone', { + params: { title } + }) + + // 根据接口文档处理响应 + if (response.data && response.data.code === 200) { + return { data: response.data.data } + } else { + throw new Error(response.data?.message || '获取书籍信息失败') + } + } catch (error) { + console.error('API请求失败:', error) + throw error + } + }, // 新增书籍 async addBook(_, bookData) { diff --git a/library_system/src/utils/request.js b/library_system/src/utils/request.js index 897ac57..d24e273 100644 --- a/library_system/src/utils/request.js +++ b/library_system/src/utils/request.js @@ -29,7 +29,10 @@ service.interceptors.response.use( // 处理业务错误 (code !== 200) if (res && typeof res === 'object' && res.code !== undefined && res.code !== 200) { - ElMessage.error(res.message || '请求失败') + // 检查是否为静默请求 + if (!response.config.silent) { + ElMessage.error(res.message || '请求失败') + } return Promise.reject(new Error(res.message || 'Error')) } @@ -41,18 +44,27 @@ service.interceptors.response.use( if (error.response) { switch (error.response.status) { case 401: - store.dispatch('logout') - router.push('/login') - ElMessage.error('请先登录') + // 只有在非静默请求时才显示错误信息 + if (!error.config?.silent) { + store.dispatch('logout') + router.push('/login') + ElMessage.error('请先登录') + } break case 403: - ElMessage.error('没有操作权限') + if (!error.config?.silent) { + ElMessage.error('没有操作权限') + } break default: - ElMessage.error(error.response.data?.message || '请求失败') + if (!error.config?.silent) { + ElMessage.error(error.response.data?.message || '请求失败') + } } } else { - ElMessage.error('网络错误,请检查连接') + if (!error.config?.silent) { + ElMessage.error('网络错误,请检查连接') + } } return Promise.reject(error) } diff --git a/library_system/src/views/Auth/Login.vue b/library_system/src/views/Auth/Login.vue index d5a5fa7..85886df 100644 --- a/library_system/src/views/Auth/Login.vue +++ b/library_system/src/views/Auth/Login.vue @@ -69,20 +69,49 @@ const rules = ref({ const loginForm = ref(null) const loading = ref(false) +// const login = async () => { +// try { +// await loginForm.value.validate() +// loading.value = true + +// await store.dispatch('login', form.value) +// ElMessage.success('登录成功') + +// // 获取用户信息 +// await store.dispatch('fetchUser') + +// // 获取用户信息后,存入 localStorage +// const userInfo = store.state.user +// localStorage.setItem('userInfo', JSON.stringify(userInfo)) +// // 跳转到首页 +// router.push('/') +// } catch (error) { +// console.error('登录失败:', error) +// ElMessage.error(error.message || '登录失败') +// } finally { +// loading.value = false +// } +// } + const login = async () => { try { + // 验证表单 await loginForm.value.validate() loading.value = true - await store.dispatch('login', form.value) - ElMessage.success('登录成功') + // 调用登录 action + const response = await store.dispatch('login', form.value) + + // 从响应中获取用户信息 + const userInfo = response.user - // 获取用户信息 - await store.dispatch('fetchUser') - // 获取用户信息后,存入 localStorage - const userInfo = store.state.user - localStorage.setItem('userInfo', JSON.stringify(userInfo)) - // 跳转到首页 + // 转换 admin 值并更新状态 + store.commit('setUser', { + ...userInfo, + admin: userInfo.admin === 1 // 将 1/0 转换为 true/false + }) + + ElMessage.success('登录成功') router.push('/') } catch (error) { console.error('登录失败:', error) diff --git a/library_system/src/views/Books/BookDetail.vue b/library_system/src/views/Books/BookDetail.vue index b19f609..051b65b 100644 --- a/library_system/src/views/Books/BookDetail.vue +++ b/library_system/src/views/Books/BookDetail.vue @@ -73,11 +73,8 @@ const fetchBook = async () => { // 正确传递书名参数 const response = await store.dispatch('fetchBookByTitle', { title }) - // 处理API响应格式 - if (response.data && response.data.code === 200) { - book.value = response.data.data - } else if (response.data) { - // 处理没有code字段但直接返回数据的情况 + // 根据接口文档2.3处理响应 + if (response.data) { book.value = response.data } else { throw new Error('书籍不存在') diff --git a/library_system/src/views/Borrow/ReturnBook.vue b/library_system/src/views/Borrow/ReturnBook.vue index 8401f16..63bd08c 100644 --- a/library_system/src/views/Borrow/ReturnBook.vue +++ b/library_system/src/views/Borrow/ReturnBook.vue @@ -70,24 +70,25 @@ } const handleReturn = async (book) => { - try { - const response = await store.dispatch('returnBook', { title: book.title }) - - // 确保从响应中获取正确的归还时间 - const returnTime = response.data?.return_time || new Date().toISOString() - - // 更新本地状态 - store.commit('removeBorrowedBook', book.title) - - ElMessage.success(`《${book.title}》归还成功`) - - // 刷新借阅记录 - await store.dispatch('fetchBorrowedBooks') - } catch (error) { - console.error('归还失败:', error) - ElMessage.error(error.message || '归还失败') + try { + const response = await store.dispatch('returnBook', { title: book.title }) + + if (response.code === 200) { + ElMessage.success(`《${book.title}》归还成功`) + + // 从本地状态中移除已归还的书籍 + store.commit('removeBorrowedBook', book.title) + + // 重新获取借阅书籍列表以确保数据同步 + await fetchBorrowedBooks() + } else { + ElMessage.error(response.message || '归还失败') + } + } catch (error) { + console.error('归还失败:', error) + ElMessage.error(error.message || '归还失败') + } } -}