You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pyx_gitkeshe/library_system/src/views/Books/BookDetail.vue

189 lines
4.3 KiB

<template>
<div class="book-detail-container" v-if="book">
<el-card class="book-card">
<div class="book-header">
<el-image :src="book.url" class="cover-large" fit="cover" />
<div class="book-info">
<h1 class="title">{{ book.title }}</h1>
<div class="meta">
<!-- <el-tag type="info" size="large">{{ book.content }}</el-tag> -->
<el-tag type="success" size="large">{{ book.money }}/</el-tag>
</div>
<div class="status">
<el-tag :type="book.state === '正常' ? 'success' : 'danger'" size="large">
{{ book.state }}
</el-tag>
<span>阅读量: {{ book.number }}</span>
</div>
<div class="actions">
<el-button
type="primary"
size="large"
:disabled="book.state !== '正常'"
@click="borrowBook"
v-if="!isAdmin">
</el-button>
<el-button
type="danger"
size="large"
@click="deleteBook"
v-if="isAdmin">
</el-button>
</div>
</div>
</div>
<el-divider />
<div class="book-description">
<h3>书籍简介</h3>
<p>{{ book.content || '暂无简介' }}</p>
</div>
</el-card>
</div>
<el-empty v-else description="书籍不存在" />
</template>
<script setup>
import { ref, onMounted, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useStore } from 'vuex'
import { ElMessage, ElMessageBox } from 'element-plus'
const route = useRoute()
const router = useRouter()
const store = useStore()
const book = ref(null)
const loading = ref(true)
const isAdmin = computed(() => store.getters.isAdmin)
onMounted(async () => {
await fetchBook()
})
const fetchBook = async () => {
try {
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(error.message || '获取书籍详情失败')
// 使用有意义的预设数据
book.value = {
title: route.params.title,
url: 'https://picsum.photos/id/24/300/400',
money: 5.00,
number: 8,
content: `无法获取《${route.params.title}》的详细信息`,
state: '维护中',
}
} finally {
loading.value = false
}
}
const borrowBook = async () => {
try {
await store.dispatch('borrowBook', { title: book.value.title })
ElMessage.success(`成功借阅《${book.value.title}`)
// 刷新书籍信息
await fetchBook()
} catch (error) {
console.error('借阅失败:', error)
ElMessage.error(error.message || '借阅失败')
}
}
const deleteBook = async () => {
try {
await ElMessageBox.confirm(
`确定要删除《${book.value.title}》吗?此操作不可恢复。`,
'删除确认',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
)
await store.dispatch('deleteBook', { title: book.value.title })
ElMessage.success('书籍已删除')
router.push('/books')
} catch (error) {
if (error !== 'cancel') {
console.error('删除失败:', error)
ElMessage.error('删除失败')
}
}
}
</script>
<style scoped>
.book-detail-container {
max-width: 1000px;
margin: 0 auto;
padding: 20px;
}
.book-header {
display: flex;
gap: 40px;
}
.cover-large {
width: 300px;
height: 400px;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.book-info {
flex: 1;
}
.title {
margin-top: 0;
font-size: 28px;
}
.meta {
display: flex;
gap: 10px;
margin: 20px 0;
}
.status {
display: flex;
align-items: center;
gap: 15px;
font-size: 18px;
margin: 30px 0;
}
.actions {
margin-top: 40px;
}
.book-description {
margin-top: 30px;
}
</style>