feat: 新增小说同类推荐

This commit is contained in:
xiongxiaoyang 2022-05-15 20:49:07 +08:00
parent 260c6827c0
commit 04ff469b3a
5 changed files with 139 additions and 161 deletions

View File

@ -8,6 +8,10 @@ export function getLastChapterAbout(params) {
return request.get('/book/lastChapterAbout', { params }); return request.get('/book/lastChapterAbout', { params });
} }
export function listRecBooks(params) {
return request.get('/book/recList', { params });
}
export function getBookContent(chapterId) { export function getBookContent(chapterId) {
return request.get(`/book/content/${chapterId}`); return request.get(`/book/content/${chapterId}`);
} }

View File

@ -1,64 +0,0 @@
<template>
<!--章节目录 start-->
<div class="pad20_nobt">
<div class="bookChapter">
<div class="book_tit">
<div class="fl">
<h3>最新章节</h3>
<span id="bookIndexCount">({{chapterAbout.chapterTotal}})</span>
</div>
<a class="fr" href="/book/indexList-1431636283466297344.html"
>全部目录</a
>
</div>
<ul class="list cf">
<li>
<span class="fl font16">
<a @click="bookContent(chapterAbout.chapterInfo.bookId,chapterAbout.chapterInfo.id)" href="javascript:void(0)" v-if="chapterAbout.chapterInfo"
>{{chapterAbout.chapterInfo.chapterName}}</a
></span
>
<span class="black9 fr" v-if="chapterAbout.chapterInfo">更新时间{{chapterAbout.chapterInfo.chapterUpdateTime}}</span>
</li>
<li class="zj_yl" id="lastBookContent">
<!--go-->
  <span v-html="`${chapterAbout.contentSummary}` + '...'"></span>
</li>
<!--此处是该章节预览截取最前面的42个字-->
</ul>
</div>
</div>
<!--章节目录 end-->
</template>
<script>
import { reactive, toRefs, onMounted } from "vue";
import { useRouter, useRoute } from "vue-router";
import { getLastChapterAbout } from "@/api/book";
export default {
name: "LastChapterAbout",
setup() {
const route = useRoute();
const router = useRouter();
const state = reactive({
chapterAbout: {},
imgBaseUrl: process.env.VUE_APP_BASE_IMG_URL,
});
const bookId = route.params.id;
onMounted(async () => {
const { data } = await getLastChapterAbout({ bookId: bookId });
state.chapterAbout = data;
});
const bookContent = (bookId, chapterId) => {
router.push({ path: `/book/${bookId}/${chapterId}` });
};
return {
...toRefs(state),
bookContent
};
},
};
</script>

View File

@ -35,4 +35,9 @@ const router = createRouter({
] ]
}) })
// 解决 vue 中路由跳转时,总是从新页面中间开始显示
router.afterEach((to,from,next) => {
window.scrollTo(0,0)
})
export default router export default router

View File

