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 || '归还失败')
+ }
}
-}