diff --git a/library_system/src/components/BookCard.vue b/library_system/src/components/BookCard.vue index 9fc4319..8e01c96 100644 --- a/library_system/src/components/BookCard.vue +++ b/library_system/src/components/BookCard.vue @@ -14,6 +14,7 @@ {{ book.state }} 阅读量: {{ book.number }}次 + 借阅 diff --git a/library_system/src/store/index.js b/library_system/src/store/index.js index 40746d2..3a02522 100644 --- a/library_system/src/store/index.js +++ b/library_system/src/store/index.js @@ -13,7 +13,7 @@ export default createStore({ isAdmin: state => state.user?.admin || false }, mutations: { - setUser(state, user) { + setUser(state, user) { state.user = user }, setBalanceAndVip(state, { balance, vip }) { @@ -28,9 +28,41 @@ export default createStore({ state.balance = 0 state.vipLevel = 0 state.borrowedBooks = [] + }, + removeBorrowedBook(state, title) { + state.borrowedBooks = state.borrowedBooks.filter(book => book.title !== title) + }, + setSessionInitialized(state, value) { + state.sessionInitialized = value } }, actions: { + async initSession({ commit, dispatch }) { + try { + // 静默获取用户信息 + const userData = await service.get('/user/getinfo', { + silent: true // 避免未登录时显示错误 + }) + + if (userData && userData.username) { + commit('setUser', { + username: userData.username, + pic: userData.pic || '', + admin: userData.admin || false + }) + + // 获取关联信息 + await dispatch('fetchBalanceAndVip') + await dispatch('fetchBorrowedBooks') + } + } catch (error) { + console.log('未检测到有效会话') + } finally { + commit('setSessionInitialized', true) + } + }, + + // 用户登录 async login({ dispatch }, { username, password }) { const response = await service.post('/user/login', @@ -89,44 +121,51 @@ export default createStore({ }, // 获取余额和VIP等级 - async fetchBalanceAndVip({ commit }) { - try { - const response = await service.post('/user/findmoney') - - // 解析消息提取余额和VIP等级 - const message = response.data.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 { - console.error('无法解析余额信息:', message) - // 尝试从数据字段获取 - if (response.data.data) { - commit('setBalanceAndVip', { - balance: parseFloat(response.data.data.balance) || 0, - vip: parseInt(response.data.data.vipLevel) || 0 - }) - } - } - - return response.data - } catch (error) { - console.error('获取余额失败:', error) - throw error +async fetchBalanceAndVip({ commit }) { + try { + const response = await service.post('/user/findmoney') + + // 确保从 response.data 获取数据 + const resData = response.data || {} + const message = resData.message || '' + + // 解析消息提取余额和VIP等级 + 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 { + console.error('无法解析余额信息:', message) + // 尝试从数据字段获取(虽然接口返回data为null,但保留此逻辑以防后端变更) + if (resData.data) { + commit('setBalanceAndVip', { + balance: parseFloat(resData.data.balance) || 0, + vip: parseInt(resData.data.vipLevel) || 0 + }) + } else { + // 添加调试日志 + console.log('完整响应数据:', resData) } - }, + } + + return resData + } catch (error) { + console.error('获取余额失败:', error) + throw error + } +}, // 账户充值 - async recharge(_, { money }) { + async recharge({ dispatch }, { money }) { // 添加 { dispatch } 解构 const response = await service.post('/user/recharge', `money=${money}`, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } ) + // 充值后刷新余额 await dispatch('fetchBalanceAndVip') return response.data @@ -158,25 +197,29 @@ export default createStore({ return response.data }, - // 租借书籍 - async borrowBook(_, { title }) { - const response = await service.post('/borrow/borrowbook', - `title=${encodeURIComponent(title)}`, - { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } - ) - - return response.data - }, - - // 归还书籍 - async returnBook(_, { title }) { - const response = await service.post('/borrow/returnbook', - `title=${encodeURIComponent(title)}`, - { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } - ) - - return response.data - }, + // 租借书籍 +async borrowBook({ dispatch }, { title }) { + const response = await service.post('/borrow/borrowbook', + `title=${encodeURIComponent(title)}`, + { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } + ) + + // 借书后刷新用户信息 + await dispatch('fetchUser') + return response.data +}, + +// 归还书籍 +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 +}, // 查询全部书籍 - 符合接口文档 async fetchBooks(_, params = {}) { @@ -217,21 +260,23 @@ export default createStore({ }, // 根据书名查单本书 - 符合接口文档 - async fetchBookByTitle(_, title) { - const response = await service.get('/api/selectone', { - params: { title } - }) - - // 处理不同响应格式 - let book = null - if (response.data) { - book = response.data.data || response.data - } else { - book = response - } - - return { data: book } - }, + async fetchBookByTitle(_, payload) { // 接收 payload 对象 + const { title } = payload; // 解构出 title + const response = await service.get('/api/selectone', { + params: { title } // 正确传递查询参数 + }) + + // 处理不同响应格式 + let bookData = null + if (response.data) { + // 适配不同后端响应结构 + bookData = response.data.data || response.data + } else { + bookData = response + } + + return { data: bookData } +}, // 新增书籍 async addBook(_, bookData) { diff --git a/library_system/src/views/Books/BookDetail.vue b/library_system/src/views/Books/BookDetail.vue index f9f00fa..03746af 100644 --- a/library_system/src/views/Books/BookDetail.vue +++ b/library_system/src/views/Books/BookDetail.vue @@ -56,7 +56,7 @@ const route = useRoute() const router = useRouter() const store = useStore() -const bookTitle = route.params.title +const bookTitle = ref(route.params.title) const book = ref(null) const isAdmin = computed(() => store.getters.isAdmin) @@ -67,19 +67,20 @@ onMounted(async () => { const fetchBook = async () => { try { - const response = await store.dispatch('fetchBookByTitle', bookTitle) + // 使用路由参数中的 bookTitle + const response = await store.dispatch('fetchBookByTitle', { title: bookTitle }) book.value = response.data } catch (error) { console.error('获取书籍详情失败:', error) ElMessage.error('获取书籍详情失败') - // 预设数据 - book.value = { - id: bookId, - title: '示例书籍', + // 预设数据 + book.value = { + id: bookTitle, // 使用标题作为ID + title: 111, // 使用路由参数 url: 'https://picsum.photos/id/24/300/400', money: 5.00, number: 8, - content: '这是一本示例书籍,用于展示书籍详情页面的效果。包含了书籍的基本信息和详细介绍,用户可以在这里查看书籍的具体内容并进行借阅操作。', + content: `无法获取《${bookTitle}》的详细信息,显示示例数据`, state: '维护中', } } diff --git a/library_system/src/views/Books/BookList.vue b/library_system/src/views/Books/BookList.vue index 53f270f..ad32576 100644 --- a/library_system/src/views/Books/BookList.vue +++ b/library_system/src/views/Books/BookList.vue @@ -102,7 +102,12 @@ const fetchBooks = async () => { } catch (error) { console.error('获取书籍列表失败:', error) ElMessage.error('获取书籍列表失败') - + books.value = [ + { id: 1, title: '三体', url: 'https://picsum.photos/id/24/200/300', money: 5, number: 12, state: '正常', content: '科幻' }, + { id: 2, title: '人类简史', url: 'https://picsum.photos/id/25/200/300', money: 4, number: 10, state: '正常', content: '历史' }, + { id: 3, title: '百年孤独', url: 'https://picsum.photos/id/26/200/300', money: 6, number: 0, state: '维护中', content: '文学' }, + ] + total.value = books.value.length } } diff --git a/library_system/src/views/Borrow/BorrowBook.vue b/library_system/src/views/Borrow/BorrowBook.vue index 2e64c5b..e92d27b 100644 --- a/library_system/src/views/Borrow/BorrowBook.vue +++ b/library_system/src/views/Borrow/BorrowBook.vue @@ -22,7 +22,7 @@ v-for="book in books" :key="book.id" :book="book" - @click="handleBorrow(book)" /> + @borrow="handleBorrow(book)" />