@ -4,34 +4,45 @@
<div class="nav_sub"> <div class="nav_sub">
<a href="/">小说精品屋</a>&gt;<a href="/book/bookclass.html?c=7">{{ <a href="/">小说精品屋</a>&gt;<a href="/book/bookclass.html?c=7">{{
book.categoryName book.categoryName
}}</a>&gt; <span>{{ book.bookName }}</span> }}</a
>&gt; <span>{{ book.bookName }}</span>
</div> </div>
<div class="channelWrap channelBookInfo cf"> <div class="channelWrap channelBookInfo cf">
<div class="bookCover cf"> <div class="bookCover cf">
<a class="book_cover"> <a class="book_cover">
<img <img
class="cover" class="cover"
:src="`${imgBaseUrl}` + `${book.picUrl}`" :src="`${imgBaseUrl}` + `${book.picUrl}`"
onerror="this.src='https://cdn.jsdelivr.net/gh/201206030/CDN/images/default.gif';this.onerror=null" onerror="this.src='https://cdn.jsdelivr.net/gh/201206030/CDN/images/default.gif';this.onerror=null"
:alt="book.bookName" :alt="book.bookName"
/></a> /></a>
<div class="book_info"> <div class="book_info">
<div class="tit"> <div class="tit">
<h1>{{book.bookName}}</h1> <h1>{{ book.bookName }}</h1>
<!--<i class="vip_b">VIP</i>--><a class="author">{{book.authorName}}</a> <!--<i class="vip_b">VIP</i>--><a class="author">{{
book.authorName
}}</a>
</div> </div>
<ul class="list"> <ul class="list">
<li> <li>
<span class="item">类别<em>{{book.categoryName}}</em></span> <span class="item"
<span class="item">状态<em>{{book.bookStatus == 0 ? '连载中' : '已完结'}}</em></span> >类别<em>{{ book.categoryName }}</em></span
<span class="item">总点击<em id="cTotal">{{book.visitCount}}</em></span> >
<span class="item">总字数<em>{{book.wordCount}}</em></span> <span class="item"
>状态<em>{{
book.bookStatus == 0 ? "连载中" : "已完结"
}}</em></span
>
<span class="item"
>总点击<em id="cTotal">{{ book.visitCount }}</em></span
>
<span class="item"
>总字数<em>{{ book.wordCount }}</em></span
>
</li> </li>
</ul> </ul>
<div class="intro_txt"> <div class="intro_txt">
<p v-html="book.bookDesc"> <p v-html="book.bookDesc"></p>
</p>
<a class="icon_hide" href="javascript:void(0)" onclick="" <a class="icon_hide" href="javascript:void(0)" onclick=""
><i></i>收起</a ><i></i>收起</a
> >
@ -40,9 +51,9 @@
> >
</div> </div>
<div class="btns" id="optBtn"> <div class="btns" id="optBtn">
<a
<a href="javascript:void(0)" @click="bookContent(book.id,book.firstChapterId)" href="javascript:void(0)"
@click="bookContent(book.id, book.firstChapterId)"
class="btn_ora" class="btn_ora"
>点击阅读</a >点击阅读</a
> >
@ -63,8 +74,52 @@
<!--left start--> <!--left start-->
<div class="wrap_left fl"> <div class="wrap_left fl">
<div class="wrap_bg"> <div class="wrap_bg">
<LastChapterAbout/> <!--章节目录 start-->
<div class="pad20_nobt">
<div class="bookChapter">
<div class="book_tit">
<div class="fl">
<h3>最新章节</h3>
<span id="bookIndexCount"
>({{ chapterAbout.chapterTotal }})</span
>
</div>
<a class="fr" href="/book/indexList-1431636283466297344.html"
>全部目录</a
>
</div>
<ul class="list cf">
<li>
<span class="fl font16">
<a
@click="
bookContent(
chapterAbout.chapterInfo.bookId,
chapterAbout.chapterInfo.id
)
"
href="javascript:void(0)"
v-if="chapterAbout.chapterInfo"
>{{ chapterAbout.chapterInfo.chapterName }}</a
></span
>
<span class="black9 fr" v-if="chapterAbout.chapterInfo"
>更新时间{{
chapterAbout.chapterInfo.chapterUpdateTime
}}</span
>
</li>
<li class="zj_yl" id="lastBookContent">
<!--go-->
  <span
