From 9e8ce09450085ad549fa005db7beff2cdd405a5f Mon Sep 17 00:00:00 2001 From: hyx <1515023255@qq.com> Date: Fri, 15 Aug 2025 19:07:30 +0800 Subject: [PATCH] =?UTF-8?q?8/15=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library_system/src/components/HeaderBar.vue | 6 +- library_system/src/store/index.js | 88 ++++++++++--------- library_system/src/utils/request.js | 26 ++---- library_system/src/views/Books/BookDetail.vue | 33 +++++-- .../src/views/Borrow/ReturnBook.vue | 27 +++--- 5 files changed, 103 insertions(+), 77 deletions(-) diff --git a/library_system/src/components/HeaderBar.vue b/library_system/src/components/HeaderBar.vue index a8679ce..925a78a 100644 --- a/library_system/src/components/HeaderBar.vue +++ b/library_system/src/components/HeaderBar.vue @@ -78,7 +78,6 @@ import { computed, onMounted } from 'vue' const store = useStore() const router = useRouter() -// 添加 onMounted 钩子来获取用户信息 onMounted(async () => { // 只有在用户已认证时才获取用户信息 if (store.getters.isAuthenticated) { @@ -100,11 +99,16 @@ 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) + + + + const activeIndex = computed(() => { const routeName = router.currentRoute.value.name if (routeName === 'Home') return 'home' diff --git a/library_system/src/store/index.js b/library_system/src/store/index.js index 3a02522..2dff8e3 100644 --- a/library_system/src/store/index.js +++ b/library_system/src/store/index.js @@ -3,10 +3,10 @@ import service from '../utils/request' export default createStore({ state: { - user: null, - balance: 0, - vipLevel: 0, - borrowedBooks: [] + 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')) || [] }, getters: { isAuthenticated: state => !!state.user, @@ -15,19 +15,27 @@ export default createStore({ mutations: { setUser(state, user) { state.user = user + sessionStorage.setItem('user', JSON.stringify(user)) }, setBalanceAndVip(state, { balance, vip }) { state.balance = balance state.vipLevel = vip + sessionStorage.setItem('balance', JSON.stringify(balance)) + sessionStorage.setItem('vipLevel', JSON.stringify(vip)) }, setBorrowedBooks(state, books) { state.borrowedBooks = books + sessionStorage.setItem('borrowedBooks', JSON.stringify(books)) }, clearUser(state) { state.user = null state.balance = 0 state.vipLevel = 0 state.borrowedBooks = [] + sessionStorage.removeItem('user') + sessionStorage.removeItem('balance') + sessionStorage.removeItem('vipLevel') + sessionStorage.removeItem('borrowedBooks') }, removeBorrowedBook(state, title) { state.borrowedBooks = state.borrowedBooks.filter(book => book.title !== title) @@ -121,35 +129,31 @@ export default createStore({ }, // 获取余额和VIP等级 -async fetchBalanceAndVip({ commit }) { + + 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) { + // 正确解析响应数据 + 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(resData.data.balance) || 0, - vip: parseInt(resData.data.vipLevel) || 0 + balance: parseFloat(balanceMatch[1]), + vip: parseInt(vipMatch[1]) }) } else { - // 添加调试日志 - console.log('完整响应数据:', resData) + // 尝试从其他字段获取 + const balance = parseFloat(resData.balance) || 0 + const vip = parseInt(resData.vipLevel) || 0 + commit('setBalanceAndVip', { balance, vip }) } + } else { + throw new Error(resData.message || '获取余额信息失败') } return resData @@ -158,6 +162,7 @@ async fetchBalanceAndVip({ commit }) { throw error } }, + // 账户充值 async recharge({ dispatch }, { money }) { // 添加 { dispatch } 解构 @@ -232,7 +237,8 @@ async returnBook({ dispatch }, { title }) { } const response = await service.get('/api/select', config) - + console.log('请求书籍:', route.params.title) + console.log('API响应:', response) // 处理不同响应格式 let list = [] let total = 0 @@ -260,22 +266,24 @@ async returnBook({ dispatch }, { title }) { }, // 根据书名查单本书 - 符合接口文档 - async fetchBookByTitle(_, payload) { // 接收 payload 对象 - const { title } = payload; // 解构出 title - const response = await service.get('/api/selectone', { - params: { title } // 正确传递查询参数 - }) + async fetchBookByTitle(_, payload) { + const { title } = payload; - // 处理不同响应格式 - let bookData = null - if (response.data) { - // 适配不同后端响应结构 - bookData = response.data.data || response.data - } else { - bookData = response + 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 } - - return { data: bookData } }, // 新增书籍 diff --git a/library_system/src/utils/request.js b/library_system/src/utils/request.js index a962ded..897ac57 100644 --- a/library_system/src/utils/request.js +++ b/library_system/src/utils/request.js @@ -21,31 +21,26 @@ service.interceptors.request.use( } ) -// 响应拦截器 - 增强版 +// 响应拦截器 service.interceptors.response.use( response => { + // 处理成功响应 const res = response.data - // 只处理有 code 字段的响应 - if (res && typeof res === 'object' && res.code !== undefined) { - // 业务错误处理 (code 不为 200) - if (res.code !== 200) { - ElMessage.error(res.message || '请求失败') - return Promise.reject(new Error(res.message || 'Error')) - } - // 成功响应返回整个响应对象 - return response + // 处理业务错误 (code !== 200) + if (res && typeof res === 'object' && res.code !== undefined && res.code !== 200) { + ElMessage.error(res.message || '请求失败') + return Promise.reject(new Error(res.message || 'Error')) } - // 没有 code 字段的响应直接返回数据 - return res + // 返回整个响应对象,确保组件可以访问响应头等信息 + return response }, error => { // 处理HTTP错误 if (error.response) { switch (error.response.status) { case 401: - // 未登录处理 store.dispatch('logout') router.push('/login') ElMessage.error('请先登录') @@ -53,11 +48,8 @@ service.interceptors.response.use( case 403: ElMessage.error('没有操作权限') break - case 500: - ElMessage.error('服务器内部错误') - break default: - ElMessage.error(error.message || '请求失败') + ElMessage.error(error.response.data?.message || '请求失败') } } else { ElMessage.error('网络错误,请检查连接') diff --git a/library_system/src/views/Books/BookDetail.vue b/library_system/src/views/Books/BookDetail.vue index 03746af..b19f609 100644 --- a/library_system/src/views/Books/BookDetail.vue +++ b/library_system/src/views/Books/BookDetail.vue @@ -56,8 +56,8 @@ const route = useRoute() const router = useRouter() const store = useStore() -const bookTitle = ref(route.params.title) const book = ref(null) +const loading = ref(true) const isAdmin = computed(() => store.getters.isAdmin) @@ -67,25 +67,40 @@ onMounted(async () => { const fetchBook = async () => { try { - // 使用路由参数中的 bookTitle - const response = await store.dispatch('fetchBookByTitle', { title: bookTitle }) - book.value = response.data + loading.value = true + const title = route.params.title + + // 正确传递书名参数 + 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字段但直接返回数据的情况 + book.value = response.data + } else { + throw new Error('书籍不存在') + } } catch (error) { console.error('获取书籍详情失败:', error) - ElMessage.error('获取书籍详情失败') - // 预设数据 + ElMessage.error(error.message || '获取书籍详情失败') + + // 使用有意义的预设数据 book.value = { - id: bookTitle, // 使用标题作为ID - title: 111, // 使用路由参数 + title: route.params.title, url: 'https://picsum.photos/id/24/300/400', money: 5.00, number: 8, - content: `无法获取《${bookTitle}》的详细信息,显示示例数据`, + content: `无法获取《${route.params.title}》的详细信息`, state: '维护中', } + } finally { + loading.value = false } } + const borrowBook = async () => { try { await store.dispatch('borrowBook', { title: book.value.title }) diff --git a/library_system/src/views/Borrow/ReturnBook.vue b/library_system/src/views/Borrow/ReturnBook.vue index 299f50d..8401f16 100644 --- a/library_system/src/views/Borrow/ReturnBook.vue +++ b/library_system/src/views/Borrow/ReturnBook.vue @@ -70,17 +70,24 @@ } const handleReturn = async (book) => { - try { - await store.dispatch('returnBook', { title: book.title }) - ElMessage.success(`《${book.title}》归还成功`) - store.commit('removeBorrowedBook', book.title) - await fetchBorrowedBooks() - - } catch (error) { - console.error('归还失败:', error) - ElMessage.error(error.message || '归还失败') - } + 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 || '归还失败') } +}