<template>
|
|
<div class="book-detail-container">
|
|
<!-- 小说基本信息部分 -->
|
|
<div class="book-info-wrapper">
|
|
<div class="book-info">
|
|
<div class="book-cover">
|
|
<img :src="book.cover" :alt="book.title">
|
|
</div>
|
|
<div class="book-details">
|
|
<h1 class="book-title">{{ book.title }}</h1>
|
|
<div class="book-meta">
|
|
<div class="meta-item">
|
|
<span class="label">作者:</span>
|
|
<span class="value">{{ book.author }}</span>
|
|
</div>
|
|
<div class="meta-item book-status-row">
|
|
<span class="status-badge">{{ book.status }}</span>
|
|
<span class="dot">·</span>
|
|
<span class="reading-tip">大家都在读</span>
|
|
</div>
|
|
</div>
|
|
<div class="book-user-info">
|
|
<div class="user-badges">
|
|
<img class="level-icon" src="@/assets/images/book/level.png" alt="我的等级" />
|
|
<span class="badge-label">我的等级</span>
|
|
</div>
|
|
<div class="user-medal">
|
|
<img class="medal-icon" src="@/assets/images/image-1.png" alt="勋章" />
|
|
</div>
|
|
<div class="user-avatar-block">
|
|
<img class="user-avatar" src="@/assets/images/center/headImage.png" alt="用户头像" />
|
|
<span class="user-name">小巴</span>
|
|
<span class="dot">·</span>
|
|
<span class="user-title">VIP会员</span>
|
|
</div>
|
|
<span class="user-intimacy">1000 累计亲密值</span>
|
|
</div>
|
|
|
|
<div class="action-buttons">
|
|
<div class="action-btn-group">
|
|
<el-button class="reward-btn" plain @click="showRewardDialog">互动打赏</el-button>
|
|
</div>
|
|
<div class="action-btn-group">
|
|
<el-button
|
|
:class="['add-to-shelf-btn', isInShelf ? 'in-shelf' : '']"
|
|
:type="isInShelf ? '' : 'primary'"
|
|
@click="toggleShelf"
|
|
>{{ isInShelf ? '已加入书架' : '加入书架' }}</el-button>
|
|
</div>
|
|
<div class="action-btn-group">
|
|
<el-button class="read-btn"
|
|
@click="goToChapter(1)"
|
|
style="background:#0A2463;color:#fff;border:none;">点击阅读</el-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- 主体内容区域:左右分栏 -->
|
|
<div class="book-main-content">
|
|
<div class="main-left">
|
|
<!-- 推荐票/亲密值统计 -->
|
|
<BookStats :book-id="book.id" />
|
|
<!-- 小说介绍 -->
|
|
<BookIntro :book-data="book" />
|
|
<!-- 目录 -->
|
|
<BookCatalog :book-id="book.id" />
|
|
<!-- 评论 -->
|
|
<BookComments :book-id="book.id" />
|
|
</div>
|
|
<div class="main-right">
|
|
<!-- 读者亲密值榜单 -->
|
|
<IntimacyRanking :book-id="book.id" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- 互动打赏弹窗 -->
|
|
<InteractiveReward
|
|
v-model:visible="rewardDialogVisible"
|
|
:book-id="book.id"
|
|
@reward-success="handleRewardSuccess"
|
|
/>
|
|
</template>
|
|
|
|
<script>
|
|
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue';
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
import BookCard from '@/components/common/BookCard.vue';
|
|
import BookStats from '@/components/book/BookStats.vue';
|
|
import BookIntro from '@/components/book/BookIntro.vue';
|
|
import BookCatalog from '@/components/book/BookCatalog.vue';
|
|
import BookComments from '@/components/book/BookComments.vue';
|
|
import IntimacyRanking from '@/components/ranking/IntimacyRanking.vue';
|
|
import InteractiveReward from '@/components/book/InteractiveReward.vue';
|
|
|
|
export default {
|
|
name: 'BookDetail',
|
|
components: {
|
|
BookCard,
|
|
BookStats,
|
|
BookIntro,
|
|
BookCatalog,
|
|
BookComments,
|
|
IntimacyRanking,
|
|
InteractiveReward
|
|
},
|
|
setup() {
|
|
const route = useRoute();
|
|
const router = useRouter();
|
|
const bookId = route.params.id;
|
|
|
|
const book = reactive({
|
|
id: bookId,
|
|
title: '重生之财源滚滚',
|
|
author: '老鹰的沙',
|
|
category: '都市小说',
|
|
status: '已完结',
|
|
userGroup: '638781087(网友交流群)',
|
|
cover: 'https://bookcover.yuewen.com/qdbimg/349573/1041637443/150.webp',
|
|
description: `<p>当那一世——</p>
|
|
<p>贺季宁曾经是A市土豪公司的金牌经理,工资高福利好,女友漂亮车位靓,最重要的是老板信任他。但是贺季宁的对手不服,老板娘不喜欢他,不怀好意的对手们联合一起,终于把他拉下台了,他失去工作,更可悲的是,他连公司配他的贷款的房子都搭进去了,欠了几百万的债,女友也离他而去。</p>
|
|
<p>临终前,他喃喃自语:如果老天给我重来一次的机会,我一定要好好做人,赚很多钱,让那帮人看着我过得好就比他们难受!</p>`,
|
|
userGroup: '638781087(网友交流群)',
|
|
chapters: [
|
|
{ id: '1', title: '第一章 重回2004', isNew: false },
|
|
{ id: '2', title: '第二章 旧车旧房', isNew: false },
|
|
{ id: '3', title: '第三章 再拼一把', isNew: false },
|
|
{ id: '4', title: '第四章 带女朋友逛街', isNew: false },
|
|
{ id: '5', title: '第五章 小刺激', isNew: false },
|
|
{ id: '6', title: '第六章 老王的门道', isNew: false },
|
|
{ id: '7', title: '第七章 正中家门', isNew: false },
|
|
{ id: '8', title: '第八章 被逼迫的交易', isNew: false },
|
|
{ id: '9', title: '第九章 意外惊喜', isNew: false },
|
|
{ id: '10', title: '第十章 生意的桥梁', isNew: true },
|
|
{ id: '11', title: '第十一章 家族分崩离析', isNew: false },
|
|
{ id: '12', title: '第十二章 老张没来', isNew: false }
|
|
],
|
|
comments: [
|
|
{
|
|
username: '万年捧',
|
|
avatar: 'https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTKlR5PibUEEsVjXGfH4c1eR5hXDicoH0EJUTHYwDO3EvZLXXgON8GrNTbRg8DnzaddicibYnGcfq28tYg/132',
|
|
time: '2022-07-03',
|
|
content: '这是本年内看的唯一一部完结的!看的人真幸运,发家文和风险防控写的都是一流'
|
|
},
|
|
{
|
|
username: '残生往事',
|
|
avatar: 'https://thirdwx.qlogo.cn/mmopen/vi_32/3F4feeHnMyoGjqKfP8vGKCHwyvovMHiaO0Q1QkQMRTGibLcyJbUcUJ4LmdkkDqC5ZcqP1rvqKMviaYAyehqYb6ciaA/132',
|
|
content: '我很喜欢男主的性格,不小心眼,有格局,做事情多考虑下一步,商业和情感都处理得不错,就是那个林涵有点没必要吧?'
|
|
}
|
|
]
|
|
});
|
|
|
|
// 推荐书籍
|
|
const recommendedBooks = reactive([
|
|
{
|
|
id: '101',
|
|
title: '三体',
|
|
author: '刘慈欣',
|
|
cover: 'https://picsum.photos/120/160?random=1',
|
|
status: '已完结'
|
|
},
|
|
{
|
|
id: '102',
|
|
title: '活着',
|
|
author: '余华',
|
|
cover: 'https://picsum.photos/120/160?random=2',
|
|
status: '已完结'
|
|
},
|
|
{
|
|
id: '103',
|
|
title: '平凡的世界',
|
|
author: '路遥',
|
|
cover: 'https://picsum.photos/120/160?random=3',
|
|
status: '已完结'
|
|
},
|
|
{
|
|
id: '104',
|
|
title: '围城',
|
|
author: '钱钟书',
|
|
cover: 'https://picsum.photos/120/160?random=4',
|
|
status: '已完结'
|
|
}
|
|
]);
|
|
|
|
const activeTab = ref('intro');
|
|
const currentPage = ref(1);
|
|
const commentText = ref('');
|
|
const isInShelf = ref(false);
|
|
const rewardDialogVisible = ref(false);
|
|
|
|
const handlePageChange = (page) => {
|
|
currentPage.value = page;
|
|
// 实际应用中这里应该加载对应页的数据
|
|
};
|
|
|
|
// 创建一个清理函数
|
|
const cleanup = () => {
|
|
// 清理所有响应式数据
|
|
Object.keys(book).forEach(key => {
|
|
if (typeof book[key] === 'object') {
|
|
book[key] = null;
|
|
}
|
|
});
|
|
activeTab.value = 'intro';
|
|
currentPage.value = 1;
|
|
commentText.value = '';
|
|
isInShelf.value = false;
|
|
rewardDialogVisible.value = false;
|
|
};
|
|
|
|
// 在组件销毁前清理
|
|
onBeforeUnmount(() => {
|
|
cleanup();
|
|
});
|
|
|
|
// 修改路由导航方式
|
|
const goToChapter = (chapterId) => {
|
|
cleanup();
|
|
router.push({
|
|
name: 'ChapterDetail',
|
|
params: {
|
|
id: bookId,
|
|
chapterId: chapterId
|
|
}
|
|
});
|
|
};
|
|
|
|
const submitComment = () => {
|
|
if (!commentText.value.trim()) {
|
|
ElMessage.warning('请输入评论内容');
|
|
return;
|
|
}
|
|
|
|
// 实际应用中这里应该调用API提交评论
|
|
book.comments.unshift({
|
|
username: '当前用户',
|
|
avatar: 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png',
|
|
time: new Date().toLocaleString(),
|
|
content: commentText.value
|
|
});
|
|
|
|
commentText.value = '';
|
|
};
|
|
|
|
const toggleShelf = () => {
|
|
isInShelf.value = !isInShelf.value;
|
|
};
|
|
|
|
const showRewardDialog = () => {
|
|
rewardDialogVisible.value = true;
|
|
};
|
|
|
|
const handleRewardSuccess = (items) => {
|
|
console.log('打赏成功,打赏项目:', items);
|
|
// 这里可以添加刷新亲密值或其他相关数据的逻辑
|
|
};
|
|
|
|
onMounted(() => {
|
|
// 实际应用中这里应该根据bookId从API获取书籍详情
|
|
console.log('加载书籍详情,ID:', bookId);
|
|
});
|
|
|
|
return {
|
|
book,
|
|
recommendedBooks,
|
|
activeTab,
|
|
currentPage,
|
|
commentText,
|
|
handlePageChange,
|
|
goToChapter,
|
|
submitComment,
|
|
isInShelf,
|
|
toggleShelf,
|
|
rewardDialogVisible,
|
|
showRewardDialog,
|
|
handleRewardSuccess,
|
|
cleanup
|
|
};
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
@use '@/assets/styles/variables.scss' as vars;
|
|
|
|
.book-detail-container {
|
|
width: 100%;
|
|
background-color: #f5f5f5;
|
|
}
|
|
|
|
// 小说基本信息部分
|
|
.book-info-wrapper {
|
|
background-color: #fff;
|
|
padding: 30px 0;
|
|
border-bottom: 1px solid #eee;
|
|
|
|
.book-info {
|
|
display: flex;
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
padding: 0 20px;
|
|
|
|
.book-cover {
|
|
width: 165px;
|
|
height: 220px;
|
|
margin-right: 30px;
|
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
|
|
|
img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
border-radius: 6px;
|
|
}
|
|
}
|
|
|
|
.book-details {
|
|
flex: 1;
|
|
|
|
.book-title {
|
|
font-size: 24px;
|
|
font-weight: bold;
|
|
margin: 0 0 15px 0;
|
|
color: #333;
|
|
}
|
|
|
|
.book-meta {
|
|
margin-bottom: 8px;
|
|
.book-status-row {
|
|
display: flex;
|
|
align-items: center;
|
|
font-size: 15px;
|
|
margin-top: 10px;
|
|
.status-badge {
|
|
background: #eaffea;
|
|
color: #52c41a;
|
|
border-radius: 6px;
|
|
padding: 2px 12px;
|
|
font-size: 15px;
|
|
font-weight: 500;
|
|
margin-right: 8px;
|
|
}
|
|
.dot {
|
|
color: #d1d1d1;
|
|
margin: 0 8px;
|
|
font-size: 18px;
|
|
}
|
|
.reading-tip {
|
|
color: #bdbdbd;
|
|
font-size: 15px;
|
|
}
|
|
}
|
|
}
|
|
.book-user-info {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 18px;
|
|
.user-badges {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-right: 18px;
|
|
.level-icon {
|
|
width: 36px;
|
|
height: 36px;
|
|
}
|
|
.badge-label {
|
|
color: #b88a4a;
|
|
font-size: 14px;
|
|
margin-left: 4px;
|
|
}
|
|
}
|
|
.user-medal {
|
|
margin-right: 18px;
|
|
.medal-icon {
|
|
width: 44px;
|
|
height: 44px;
|
|
}
|
|
}
|
|
.user-avatar-block {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-right: 18px;
|
|
.user-avatar {
|
|
width: 36px;
|
|
height: 36px;
|
|
border-radius: 50%;
|
|
margin-right: 8px;
|
|
}
|
|
.user-name {
|
|
color: #222;
|
|
font-size: 16px;
|
|
font-weight: 500;
|
|
margin-right: 4px;
|
|
}
|
|
.dot {
|
|
color: #d1d1d1;
|
|
margin: 0 8px;
|
|
font-size: 18px;
|
|
}
|
|
.user-title {
|
|
background: #ede6ff;
|
|
color: #a97cff;
|
|
border-radius: 8px;
|
|
padding: 2px 10px;
|
|
font-size: 15px;
|
|
margin-left: 2px;
|
|
}
|
|
}
|
|
.user-intimacy {
|
|
color: #bdbdbd;
|
|
font-size: 15px;
|
|
}
|
|
}
|
|
|
|
.action-buttons {
|
|
display: flex;
|
|
gap: 24px;
|
|
margin-top: 10px;
|
|
.action-btn-group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
.el-button {
|
|
width: 140px;
|
|
height: 40px;
|
|
font-size: 16px;
|
|
border-radius: 4px;
|
|
margin: 0;
|
|
font-weight: 500;
|
|
}
|
|
.diamond-icon {
|
|
width: 28px;
|
|
height: 18px;
|
|
margin-top: 4px;
|
|
}
|
|
.reward-btn {
|
|
color: #0A2463;
|
|
border: 1.5px solid #0A2463;
|
|
background: #fff;
|
|
}
|
|
.add-to-shelf-btn {
|
|
background: #FF7C6A;
|
|
color: #fff;
|
|
border: none;
|
|
}
|
|
.add-to-shelf-btn.in-shelf {
|
|
background: #fff;
|
|
color: #FF7C6A;
|
|
border: 1.5px solid #FF7C6A;
|
|
}
|
|
.read-btn {
|
|
background: #0A2463;
|
|
color: #fff;
|
|
border: none;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.book-main-content {
|
|
display: flex;
|
|
gap: 3px;
|
|
margin-top: 20px;
|
|
.main-left {
|
|
flex: 1.8;
|
|
min-width: 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 3px;
|
|
}
|
|
.main-right {
|
|
flex: 1;
|
|
min-width: 220px;
|
|
max-width: 280px;
|
|
}
|
|
}
|
|
</style>
|