v-html="`${chapterAbout.contentSummary}` + '...'"
></span>
</li>
<!--此处是该章节预览截取最前面的42个字-->
</ul>
</div>
</div>
<!--章节目录 end-->
<!--作品评论区 start--> <!--作品评论区 start-->
<div class="pad20"> <div class="pad20">
@ -74,7 +129,7 @@
<h3>作品评论区</h3> <h3>作品评论区</h3>
<span id="bookCommentTotal">(0)</span> <span id="bookCommentTotal">(0)</span>
</div> </div>
<a class="fr" href="#txtComment">发表评论</a> <!-- <a class="fr" href="#txtComment">发表评论</a> -->
</div> </div>
<div class="no_comment" id="noCommentPanel"> <div class="no_comment" id="noCommentPanel">
<img :src="no_comment" alt="" /> <img :src="no_comment" alt="" />
@ -93,16 +148,19 @@
> >
</div> </div>
<!--
<div class="reply_bar" id="reply_bar"> <div class="reply_bar" id="reply_bar">
<div class="tit"> <div class="tit">
<span class="fl font16">发表评论</span> <span class="fl font16">发表评论</span>
<!--未登录状态下不可发表评论显示以下链接-->
<span class="fr black9" style="display: none" <span class="fr black9" style="display: none"
>请先 <a class="orange" href="/user/login.html">登录</a >请先 <a class="orange" href="/user/login.html">登录</a
><em class="ml10 mr10">|</em ><em class="ml10 mr10">|</em
><a class="orange" href="/user/register.html">注册</a></span ><a class="orange" href="/user/register.html">注册</a></span
> >
</div> </div>
<textarea <textarea
name="txtComment" name="txtComment"
rows="2" rows="2"
@ -124,7 +182,9 @@
></span ></span
> >
</div> </div>
</div> </div>
-->
</div> </div>
</div> </div>
<!--作品评论区 end--> <!--作品评论区 end-->
@ -143,7 +203,9 @@
<div class="msg"> <div class="msg">
<span class="icon_qyzz">签约作家</span> <span class="icon_qyzz">签约作家</span>
<h4> <h4>
<a href="javascript:searchByK('冷漠的天蝎')">冷漠的天蝎</a> <a href="javascript:searchByK('冷漠的天蝎')">{{
book.authorName
}}</a>
</h4> </h4>
</div> </div>
</div> </div>
@ -161,75 +223,26 @@
</div> </div>
<div class="tj_bar"> <div class="tj_bar">
<ul id="recBookList"> <ul id="recBookList">
<li> <li v-for="(item, index) in books" :key="index">
<div class="book_intro"> <div class="book_intro">
<div class="cover"> <div class="cover">
<a href="/book/1338066517509591040.html" <a href="javascript:void(0)" @click="bookDetail(item.id)"
><img ><img
src="/localPic/2020/12/13/04f7e86f8a964705b9d0149c5aaf773f.jpg" :src="`${imgBaseUrl}` + `${item.picUrl}`"
alt="庆荣华" :alt="item.bookName"
onerror="this.src='https://cdn.jsdelivr.net/gh/201206030/CDN/images/default.gif';this.onerror=null"
/></a> /></a>
</div> </div>
<div class="dec"> <div class="dec">
<a class="book_name" href="/book/1338066517509591040.html" <a href="javascript:void(0)" @click="bookDetail(item.id)">{{
>庆荣华</a item.bookName
> }}</a>
<a class="txt" href="/book/1338066517509591040.html" <a
>  睁开眼后和姐姐互换了身体的曾华心里只有两件事报仇和报恩可报着报着她却渐渐迷失了自己</a class="txt"
> href="javascript:void(0)"
</div> @click="bookDetail(item.id)"
</div> v-html="item.bookDesc"
</li> ></a>
<li>
<div class="book_intro">
<div class="cover">
<a href="/book/1337999139673264128.html"
><img
src="/localPic/2020/12/13/430277d60be6492c9580cbcbfa8332c7.jpg"
alt="戏精娘子总想毒死我"
/></a>
</div>
<div class="dec">
<a class="book_name" href="/book/1337999139673264128.html"
>戏精娘子总想毒死我</a
>
<a class="txt" href="/book/1337999139673264128.html"
>  上辈子抢个压寨夫君助他得天下坐龙庭本想白头到老举案齐眉渣男却朝她举起了刀再世为人夏文锦防火防盗防美男誓要活出个别样人生夏家老爹愁白了头女儿戏精贪财嘴毒无赖不要脸整个南夏无人能及这以后怎么嫁得出去后来夏文锦拐走了南夏最俊的皇孙每天在京城大街招摇过市南夏众臣见识了她的粗鲁不要脸在被怼得怀疑人生后一致觉得她玷污了他们殿下这朵高岭之花每日奏请废黜直到敌国来袭太子亲征太子妃跟去了一出口怼退百万雄师</a
>
</div>
</div>
</li>
<li>
<div class="book_intro">
<div class="cover">
<a href="/book/1357673757073805312.html"
><img src="/images/default.gif" alt="锦衣春"
/></a>
</div>
<div class="dec">
<a class="book_name" href="/book/1357673757073805312.html"
>锦衣春</a
>
<a class="txt" href="/book/1357673757073805312.html"
>  韩绮只不过是不想卫武再入岐途一心想导他向善凭他的聪明不入奸党也能做个富甲一方大富豪只一不小心用力过猛把自己搭进去不说还让夫君与奸党成了死敌这下子可如何是好让夫君抱条大粗腿如何</a
>
</div>
</div>
</li>
<li>
<div class="book_intro">
<div class="cover">
<a href="/book/1357666748404404224.html"
><img src="/images/default.gif" alt="太子有点冷"
/></a>
</div>
<div class="dec">
<a class="book_name" href="/book/1357666748404404224.html"
>太子有点冷</a
>
<a class="txt" href="/book/1357666748404404224.html"
>  一个在宗门里修炼得高深武功习得卓绝剑法的人人称道大弟子被师妹抛弃他回家当太子才上位不久各种刀光剑影明枪暗箭纷沓而来都怕他太闲似的恨不得把他扎成只刺猬然后将人拖下宝座然而他不动声色解决掉一干人等这简直比坐上的皇帝还要威风所以被师妹抛弃怎么办回家当太子然后呢她来给你当太监之后呢宠她上天</a
>
</div> </div>
</div> </div>
</li> </li>
@ -248,11 +261,9 @@
import "@/assets/styles/book.css"; import "@/assets/styles/book.css";
import { reactive, toRefs, onMounted } from "vue"; import { reactive, toRefs, onMounted } from "vue";
import { useRouter, useRoute } from "vue-router"; import { useRouter, useRoute } from "vue-router";
import { getBookById } from "@/api/book"; import { getBookById,getLastChapterAbout,listRecBooks } from "@/api/book";
import { ElMessage, ElLoading } from "element-plus";
import Header from "@/components/common/Header"; import Header from "@/components/common/Header";
import Footer from "@/components/common/Footer"; import Footer from "@/components/common/Footer";
import LastChapterAbout from "@/components/book/LastChapterAbout.vue"
import author_head from "@/assets/images/author_head.png"; import author_head from "@/assets/images/author_head.png";
import no_comment from "@/assets/images/no_comment.png"; import no_comment from "@/assets/images/no_comment.png";
export default { export default {
@ -260,7 +271,6 @@ export default {
components: { components: {
Header, Header,
Footer, Footer,
LastChapterAbout
}, },
setup() { setup() {
const route = useRoute(); const route = useRoute();
@ -268,23 +278,49 @@ export default {
const state = reactive({ const state = reactive({
book: {}, book: {},
books: {},
chapterAbout:{},
imgBaseUrl: process.env.VUE_APP_BASE_IMG_URL, imgBaseUrl: process.env.VUE_APP_BASE_IMG_URL,
}); });
const bookId = route.params.id; onMounted(() => {
onMounted(async () => { const bookId = route.params.id;
const { data } = await getBookById(bookId) loadBook(bookId)
state.book = data loadRecBooks(bookId)
loadLastChapterAbout(bookId)
}); });
const bookContent = (bookId,chapterId) => { const loadBook = async (bookId) => {
const { data } = await getBookById(bookId);
state.book = data;
};
const loadRecBooks = async (bookId) => {
const { data } = await listRecBooks({ bookId: bookId });
state.books = data;
};
const loadLastChapterAbout = async (bookId) => {
const { data } = await getLastChapterAbout({ bookId: bookId });
state.chapterAbout = data;
}
const bookContent = (bookId, chapterId) => {
router.push({ path: `/book/${bookId}/${chapterId}` }); router.push({ path: `/book/${bookId}/${chapterId}` });
}; };
const bookDetail = (bookId) => {
router.push({ path: `/book/${bookId}` });
loadBook(bookId)
loadRecBooks(bookId)
loadLastChapterAbout(bookId)
};
return { return {
...toRefs(state), ...toRefs(state),
author_head, author_head,
no_comment, no_comment,
bookContent bookContent,
bookDetail,
}; };
}, },
mounted() { mounted() {

View File

@ -249,11 +249,8 @@ import "@/assets/styles/read.css"
import { reactive, toRefs, onMounted } from "vue"; import { reactive, toRefs, onMounted } from "vue";
import { useRouter, useRoute } from "vue-router"; import { useRouter, useRoute } from "vue-router";
import {getBookContent } from "@/api/book"; import {getBookContent } from "@/api/book";
import { ElMessage, ElLoading } from "element-plus";
import Top from "@/components/common/Top"; import Top from "@/components/common/Top";
import Footer from "@/components/common/Footer"; import Footer from "@/components/common/Footer";
import author_head from "@/assets/images/author_head.png";
import no_comment from "@/assets/images/no_comment.png";
export default { export default {
name: "bookContent", name: "bookContent",
components: { components: {