| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- <template>
- <view class="reading-container">
- <!-- 顶部章节信息 -->
- <view class="chapter-header">
- <text class="chapter-title">{{ chapter.title }}</text>
- </view>
-
- <!-- 小说内容 -->
- <scroll-view scroll-y class="content-container">
- <rich-text :nodes="chapter.content" class="content-text"></rich-text>
- </scroll-view>
-
- <!-- 底部操作栏 -->
- <view class="action-bar">
- <button @click="prevChapter">上一章</button>
- <button @click="showCatalog">目录</button>
- <button @click="nextChapter">下一章</button>
- </view>
-
- <!-- 章节间广告 -->
- <ad-banner v-if="showAd" :ads="midAds" />
- </view>
- </template>
-
- <script>
- import AdBanner from '@/components/AdBanner';
-
- export default {
- components: { AdBanner },
- data() {
- return {
- novelId: null,
- chapterId: null,
- chapter: {},
- chapters: [],
- showAd: false,
- midAds: []
- };
- },
- onLoad(options) {
- this.novelId = options.novelId;
- this.chapterId = options.chapterId;
- this.loadChapterData();
- this.scheduleAd();
- },
- methods: {
- async loadChapterData() {
- try {
- // 加载章节列表
- const chaptersRes = await this.$http.get(`/novel/${this.novelId}/chapters`);
- this.chapters = chaptersRes.data;
-
- // 加载当前章节内容
- await this.loadChapterContent(this.chapterId || this.chapters[0].id);
- } catch (e) {
- uni.showToast({ title: '加载失败', icon: 'none' });
- }
- },
- async loadChapterContent(chapterId) {
- const res = await this.$http.get(`/novel/chapter/${chapterId}`);
- this.chapter = res.data;
- this.chapterId = chapterId;
-
- // 保存阅读进度
- this.saveReadingProgress();
- },
- saveReadingProgress() {
- const progress = {
- novelId: this.novelId,
- chapterId: this.chapterId,
- timestamp: Date.now()
- };
- uni.setStorageSync('readingProgress', progress);
-
- // 同步到后台
- if (this.$store.getters.token) {
- this.$http.post('/user/reading-progress', progress);
- }
- },
- prevChapter() {
- const currentIndex = this.chapters.findIndex(c => c.id === this.chapterId);
- if (currentIndex > 0) {
- this.loadChapterContent(this.chapters[currentIndex - 1].id);
- }
- },
- nextChapter() {
- const currentIndex = this.chapters.findIndex(c => c.id === this.chapterId);
- if (currentIndex < this.chapters.length - 1) {
- this.loadChapterContent(this.chapters[currentIndex + 1].id);
- }
- },
- showCatalog() {
- uni.navigateTo({
- url: `/pages/novel/catalog?novelId=${this.novelId}`
- });
- },
- async scheduleAd() {
- // 30秒后显示广告
- setTimeout(async () => {
- const res = await this.$http.get('/ad/position?code=CHAPTER_MID');
- this.midAds = res.data;
- this.showAd = true;
-
- // 10秒后隐藏
- setTimeout(() => this.showAd = false, 10000);
- }, 30000);
- }
- }
- }
- </script>
-
- <style scoped>
- .reading-container {
- padding: 20rpx;
- padding-bottom: 120rpx; /* 为操作栏留空间 */
- }
-
- .chapter-header {
- padding: 20rpx 0;
- border-bottom: 1rpx solid #eee;
- }
-
- .chapter-title {
- font-size: 36rpx;
- font-weight: bold;
- }
-
- .content-container {
- height: calc(100vh - 300rpx);
- padding: 30rpx 0;
- }
-
- .content-text {
- font-size: 32rpx;
- line-height: 1.8;
- }
-
- .action-bar {
- position: fixed;
- bottom: 0;
- left: 0;
- right: 0;
- display: flex;
- background: white;
- padding: 20rpx;
- box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.1);
- z-index: 999;
- }
-
- .action-bar button {
- flex: 1;
- margin: 0 10rpx;
- font-size: 28rpx;
- }
- </style>
|