bookStore.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import { defineStore } from 'pinia'
  2. import API from '@api'
  3. import type {
  4. BaseBook,
  5. Book,
  6. BookChapter,
  7. BookProgress,
  8. SeachBook,
  9. } from '@/book'
  10. import type { webReadConfig } from '@/web'
  11. import { ElMessage } from 'element-plus/es'
  12. const default_config: webReadConfig = {
  13. theme: 0,
  14. font: 0,
  15. fontSize: 18,
  16. readWidth: 800,
  17. infiniteLoading: false,
  18. customFontName: '',
  19. jumpDuration: 1000,
  20. spacing: {
  21. paragraph: 1,
  22. line: 0.8,
  23. letter: 0,
  24. },
  25. }
  26. let webReadConfigLoadedDate: Date | undefined
  27. export const useBookStore = defineStore('book', {
  28. state: () => {
  29. return {
  30. searchBooks: [] as SeachBook[],
  31. shelf: [] as Book[],
  32. catalog: [] as BookChapter[],
  33. readingBook: { chapterPos: 0, chapterIndex: 0 } as BaseBook & {
  34. chapterPos: number
  35. chapterIndex: number
  36. isSeachBook?: boolean
  37. },
  38. popCataVisible: false,
  39. contentLoading: true,
  40. showContent: false,
  41. config: default_config,
  42. miniInterface: false,
  43. readSettingsVisible: false,
  44. }
  45. },
  46. getters: {
  47. bookProgress: (state): BookProgress | undefined => {
  48. if (state.catalog.length === 0) return
  49. const { chapterIndex, chapterPos, name, author } = state.readingBook
  50. const title = state.catalog[chapterIndex]?.title
  51. if (!title) return
  52. return {
  53. name,
  54. author,
  55. durChapterIndex: chapterIndex,
  56. durChapterPos: chapterPos,
  57. durChapterTime: new Date().getTime(),
  58. durChapterTitle: title,
  59. }
  60. },
  61. theme: state => {
  62. return state.config.theme
  63. },
  64. isNight: state => state.config.theme === 6,
  65. },
  66. actions: {
  67. /** 从后端加载书架书籍,优先返回内存缓存 */
  68. async loadBookShelf(): Promise<Book[]> {
  69. const fetchBookshellf_promise = API.getBookShelf().then(resp => {
  70. const { isSuccess, data, errorMsg } = resp.data
  71. if (isSuccess === true) {
  72. if (
  73. this.shelf.length !== data.length &&
  74. this.shelf.length > 0 &&
  75. data.length > 0
  76. ) {
  77. ElMessage.info(`书架数据已更新`)
  78. }
  79. this.shelf = data.sort((a, b) => {
  80. const x = a['durChapterTime'] || 0
  81. const y = b['durChapterTime'] || 0
  82. return y - x
  83. })
  84. } else {
  85. if (errorMsg.includes('还没有添加小说') && this.shelf.length > 0) {
  86. ElMessage.info('当前书架上的书籍已经被删除')
  87. return (this.shelf = [])
  88. }
  89. ElMessage.error(errorMsg ?? '后端返回格式错误!')
  90. }
  91. return this.shelf
  92. })
  93. if (this.shelf.length > 0) {
  94. // bookshelf data fetched before:do not await
  95. return this.shelf
  96. } else {
  97. return await fetchBookshellf_promise
  98. }
  99. },
  100. /** 从后端加载书籍目录,优先返回内存缓存 */
  101. async loadWebCatalog(
  102. book: typeof this.readingBook,
  103. ): Promise<BookChapter[]> {
  104. const { bookUrl, name, chapterIndex } = book
  105. const fetchChapterList_promise = API.getChapterList(
  106. bookUrl as string,
  107. ).then(res => {
  108. const { isSuccess, data, errorMsg } = res.data
  109. if (isSuccess === false) {
  110. ElMessage.error(errorMsg)
  111. throw new Error()
  112. }
  113. if (
  114. bookUrl === this.readingBook.bookUrl &&
  115. data.length !== this.catalog.length &&
  116. data.length > 0 &&
  117. this.catalog.length > 0
  118. ) {
  119. ElMessage.info(`书籍${name}: 章节目录已更新`)
  120. }
  121. this.catalog = data
  122. return this.catalog
  123. })
  124. if (
  125. bookUrl === this.readingBook.bookUrl &&
  126. this.catalog.length > 0 &&
  127. this.catalog.length - 1 >= chapterIndex
  128. ) {
  129. return this.catalog
  130. } else {
  131. return await fetchChapterList_promise
  132. }
  133. },
  134. setPopCataVisible(visible: boolean) {
  135. this.popCataVisible = visible
  136. },
  137. setContentLoading(loading: boolean) {
  138. this.contentLoading = loading
  139. },
  140. setReadingBook(readingBook: typeof this.readingBook) {
  141. this.readingBook = readingBook
  142. },
  143. /** 只从从后端加载一次web阅读配置 */
  144. async loadWebConfig() {
  145. if (webReadConfigLoadedDate === undefined) {
  146. const _config = await API.getReadConfig()
  147. webReadConfigLoadedDate = new Date()
  148. return this.setConfig(_config)
  149. }
  150. },
  151. setConfig(config?: webReadConfig) {
  152. this.config = Object.assign({}, this.config, config)
  153. },
  154. setReadSettingsVisible(visible: boolean) {
  155. this.readSettingsVisible = visible
  156. },
  157. setShowContent(visible: boolean) {
  158. this.showContent = visible
  159. },
  160. setMiniInterface(mini: boolean) {
  161. this.miniInterface = mini
  162. },
  163. async setSearchBooks(books: SeachBook[]) {
  164. books.forEach(book => {
  165. const isSeachBook = this.shelf.every(
  166. item => item.bookUrl !== book.bookUrl,
  167. )
  168. if (isSeachBook === true) {
  169. this.searchBooks.push(book)
  170. }
  171. })
  172. },
  173. clearSearchBooks() {
  174. this.searchBooks = []
  175. },
  176. /** 1.保存进度到app 2.修改内存中的数据*/
  177. async saveBookProgress() {
  178. if (!this.bookProgress) return Promise.resolve()
  179. const { bookUrl } = this.readingBook
  180. const shelfRaw = toRaw(this.shelf)
  181. const findIndex = shelfRaw.findIndex(book => book.bookUrl === bookUrl)
  182. if (findIndex > -1) {
  183. this.shelf[findIndex] = Object.assign(
  184. {},
  185. shelfRaw[findIndex],
  186. this.bookProgress,
  187. )
  188. }
  189. // 直接关闭浏览器时 http请求可能被取消
  190. // return API.saveBookProgress(this.bookProgress)
  191. return API.saveBookProgressWithBeacon(this.bookProgress)
  192. },
  193. },
  194. })