/** * 书籍目录页面 - 主要逻辑 */ class BookCatalogApp { constructor() { this.books = []; this.filteredBooks = []; this.statistics = null; this.init(); } async init() { try { await this.loadStatistics(); await this.loadBooks(); this.setupEventListeners(); } catch (error) { console.error('应用初始化失败:', error); this.showToast('应用初始化失败,请刷新页面重试', 'error'); } } setupEventListeners() { // 搜索功能 const searchInput = document.getElementById('searchInput'); const searchBtn = document.getElementById('searchBtn'); searchBtn.addEventListener('click', () => this.performSearch()); searchInput.addEventListener('input', () => this.performSearch()); searchInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') this.performSearch(); }); } async loadStatistics() { try { const response = await fetch('/api/v2/statistics'); if (!response.ok) { throw new Error('获取统计信息失败'); } const result = await response.json(); if (!result.success) { throw new Error(result.error || '获取统计信息失败'); } this.statistics = result.statistics; this.renderStatistics(); } catch (error) { console.error('加载统计信息失败:', error); // 统计信息加载失败不影响主要功能,只记录错误 } } renderStatistics() { if (!this.statistics) return; document.getElementById('totalBooks').textContent = this.statistics.total_books || 0; document.getElementById('totalPages').textContent = this.statistics.total_pages || 0; document.getElementById('totalPieces').textContent = this.statistics.total_pieces || 0; document.getElementById('totalCatalogs').textContent = this.statistics.total_catalogs || 0; document.getElementById('statistics').style.display = 'grid'; } async loadBooks() { const loading = document.getElementById('loading'); const booksGrid = document.getElementById('booksGrid'); const emptyState = document.getElementById('emptyState'); loading.style.display = 'block'; booksGrid.style.display = 'none'; emptyState.style.display = 'none'; try { const response = await fetch('/api/v2/books'); if (!response.ok) { throw new Error('获取书籍列表失败'); } const result = await response.json(); if (!result.success) { throw new Error(result.error || '获取书籍列表失败'); } this.books = result.books || []; this.filteredBooks = [...this.books]; console.log(`加载了 ${this.books.length} 本书籍`); if (this.books.length === 0) { loading.style.display = 'none'; emptyState.style.display = 'block'; } else { this.renderBooks(); } } catch (error) { console.error('加载书籍列表失败:', error); loading.style.display = 'none'; emptyState.style.display = 'block'; this.showToast('加载书籍列表失败: ' + error.message, 'error'); } } renderBooks() { const loading = document.getElementById('loading'); const booksGrid = document.getElementById('booksGrid'); const emptyState = document.getElementById('emptyState'); loading.style.display = 'none'; if (this.filteredBooks.length === 0) { booksGrid.style.display = 'none'; emptyState.innerHTML = `
未找到匹配的教材
`; emptyState.style.display = 'block'; return; } booksGrid.style.display = 'grid'; emptyState.style.display = 'none'; booksGrid.innerHTML = ''; this.filteredBooks.forEach(book => { const bookCard = this.createBookCard(book); booksGrid.appendChild(bookCard); }); } createBookCard(book) { const card = document.createElement('div'); card.className = 'book-card'; card.dataset.bookId = book.market_book_id; // 构建封面URL const coverUrl = this.getCoverUrl(book); // 年级和学期信息 const gradeInfo = this.getGradeInfo(book.grade_id, book.reel_id); card.innerHTML = ` ${book.market_book_name}
${book.market_book_name}
${book.max_page || 0} 页 ${gradeInfo}
${book.market_classify_name || '未分类'}
`; // 点击事件 card.addEventListener('click', () => { this.openBook(book.market_book_id); }); return card; } getCoverUrl(book) { if (book.market_book_cover) { // 如果有封面路径,使用 data 目录 return `data/${book.market_book_cover}`; } // 默认封面 return 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjI4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMjAwIiBoZWlnaHQ9IjI4MCIgZmlsbD0iIzY2N2VlYSIvPjx0ZXh0IHg9IjUwJSIgeT0iNTAlIiBmb250LWZhbWlseT0iQXJpYWwiIGZvbnQtc2l6ZT0iMjQiIGZpbGw9IndoaXRlIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBkeT0iLjNlbSI+8J+TljwvdGV4dD48L3N2Zz4='; } getGradeInfo(gradeId, reelId) { const grades = { 40: '一年级', 41: '二年级', 42: '三年级', 43: '四年级', 44: '五年级', 45: '六年级' }; const reels = { 1: '上册', 2: '下册' }; const grade = grades[gradeId] || `年级${gradeId}`; const reel = reels[reelId] || `学期${reelId}`; return `${grade}${reel}`; } performSearch() { const keyword = document.getElementById('searchInput').value.trim().toLowerCase(); if (!keyword) { this.filteredBooks = [...this.books]; } else { this.filteredBooks = this.books.filter(book => { return book.market_book_name.toLowerCase().includes(keyword) || (book.market_classify_name && book.market_classify_name.toLowerCase().includes(keyword)); }); } this.renderBooks(); } openBook(bookId) { // 跳转到阅读页面 window.location.href = `/reader?book_id=${bookId}`; } showToast(message, type = 'info') { const toast = document.getElementById('toast'); toast.textContent = message; toast.className = `toast ${type} show`; setTimeout(() => { toast.classList.remove('show'); }, 3000); } } // 页面加载完成后初始化应用 document.addEventListener('DOMContentLoaded', () => { new BookCatalogApp(); });