- <template>
- <!-- 小说详情页面 -->
- <view class="novel-detail">
- <navbar title="小说详情" leftClick @leftClick="$utils.navigateBack" />
-
- <!-- 小说基本信息 -->
- <view class="novel-info">
- <view class="novel-cover">
- <image :src="novelData.image &&
- novelData.image.split(',')[0]" mode="aspectFill"></image>
- </view>
- <view class="novel-basic">
- <text class="title">{{ novelData.name }}</text>
- <view class="author-line">
- <text class="label">作者:</text>
- <text class="author">{{ novelData.author }}</text>
- </view>
- <!-- <view class="status-line">
- <text class="label">完结:</text>
- <text class="status">{{ novelData.status }}</text>
- </view> -->
-
- <view class="content-row">
- <view class="book-status">
- <text>{{novelData.status}}</text>
- </view>
- <view class="book-text">
- {{ novelData.service }}
- </view>
- </view>
-
- <view class="score-line">
- <text class="score">{{ novelData.qmNum || 0}}</text>
- <text class="score-label">作者累计亲密度值</text>
- </view>
- </view>
- </view>
-
- <!-- 推荐票数显示 -->
- <view class="recommendation-section">
- <view class="rec-left">
- <text class="rec-count">{{ novelData.tuiNum || 0 }}</text>
- <text class="rec-label">推荐票数</text>
- </view>
- <view class="rec-divider"></view>
- <view class="rec-right">
- <button class="recommend-btn" @click="$refs.novelVotePopup.open(id)">
- <text class="btn-icon">📑</text>
- 投推荐票
- </button>
- </view>
- </view>
-
- <!-- 阅读和收藏按钮 -->
-
-
- <!-- 我的等级 -->
- <view class="user-level">
- <view class="level-left">
- <view class="level-title">
- <!-- <text class="title-icon">👑</text> -->
-
- <image style="width: 30rpx;height: 30rpx;" src="/pages_order/static/book/level.png"
- mode="aspectFill"></image>
-
- <text>我的等级</text>
- </view>
- <view class="level-info">
- <image class="user-avatar" src="/pages_order/static/book/dj.png" mode="aspectFill"></image>
-
- <view class="user-details">
- <text class="username">
- <image
- src="https://tse4-mm.cn.bing.net/th/id/OIP-C.iUyxJ_fxLjjX3kEBjteXWwAAAA?rs=1&pid=ImgDetMain"
- mode="aspectFill"></image>
-
- <view class="name">
- 周海
- </view>
-
- </text>
- <view class="user-score">
- <text class="score-value">6785452</text>
- <text class="score-label">亲密值</text>
- </view>
- <text class="user-role">护书使者 五级</text>
- </view>
- </view>
- </view>
- <view class="level-right">
- <view class="rank-btn" @click="toggleInteractive">
- <image class="rank-icon" src="/pages_order/static/book/bd.png" mode="aspectFit"></image>
- <text class="check-text">点击查看</text>
- </view>
- </view>
- </view>
-
- <!-- 小说简介 -->
- <view class="novel-intro">
- <view class="intro-title">
- <text>简介:</text>
- </view>
- <view class="intro-content">
- {{ novelData.details }}
- </view>
- </view>
-
- <!-- 目录 -->
- <view class="novel-catalog" @click="$refs.chapterPopup.open()">
- <view class="catalog-header">
- <view class="catalog-title">
- <text class="title-icon">📖</text>
- <text>目录</text>
- </view>
- <view class="chapter-nav">
- <text class="current-chapter">
- {{ catalog ? catalog.title : '暂无章节' }}
- </text>
- <text class="nav-arrow">></text>
- </view>
- </view>
- </view>
-
-
- <!-- 书评区域 -->
- <view class="comments-section">
- <view class="comments-header">
- <view class="header-left">
- <text class="title-icon">📝</text>
- <text>书评</text>
- </view>
- <view class="header-right">
- <text @click="goToWriteReview">写书评</text>
- </view>
- </view>
- <view class="comment-list">
- <commentItem v-for="(item, index) in list" :item="item" :key="index" />
- <uv-empty mode="list" v-if="list.length == 0"></uv-empty>
- </view>
- </view>
-
- <!-- 底部操作栏 -->
- <view class="novel-bottom">
- <view class="bottom-left">
- <view class="action-btn" @click="addToBookshelf">
- <view class="btn-icon">
- <uv-icon name="grid" color="#999" size="60rpx"></uv-icon>
- </view>
- <text>加入书架</text>
- </view>
- <!-- <view class="action-btn" @click="goToGiftbox">
- <text class="btn-icon">🎁</text>
- <text>礼物盒</text>
- </view> -->
- <view class="action-btn" @click="$utils.navigateTo(`/pages_order/novel/Giftbox?id=${novelData.id}`)">
- <view class="btn-icon">
- <uv-icon name="gift" color="#999" size="60rpx"></uv-icon>
- </view>
- <text>互动打赏</text>
- </view>
- </view>
- <view class="bottom-right">
- <button class="read-now-btn" @click="toRead">立即阅读</button>
- </view>
- </view>
-
- <novelVotePopup ref="novelVotePopup" @updateVote="updateVote"/>
-
- <chapterPopup ref="chapterPopup" :bookId="id" :chapterList="chapterList" @selectChapter="selectChapter"/>
- </view>
- </template>
-
- <script>
- import catalogpopup from '@/components/novel/CatalogPopup.vue'
- import chapterPopup from '../components/novel/chapterPopup.vue'
- import commentItem from '../components/comment/commentItem.vue'
- import novelVotePopup from '../components/novel/novelVotePopup.vue'
- import mixinsList from '@/mixins/list.js'
- export default {
- mixins: [mixinsList],
- components: {
- catalogpopup,
- chapterPopup,
- commentItem,
- novelVotePopup,
- },
- data() {
- return {
- novelData: {},
- isCollected: false,
- comments: [],
- currentIndex: 0,
- id: 0,
- bookLevel: {},
- mixinsListApi: 'getBookCommentList',
- catalog: {}, //最后一个章节
- fastCatalog: {}, //第一章节
- chapterList : [],//章节列表
- }
- },
- computed: {},
- onLoad({
- id
- }) {
- this.id = id
- this.queryParams.bookId = id
- },
- onShow() {
- this.getDateil()
- this.getBookCatalogList()
- if(this.isLogin){
- this.getAchievement()
- }
- },
- methods: {
- updateVote() {
- this.getDateil()
- this.getAchievement()
- },
- getDateil() {
- let data = {
- id: this.id
- }
- if(uni.getStorageSync('data')){
- data.token = uni.getStorageSync('token')
- }
- this.$fetch('getBookDetail', data).then(res => {
- this.novelData = res
- })
- },
- getAchievement() {
- this.$fetch('getAchievement', {
- id: this.id
- }).then(res => {
- this.bookLevel = res
- })
- },
- getBookCatalogList() {
-
- this.$fetch('getBookCatalogList', {
- bookId : this.id,
- pageNo : 1,
- pageSize : 9999999,
- reverse : 0,
- }).then(res => {
- this.chapterList = res.records
- this.catalog = res.records[res.records.length - 1]
- this.fastCatalog = res.records[0]
- })
-
- // 获取最后章节
- // this.$fetch('getBookCatalogList', {
- // bookId: this.id,
- // pageNo: 1,
- // pageSize: 1,
- // reverse: 1,
- // }).then(res => {
- // this.catalog = res.records[0]
- // })
-
- // // 获取第一章节
- // this.$fetch('getBookCatalogList', {
- // bookId: this.id,
- // pageNo: 1,
- // pageSize: 1,
- // reverse: 0,
- // }).then(res => {
- // this.fastCatalog = res.records[0]
- // })
- },
- toggleCollect() {
- this.isCollected = !this.isCollected
- },
- goToWriteReview() {
- uni.navigateTo({
- url: `/pages_order/comment/review?id=${this.id}`
- })
- },
- addToBookshelf() {
- this.$fetch('addReadBook', {
- shopId: this.id,
- name: this.novelData.name,
- image: this.novelData.image,
- }).then(res => {
- uni.showToast({
- title: '已加入书架',
- icon: 'success'
- })
- })
- },
- toggleInteractive() {
- uni.navigateTo({
- url: `/pages_order/novel/Tipping?id=${this.id}`
- })
- },
- goToGiftbox() {
- uni.navigateTo({
- url: `/pages_order/novel/Giftbox?id=${this.id}`
- })
- },
- toRead() {
- if (!this.fastCatalog) {
- uni.showToast({
- title: '暂无章节',
- icon: 'none'
- })
- return
- }
-
- uni.navigateTo({
- url: `/pages_order/novel/readnovels?cid=${this.fastCatalog.id}&id=${this.id}`
- })
- },
- selectChapter({item, index}){
- uni.navigateTo({
- url: `/pages_order/novel/readnovels?cid=${item.id}&id=${this.id}`
- })
- },
- }
- }
- </script>
-
- <style lang="scss" scoped>
- .novel-detail {
- min-height: 100vh;
- background-color: #f5f5f5;
- padding-bottom: calc(env(safe-area-inset-bottom) + 30rpx);
-
- .nav-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 20rpx 30rpx;
- background-color: transparent;
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- z-index: 100;
- }
-
- .novel-info {
- padding: 20rpx;
- display: flex;
- background: #fff;
-
- .novel-cover {
- width: 200rpx;
- height: 280rpx;
- margin-right: 20rpx;
-
- image {
- width: 100%;
- height: 100%;
- border-radius: 8rpx;
- }
- }
-
- .novel-basic {
- flex: 1;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
-
- .title {
- font-size: 36rpx;
- font-weight: bold;
- margin-bottom: 16rpx;
- }
-
- .author-line,
- .status-line {
- display: flex;
- align-items: center;
- margin-bottom: 12rpx;
- font-size: 28rpx;
- color: #666;
- }
-
- .content-row {
- display: flex;
- align-items: center;
- margin-bottom: 10rpx;
-
- .book-status {
- flex-shrink: 0;
-
- text {
- font-size: 20rpx;
- color: #67C23A;
- background-color: rgba(103, 194, 58, 0.1);
- border-radius: 20rpx;
- padding: 4rpx 12rpx;
- }
- }
-
- .book-text {
- font-size: 20rpx;
- }
- }
-
- .label {
- color: #999;
- margin-right: 8rpx;
- }
-
- .score-line {
- margin-top: 16rpx;
-
- .score {
- font-size: 32rpx;
- color: #333;
- font-weight: bold;
- }
-
- .score-label {
- font-size: 24rpx;
- color: #999;
- margin-left: 8rpx;
- }
- }
- }
- }
-
- .recommendation-section {
- padding: 24rpx 32rpx;
- background: #fff;
- display: flex;
- justify-content: space-between;
- align-items: center;
- position: relative;
-
- .rec-left {
- display: flex;
- flex-direction: column;
- align-items: flex-start;
- margin-left: 70rpx;
-
- .rec-count {
- font-size: 44rpx;
- font-weight: 500;
- color: #333;
- line-height: 1.2;
- }
-
- .rec-label {
- font-size: 26rpx;
- color: #999;
- margin-top: 4rpx;
- }
- }
-
- .rec-divider {
- position: absolute;
- right: 160rpx;
- top: 20rpx;
- bottom: 20rpx;
- width: 2rpx;
- background: #eee;
- }
-
- .rec-right {
- flex-shrink: 0;
-
- .recommend-btn {
- background: #fff;
- color: #4a90e2;
- border: 2rpx solid #4a90e2;
- border-radius: 40rpx;
- padding: 12rpx 32rpx;
- font-size: 28rpx;
- display: flex;
- align-items: center;
- line-height: 1;
- height: 64rpx;
-
- .btn-icon {
- margin-right: 8rpx;
- font-size: 32rpx;
- }
- }
- }
- }
-
- .action-buttons {
- display: flex;
- padding: 30rpx;
- gap: 20rpx;
-
- button {
- flex: 1;
- height: 80rpx;
- border-radius: 40rpx;
- font-size: 32rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- }
-
- .read-btn {
- background-color: #4a90e2;
- color: #fff;
- }
-
- .collect-btn {
- background-color: #f0f0f0;
- color: #666;
- }
- }
-
- .user-level {
- margin: 20rpx 30rpx;
- background-color: #fff;
- border-radius: 12rpx;
- padding: 24rpx 32rpx;
- display: flex;
- justify-content: space-between;
- align-items: stretch;
-
- .level-left {
- flex: 1;
-
- .level-title {
- display: flex;
- align-items: center;
- gap: 8rpx;
- margin-bottom: 20rpx;
- margin-left: 20rpx;
-
- .title-icon {
- font-size: 36rpx;
- color: #FFB800;
- }
-
- text {
- font-size: 32rpx;
- font-weight: 500;
- color: #333;
- }
- }
-
- .level-info {
- display: flex;
- align-items: flex-start;
- gap: 20rpx;
-
- .user-avatar {
- width: 80rpx;
- height: 80rpx;
- border-radius: 50%;
- border: 2rpx solid #f0f0f0;
- }
-
- .user-details {
- display: flex;
- flex-direction: column;
- gap: 8rpx;
-
- .username {
- display: flex;
- font-size: 28rpx;
- color: #333;
- font-weight: 500;
-
- image {
- width: 60rpx;
- height: 60rpx;
- }
- }
-
- .user-score {
- display: flex;
- align-items: center;
- gap: 8rpx;
-
- .score-value {
- font-size: 28rpx;
- color: #333;
- }
-
- .score-label {
- font-size: 24rpx;
- color: #999;
- }
- }
-
- .user-role {
- font-size: 24rpx;
- color: #666;
- background: #f5f5f5;
- padding: 4rpx 12rpx;
- border-radius: 4rpx;
- display: inline-block;
- }
- }
- }
- }
-
- .level-right {
- display: flex;
- align-items: center;
-
- .rank-btn {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- padding: 0 20rpx;
-
- .rank-icon {
- width: 200rpx;
- height: 60rpx;
- margin-bottom: 8rpx;
- }
-
- text {
- font-size: 26rpx;
- color: #333;
- line-height: 1.4;
- }
-
- .check-text {
- font-size: 22rpx;
- color: #999;
- }
- }
- }
- }
-
- .novel-intro {
- margin: 20rpx 30rpx;
- background-color: #fff;
- border-radius: 12rpx;
- padding: 24rpx;
-
- .intro-title {
- font-size: 32rpx;
- font-weight: 500;
- color: #333;
- margin-bottom: 16rpx;
- }
-
- .intro-content {
- font-size: 28rpx;
- color: #666;
- line-height: 1.6;
- display: flex;
- flex-direction: column;
- gap: 16rpx;
-
- text {
- display: block;
- }
- }
- }
-
- .comments-section {
- margin: 20rpx 30rpx;
- background-color: #fff;
- border-radius: 12rpx;
- padding: 24rpx;
-
- .comments-header {
- display: flex;
- align-items: center;
- margin-bottom: 24rpx;
- border-bottom: 2rpx solid #f5f5f5;
- padding-bottom: 24rpx;
- justify-content: flex-start;
-
- .header-left {
- display: flex;
- align-items: center;
- gap: 8rpx;
-
- .title-icon {
- font-size: 32rpx;
- }
-
- text {
- display: flex;
- align-items: center;
- font-size: 32rpx;
- font-weight: 500;
- color: #333;
- white-space: nowrap;
- }
- }
-
- .header-right {
- margin-left: auto;
- }
- }
-
- .comment-list {
- display: flex;
- flex-direction: column;
- gap: 32rpx;
- }
-
- .like-icon {
- font-size: 24rpx;
- color: #999;
- }
-
- .like-count {
- font-size: 24rpx;
- color: #999;
- }
- }
-
- .novel-catalog {
- margin: 20rpx 30rpx;
- background-color: #fff;
- border-radius: 12rpx;
- padding: 24rpx;
-
- .catalog-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- border-bottom: 2rpx solid #f5f5f5;
-
- .catalog-title {
- display: flex;
- align-items: center;
- gap: 8rpx;
-
- .title-icon {
- font-size: 32rpx;
- }
-
- text {
- font-size: 32rpx;
- font-weight: 500;
- color: #333;
- }
- }
-
- .chapter-nav {
- display: flex;
- align-items: center;
- gap: 8rpx;
-
- .current-chapter {
- font-size: 28rpx;
- color: #666;
- }
-
- .nav-arrow {
- font-size: 28rpx;
- color: #999;
- }
- }
- }
- }
-
- .novel-bottom {
- position: fixed;
- bottom: 0;
- left: 0;
- right: 0;
- height: 100rpx;
- background: #fff;
- display: flex;
- align-items: center;
- padding: 0 30rpx;
- padding-top: 15rpx;
- padding-bottom: env(safe-area-inset-bottom);
- box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
- gap: 40rpx;
-
- .bottom-left {
- display: flex;
- gap: 40rpx;
-
- .action-btn {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 4rpx;
-
- .btn-icon {
- font-size: 40rpx;
- line-height: 1;
- }
-
- text {
- font-size: 24rpx;
- color: #666;
- }
- }
- }
-
- .bottom-right {
- flex: 1;
- display: flex;
-
- .read-now-btn {
- flex: 1;
- background: #1a237e;
- color: #fff;
- font-size: 32rpx;
- height: 80rpx;
- line-height: 80rpx;
- padding: 0 60rpx;
- border-radius: 40rpx;
- border: none;
- }
- }
- }
- }
- </style>
|