二次更新

hyx_brand
hyx 1 month ago
parent ddc810f5ed
commit 44c71c9562

@ -38,13 +38,24 @@
<el-icon><ArrowDown /></el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="goToProfile"></el-dropdown-item>
<el-dropdown-item @click="goToRecharge"></el-dropdown-item>
<el-dropdown-item @click="goToRecords"></el-dropdown-item>
<el-dropdown-item divided @click="logout">退</el-dropdown-item>
</el-dropdown-menu>
</template>
<el-dropdown-menu>
<!-- 用户信息展示区域 -->
<div class="user-dropdown-info">
<div class="user-name">{{ user.username }}</div>
<div class="user-vip">VIP{{ vip }}</div>
<div class="user-balance">
<el-icon><Wallet /></el-icon>
余额: {{ balance }}
</div>
</div>
<el-divider /> <!-- 分割线 -->
<!-- 保留的功能选项 -->
<el-dropdown-item @click="goToRecharge"></el-dropdown-item>
<el-dropdown-item @click="goToRecords"></el-dropdown-item>
<el-dropdown-item divided @click="logout">退</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<div v-else>
<el-button type="text" @click="goToLogin"></el-button>
@ -60,9 +71,12 @@ import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
import { ElMessage } from 'element-plus'
import { Reading, ArrowDown } from '@element-plus/icons-vue'
import { Wallet } from '@element-plus/icons-vue'
const store = useStore()
const router = useRouter()
const vip = computed(() => store.state.vipLevel)
const balance = computed(() => store.state.balance)
const user = computed(() => store.state.user)
const isAdmin = computed(() => store.getters.isAdmin)
@ -163,7 +177,7 @@ const logout = () => {
.user-info {
display: flex;
align-items: center;
gap: 10px;
gap: 5px;
}
.username {
@ -176,4 +190,29 @@ const logout = () => {
color: white;
cursor: pointer;
}
.user-dropdown-info {
padding: 5px 16px;
text-align: center;
}
.user-name {
font-weight: bold;
margin-bottom: 4px;
}
.user-vip {
color: #ff9a2e;
font-size: 14px;
margin-bottom: 6px;
}
.user-balance {
font-size: 14px;
color: #666;
display: flex;
align-items: center;
justify-content: center;
gap: 2px;
}
</style>

@ -20,12 +20,7 @@ const routes = [
name: 'Register',
component: () => import('../views/Auth/Register.vue')
},
{
path: '/profile',
name: 'Profile',
component: () => import('../views/User/Profile.vue'),
meta: { requiresAuth: true }
},
{
path: '/books',
name: 'Books',
@ -44,12 +39,12 @@ const routes = [
component: () => import('../views/Books/AddBook.vue'),
meta: { requiresAuth: true, requiresAdmin: true }
},
{
path: '/books/edit/:id',
name: 'EditBook',
component: () => import('../views/Books/EditBook.vue'),
meta: { requiresAuth: true, requiresAdmin: true }
},
// {
// path: '/books/edit/:id',
// name: 'EditBook',
// component: () => import('../views/Books/EditBook.vue'),
// meta: { requiresAuth: true, requiresAdmin: true }
// },
{
path: '/borrow',
name: 'BorrowBook',

@ -1,10 +1,10 @@
import { createStore } from 'vuex'
import axios from 'axios'
import service from '../utils/request'
// 配置axios基础路径
axios.defaults.baseURL = 'http://localhost:8877'
// 允许跨域携带cookie
axios.defaults.withCredentials = true
// // 配置axios基础路径
// axios.defaults.baseURL = 'http://localhost:8877'
// // 允许跨域携带cookie
// axios.defaults.withCredentials = true
export default createStore({
state: {
@ -39,7 +39,7 @@ export default createStore({
actions: {
// 用户登录
async login({ dispatch }, { username, password }) {
const response = await axios.post('/user/login',
const response = await service.post('/user/login',
`username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}`,
{ headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
)
@ -55,7 +55,7 @@ export default createStore({
// 用户注册
async register(_, { username, password }) {
const response = await axios.post('/user/register',
const response = await service.post('/user/register',
`username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}`,
{ headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
)
@ -68,23 +68,34 @@ export default createStore({
},
// 获取当前用户信息
async fetchUser({ commit, dispatch }) {
const response = await axios.get('/user/getinfo')
if (response.data.code === 200) {
commit('setUser', response.data.data)
// 同时获取余额和VIP信息
await dispatch('fetchBalanceAndVip')
// 获取已借书籍
await dispatch('fetchBorrowedBooks')
}
return response.data
},
async fetchUser({ commit, dispatch }) {
const response = await service.get('/user/getinfo')
// 接口可能返回两种格式:
// 1. 带code的标准格式{code:200, message:..., data: null}
// 2. 直接返回用户信息:{username: "张三", pic: "..."}
if (response.data.code === 200) {
// 情况1如果code=200但data为null可能接口直接在根节点返回用户信息
const userData = response.data.data || response.data;
// 过滤掉非用户信息字段如code/message
const filteredUser = {
username: userData.username || '',
pic: userData.pic || ''
};
commit('setUser', filteredUser);
await dispatch('fetchBalanceAndVip');
await dispatch('fetchBorrowedBooks');
} else {
// 处理接口返回非200的情况如未登录
commit('setUser', null);
}
return response.data;
},
// 获取余额和VIP等级
async fetchBalanceAndVip({ commit }) {
const response = await axios.post('/user/findmoney')
const response = await service.post('/user/findmoney')
if (response.data.code === 200) {
// 解析消息提取余额和VIP等级
@ -104,7 +115,7 @@ export default createStore({
// 账户充值
async recharge(_, { money }) {
const response = await axios.post('/user/recharge',
const response = await service.post('/user/recharge',
`money=${money}`,
{ headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
)
@ -124,7 +135,7 @@ export default createStore({
// 获取借阅记录
async fetchBorrowRecords() {
const response = await axios.get('/user/findone')
const response = await service.get('/user/findone')
if (response.data.code !== 200) {
throw new Error(response.data.message || '获取借阅记录失败')
@ -135,7 +146,7 @@ export default createStore({
// 获取当前用户已借书籍
async fetchBorrowedBooks({ commit }) {
const response = await axios.get('/user/borrow/books')
const response = await service.get('/user/borrow/books')
if (response.data.code === 200) {
commit('setBorrowedBooks', response.data.data || [])
@ -146,7 +157,7 @@ export default createStore({
// 借书
async borrowBook(_, { title }) {
const response = await axios.post('/borrow/borrowbook',
const response = await service.post('/borrow/borrowbook',
`title=${encodeURIComponent(title)}`,
{ headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
)
@ -160,7 +171,7 @@ export default createStore({
// 还书
async returnBook(_, { title }) {
const response = await axios.post('/borrow/returnbook',
const response = await service.post('/borrow/returnbook',
`title=${encodeURIComponent(title)}`,
{ headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
)
@ -185,7 +196,7 @@ export default createStore({
url += `?${queryParams.toString()}`
}
const response = await axios.get(url)
const response = await service.get(url)
if (response.data.code !== 200) {
throw new Error(response.data.message || '获取书籍列表失败')
@ -200,7 +211,7 @@ export default createStore({
},
async fetchBookById(_, id) {
const response = await axios.get(`/api/selectone?id=${id}`)
const response = await service.get(`/api/selectone?id=${id}`)
if (response.data.code !== 200) {
throw new Error(response.data.message || '获取书籍详情失败')
@ -210,7 +221,7 @@ export default createStore({
},
async addBook(_, bookData) {
const response = await axios.post('/api/add', bookData, {
const response = await service.post('/api/add', bookData, {
headers: { 'Content-Type': 'application/json' }
})
@ -222,7 +233,7 @@ export default createStore({
},
async deleteBook(_, { title }) {
const response = await axios.post('/user/delete',
const response = await service.post('/user/delete',
`title=${encodeURIComponent(title)}`,
{ headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
)
@ -235,7 +246,7 @@ export default createStore({
},
async fetchWeeklyRank() {
const response = await axios.get('/api/rank/weekly')
const response = await service.get('/api/rank/weekly')
if (response.data.code !== 200) {
throw new Error(response.data.message || '获取本周热租榜失败')
@ -245,7 +256,7 @@ export default createStore({
},
async fetchMonthlyRank() {
const response = await axios.get('/api/rank/monthly')
const response = await service.get('/api/rank/monthly')
if (response.data.code !== 200) {
throw new Error(response.data.message || '获取本月热租榜失败')

@ -74,7 +74,7 @@ const login = async () => {
await loginForm.value.validate()
loading.value = true
await store.dispatch('user/login', form.value)
await store.dispatch('login', form.value)
ElMessage.success('登录成功')
//

@ -96,7 +96,7 @@ const submitForm = async () => {
await addBookForm.value.validate()
loading.value = true
await store.dispatch('book/addBook', form.value)
await store.dispatch('addBook', form.value)
ElMessage.success('添加书籍成功')
router.push('/books')
} catch (error) {

@ -67,7 +67,7 @@ onMounted(async () => {
const fetchBook = async () => {
try {
const response = await store.dispatch('book/fetchBookById', bookId)
const response = await store.dispatch('fetchBookById', bookId)
book.value = response.data
} catch (error) {
console.error('获取书籍详情失败:', error)
@ -87,7 +87,7 @@ const fetchBook = async () => {
const borrowBook = async () => {
try {
await store.dispatch('borrow/borrowBook', { title: book.value.title })
await store.dispatch('borrowBook', { title: book.value.title })
ElMessage.success(`成功借阅《${book.value.title}`)
//
await fetchBook()
@ -109,7 +109,7 @@ const deleteBook = async () => {
}
)
await store.dispatch('book/deleteBook', { title: book.value.title })
await store.dispatch('deleteBook', { title: book.value.title })
ElMessage.success('书籍已删除')
router.push('/books')
} catch (error) {

@ -96,7 +96,7 @@ const fetchBooks = async () => {
keyword: searchKeyword.value
}
const response = await store.dispatch('book/fetchBooks', params)
const response = await store.dispatch('fetchBooks', params)
books.value = response.data.list
total.value = response.data.total
} catch (error) {

@ -65,7 +65,7 @@ const fetchBooks = async () => {
keyword: searchKeyword.value
}
const response = await store.dispatch('book/fetchBooks', params)
const response = await store.dispatch('fetchBooks', params)
books.value = response.data.list
total.value = response.data.total
} catch (error) {
@ -102,7 +102,7 @@ const handleBorrow = async (book) => {
return
}
await store.dispatch('borrow/borrowBook', { title: book.title })
await store.dispatch('borrowBook', { title: book.title })
ElMessage.success(`成功借阅《${book.title}`)
//
await fetchBooks()

@ -60,11 +60,11 @@
onMounted(async () => {
try {
//
const weeklyResponse = await store.dispatch('book/fetchWeeklyRank')
const weeklyResponse = await store.dispatch('fetchWeeklyRank')
weeklyRank.value = weeklyResponse.data.slice(0, 6)
//
const monthlyResponse = await store.dispatch('book/fetchMonthlyRank')
const monthlyResponse = await store.dispatch('fetchMonthlyRank')
monthlyRank.value = monthlyResponse.data.slice(0, 6)
} catch (error) {
console.error('获取排行榜数据失败:', error)

@ -51,7 +51,7 @@ onMounted(async () => {
const fetchMonthlyRank = async () => {
try {
const response = await store.dispatch('book/fetchMonthlyRank')
const response = await store.dispatch('fetchMonthlyRank')
rankList.value = response.data
} catch (error) {
console.error('获取本月热租榜失败:', error)

@ -50,7 +50,7 @@ onMounted(async () => {
const fetchWeeklyRank = async () => {
try {
const response = await store.dispatch('book/fetchWeeklyRank')
const response = await store.dispatch('fetchWeeklyRank')
rankList.value = response.data
} catch (error) {
console.error('获取本周热租榜失败:', error)

@ -46,7 +46,7 @@ onMounted(async () => {
const fetchRecords = async () => {
try {
const response = await store.dispatch('borrow/fetchBorrowRecords')
const response = await store.dispatch('fetchBorrowRecords')
records.value = response.data
} catch (error) {
console.error('获取借阅记录失败:', error)

@ -1,122 +0,0 @@
<template>
<div class="profile-container">
<el-card class="profile-card">
<div class="profile-header">
<el-avatar :src="user.pic" :size="100" class="avatar" />
<div class="user-info">
<h2>{{ user.username }}</h2>
<div class="vip-level">
<el-tag type="warning" size="large">VIP{{ vip }}</el-tag>
</div>
<div class="balance">
<el-text type="primary" size="large">
<el-icon><Wallet /></el-icon>
余额: {{ balance }}
</el-text>
</div>
</div>
</div>
<el-divider />
<div class="profile-details">
<el-descriptions title="个人信息" :column="2" border>
<el-descriptions-item label="用户名">{{ user.username }}</el-descriptions-item>
<el-descriptions-item label="账户类型">
<el-tag :type="isAdmin ? 'danger' : 'success'">
{{ isAdmin ? '管理员' : '普通用户' }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="注册时间">{{ formatDate(user.create_time) }}</el-descriptions-item>
<el-descriptions-item label="最后登录时间">{{ formatDate(user.update_time) }}</el-descriptions-item>
</el-descriptions>
</div>
<div class="profile-actions">
<el-button type="primary" @click="goToRecharge"></el-button>
<el-button @click="goToRecords"></el-button>
</div>
</el-card>
</div>
</template>
<script setup>
import { computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useStore } from 'vuex'
import { Wallet } from '@element-plus/icons-vue'
import { formatDate } from '@/utils/date'
const store = useStore()
const router = useRouter()
const user = computed(() => store.state.user || {})
const balance = computed(() => store.state.balance)
const vip = computed(() => store.state.vip)
const isAdmin = computed(() => store.getters.isAdmin)
onMounted(async () => {
try {
store.dispatch('fetchUser')
}catch (error) {
console.error('获取用户信息失败:', error)
ElMessage.error('获取用户信息失败,展示示例数据')
}
})
const goToRecharge = () => {
router.push('/recharge')
}
const goToRecords = () => {
router.push('/borrow-records')
}
</script>
<style scoped>
.profile-container {
max-width: 900px;
margin: 0 auto;
padding: 20px;
}
.profile-card {
padding: 30px;
}
.profile-header {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.avatar {
margin-right: 30px;
}
.user-info h2 {
margin: 0 0 10px;
font-size: 24px;
}
.vip-level {
margin-bottom: 10px;
}
.balance {
font-size: 18px;
}
.profile-details {
margin: 30px 0;
}
.profile-actions {
display: flex;
justify-content: center;
gap: 20px;
}
</style>

@ -67,7 +67,7 @@ const submitRecharge = async () => {
try {
await rechargeForm.value.validate()
await store.dispatch('user/recharge', { money: form.value.money })
await store.dispatch('recharge', { money: form.value.money })
ElMessage.success(`成功充值¥${form.value.money}`)
//

Loading…
Cancel
Save