├── php-api/ # 改造后的PHP接口层 ├── java-ad-service/ # 若依框架微服务(广告+VIP+分账) ├── uniapp-reader/ # UniApp前端项目 │ ├── pages/ # 各端页面 │ └──
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

detail.vue 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <template>
  2. <view>
  3. <!-- 章节间广告 -->
  4. <ad-banner v-if="showMidAd" :ads="midAds" />
  5. <scroll-view scroll-y>
  6. <!-- 章节内容 -->
  7. <view v-for="chapter in chapters" :key="chapter.id">
  8. <text>{{ chapter.title }}</text>
  9. <rich-text :nodes="chapter.content" />
  10. </view>
  11. <!-- 章节底部广告 -->
  12. <ad-banner :ads="chapterAds" />
  13. </scroll-view>
  14. <!-- 底部操作栏 -->
  15. <view class="action-bar">
  16. <button @click="prevChapter">上一章</button>
  17. <button @click="showCatalog">目录</button>
  18. <button @click="nextChapter">下一章</button>
  19. </view>
  20. </view>
  21. </template>
  22. <script>
  23. import AdBanner from '@/components/AdBanner';
  24. export default {
  25. components: { AdBanner },
  26. data() {
  27. return {
  28. novel: {},
  29. chapters: [],
  30. currentChapter: 0,
  31. // 确保数组初始化
  32. midAds: [],
  33. chapterAds: [],
  34. showMidAd: false
  35. };
  36. },
  37. onLoad(options) {
  38. this.novelId = options.id;
  39. this.loadNovelData();
  40. this.scheduleMidAd();
  41. },
  42. methods: {
  43. async loadNovelData() {
  44. // 加载小说详情
  45. const novelRes = await this.$http.get(`/novel/detail/${this.novelId}`);
  46. if (novelRes.data) {
  47. this.novel = novelRes.data;
  48. }
  49. // 加载章节列表
  50. const chapterRes = await this.$http.get(`/chapter/list/${this.novelId}`);
  51. if (chapterRes.rows && Array.isArray(chapterRes.rows)) {
  52. this.chapters = chapterRes.rows;
  53. }
  54. // 加载当前章节内容
  55. if (this.chapters.length > 0) {
  56. await this.loadChapterContent(0);
  57. }
  58. // 加载章节广告
  59. const adRes = await this.$http.get('/ad/position?code=CHAPTER_FOOTER');
  60. this.chapterAds = adRes.data;
  61. },
  62. async loadChapterContent(index) {
  63. if (index < 0 || index >= this.chapters.length) return;
  64. const chapterId = this.chapters[index].id;
  65. const res = await this.$http.get(`/chapter/content/${chapterId}`);
  66. // 更新章节内容
  67. if (res.data) {
  68. this.$set(this.chapters, index, {
  69. ...this.chapters[index],
  70. content: res.data.content
  71. });
  72. this.currentChapter = index;
  73. }}
  74. ,
  75. // 定时显示中间广告
  76. scheduleMidAd() {
  77. setTimeout(async () => {
  78. const res = await this.$http.get('/ad/position?code=MID_CHAPTER');
  79. this.midAds = res.data;
  80. this.showMidAd = true;
  81. // 10秒后隐藏
  82. setTimeout(() => this.showMidAd = false, 10000);
  83. }, 30000); // 30秒后显示
  84. },
  85. prevChapter() {
  86. this.loadChapterContent(this.currentChapter - 1);
  87. },
  88. nextChapter() {
  89. this.loadChapterContent(this.currentChapter + 1);
  90. },
  91. showCatalog() {
  92. uni.navigateTo({
  93. url: `/pages/novel/catalog?id=${this.novelId}`
  94. });
  95. }
  96. }
  97. }
  98. </script>