read.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // pages/read/read.js
  2. const chapterApi = require('../../api/chapter');
  3. const historyApi = require('../../api/history');
  4. const userUtil = require('../../utils/user');
  5. Page({
  6. data: {
  7. contentId: null,
  8. chapterId: null,
  9. chapter: null,
  10. chapters: [],
  11. currentIndex: 0,
  12. fontSize: 32, // 字体大小(rpx)
  13. backgroundColor: '#fff', // 背景颜色
  14. loading: true,
  15. showSettings: false
  16. },
  17. onLoad(options) {
  18. const contentId = parseInt(options.contentId);
  19. const chapterId = parseInt(options.chapterId);
  20. if (!contentId || !chapterId) {
  21. wx.showToast({
  22. title: '参数错误',
  23. icon: 'none'
  24. });
  25. setTimeout(() => {
  26. wx.navigateBack();
  27. }, 1500);
  28. return;
  29. }
  30. this.setData({ contentId, chapterId });
  31. this.loadChapters();
  32. this.loadChapter();
  33. },
  34. // 加载章节列表
  35. async loadChapters() {
  36. try {
  37. const chapters = await chapterApi.getBookChapterList(this.data.contentId);
  38. const currentIndex = chapters.findIndex(c => c.chapterId === this.data.chapterId);
  39. this.setData({
  40. chapters,
  41. currentIndex: currentIndex >= 0 ? currentIndex : 0
  42. });
  43. } catch (error) {
  44. console.error('加载章节列表失败:', error);
  45. }
  46. },
  47. // 加载章节内容
  48. async loadChapter() {
  49. this.setData({ loading: true });
  50. try {
  51. const chapter = await chapterApi.getBookChapter(this.data.chapterId);
  52. this.setData({ chapter });
  53. wx.setNavigationBarTitle({
  54. title: chapter.chapterTitle || '阅读'
  55. });
  56. // 保存阅读历史
  57. this.saveHistory();
  58. } catch (error) {
  59. wx.showToast({
  60. title: error || '加载失败',
  61. icon: 'none'
  62. });
  63. } finally {
  64. this.setData({ loading: false });
  65. }
  66. },
  67. // 保存阅读历史
  68. async saveHistory() {
  69. if (!userUtil.isLogin() || !this.data.contentId) {
  70. return;
  71. }
  72. try {
  73. await historyApi.addHistory(this.data.contentId);
  74. } catch (error) {
  75. console.error('保存阅读历史失败:', error);
  76. // 静默失败,不影响阅读体验
  77. }
  78. },
  79. // 上一章
  80. prevChapter() {
  81. if (this.data.currentIndex > 0) {
  82. const prevChapter = this.data.chapters[this.data.currentIndex - 1];
  83. this.setData({
  84. chapterId: prevChapter.chapterId,
  85. currentIndex: this.data.currentIndex - 1
  86. });
  87. this.loadChapter();
  88. } else {
  89. wx.showToast({
  90. title: '已经是第一章了',
  91. icon: 'none'
  92. });
  93. }
  94. },
  95. // 下一章
  96. nextChapter() {
  97. if (this.data.currentIndex < this.data.chapters.length - 1) {
  98. const nextChapter = this.data.chapters[this.data.currentIndex + 1];
  99. this.setData({
  100. chapterId: nextChapter.chapterId,
  101. currentIndex: this.data.currentIndex + 1
  102. });
  103. this.loadChapter();
  104. } else {
  105. wx.showToast({
  106. title: '已经是最后一章了',
  107. icon: 'none'
  108. });
  109. }
  110. },
  111. // 显示/隐藏设置
  112. toggleSettings() {
  113. this.setData({
  114. showSettings: !this.data.showSettings
  115. });
  116. },
  117. // 调整字体大小
  118. adjustFontSize(e) {
  119. const size = parseInt(e.detail.value);
  120. this.setData({ fontSize: size * 2 + 28 }); // 28-48
  121. },
  122. // 切换背景色
  123. changeBackground(e) {
  124. const color = e.currentTarget.dataset.color;
  125. this.setData({ backgroundColor: color });
  126. },
  127. // 显示目录
  128. showChapterList() {
  129. const itemList = this.data.chapters.map((item, index) =>
  130. `${index + 1}. ${item.chapterTitle}`
  131. );
  132. wx.showActionSheet({
  133. itemList,
  134. success: (res) => {
  135. const chapter = this.data.chapters[res.tapIndex];
  136. this.setData({
  137. chapterId: chapter.chapterId,
  138. currentIndex: res.tapIndex
  139. });
  140. this.loadChapter();
  141. }
  142. });
  143. }
  144. });