|
|
|
@ -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) {
|
|
|
|
|