/** * 阅读记录:最近阅读 + 已读章节(与「我的」数据源一致) */ const app = getApp() const { cleanSingleLineField } = require('../../utils/contentParser.js') function titleFromBookData(sectionId, bookFlat) { const row = bookFlat.find((s) => s.id === sectionId) return cleanSingleLineField( row?.sectionTitle || row?.section_title || row?.title || row?.chapterTitle || '' ) || `章节 ${sectionId}` } function midFromBookData(sectionId, bookFlat) { const row = bookFlat.find((s) => s.id === sectionId) return row?.mid ?? row?.MID ?? 0 } function mergeRecentFromLocal(apiList) { const normalized = Array.isArray(apiList) ? apiList.map((item) => ({ id: item.id, mid: item.mid, title: cleanSingleLineField(item.title || '') || `章节 ${item.id}` })) : [] if (normalized.length > 0) return normalized try { const progressData = wx.getStorageSync('reading_progress') || {} const bookFlat = Array.isArray(app.globalData.bookData) ? app.globalData.bookData : [] return Object.keys(progressData) .map((id) => ({ id, ts: progressData[id]?.lastOpenAt || progressData[id]?.last_open_at || 0 })) .filter((e) => e.id) .sort((a, b) => b.ts - a.ts) .slice(0, 20) .map((e) => ({ id: e.id, mid: midFromBookData(e.id, bookFlat), title: titleFromBookData(e.id, bookFlat) })) } catch (e) { return [] } } Page({ data: { statusBarHeight: 44, isLoggedIn: false, focus: 'all', recentList: [], readAllList: [], recentSectionTitle: '最近阅读', readSectionTitle: '已读章节' }, onLoad(options) { const focus = (options.focus === 'recent' || options.focus === 'read') ? options.focus : 'all' this.setData({ statusBarHeight: app.globalData.statusBarHeight || 44, focus }) this._applyMpUiTitles() }, onShow() { this.setData({ isLoggedIn: !!(app.globalData.isLoggedIn && app.globalData.userInfo?.id) }) this._applyMpUiTitles() if (this.data.isLoggedIn) this.loadData() }, _applyMpUiTitles() { const my = app.globalData.configCache?.mpConfig?.mpUi?.myPage || {} this.setData({ recentSectionTitle: my.recentReadTitle || '最近阅读', readSectionTitle: my.readStatLabel || '已读章节' }) }, async _ensureBookFlat() { let flat = Array.isArray(app.globalData.bookData) ? app.globalData.bookData : [] if (flat.length) return flat try { const r = await app.request({ url: '/api/miniprogram/book/all-chapters', silent: true }) const list = r?.data if (Array.isArray(list) && list.length) { app.globalData.bookData = list return list } } catch (_) {} return [] }, async loadData() { const userId = app.globalData.userInfo?.id if (!userId) return try { const res = await app.request({ url: `/api/miniprogram/user/dashboard-stats?userId=${encodeURIComponent(userId)}`, silent: true }) const bookFlat = await this._ensureBookFlat() let recent = [] let readIds = [] if (res?.success && res.data) { const apiRecent = Array.isArray(res.data.recentChapters) ? res.data.recentChapters : [] recent = mergeRecentFromLocal(apiRecent) readIds = Array.isArray(res.data.readSectionIds) ? res.data.readSectionIds.filter(Boolean) : [] } else { recent = mergeRecentFromLocal([]) } try { const progressData = wx.getStorageSync('reading_progress') || {} const fromKeys = Object.keys(progressData).filter(Boolean) const stored = wx.getStorageSync('readSectionIds') const fromStored = Array.isArray(stored) ? stored.filter(Boolean) : [] const fromGlobal = Array.isArray(app.globalData.readSectionIds) ? app.globalData.readSectionIds.filter(Boolean) : [] readIds = [...new Set([...readIds, ...fromGlobal, ...fromStored, ...fromKeys])] } catch (_) {} if (readIds.length === 0 && recent.length > 0) { readIds = recent.map((r) => r.id) } const readAllList = readIds.map((id) => ({ id, mid: midFromBookData(id, bookFlat), title: titleFromBookData(id, bookFlat) })) this.setData({ recentList: recent, readAllList }) } catch (e) { console.warn('[reading-records]', e) try { const bookFlat = await this._ensureBookFlat() let readIds = Array.isArray(app.globalData.readSectionIds) ? [...app.globalData.readSectionIds] : [] if (!readIds.length) { try { const stored = wx.getStorageSync('readSectionIds') if (Array.isArray(stored)) readIds = [...stored] } catch (_) {} } const recent = mergeRecentFromLocal([]) if (!readIds.length && recent.length) readIds = recent.map((r) => r.id) const readAllList = readIds.map((id) => ({ id, mid: midFromBookData(id, bookFlat), title: titleFromBookData(id, bookFlat) })) this.setData({ recentList: recent, readAllList }) } catch (_) { this.setData({ recentList: [], readAllList: [] }) } } }, goRead(e) { const id = e.currentTarget.dataset.id const mid = e.currentTarget.dataset.mid if (!id) return const q = mid ? `mid=${mid}` : `id=${id}` wx.navigateTo({ url: `/pages/read/read?${q}` }) }, goChapters() { wx.switchTab({ url: '/pages/chapters/chapters' }) }, goLogin() { wx.switchTab({ url: '/pages/my/my' }) }, goBack() { getApp().goBackOrToHome() } })