mirror of
https://github.com/KingHWJ/WeReadBoard.git
synced 2026-11-03 18:24:58 +08:00
feat(web): v2 看板前端接入真实数据接口
前端样式完全沿用 2.0 设计稿,仅替换数据来源。 - templates/index.html 改用设计稿 DOM 结构与类名,引用 styles.css + weapi.js + app.js - static/css/styles.css 引入 2.0 设计稿样式 - static/js/weapi.js 新增,封装 /api/v2/* 调用为全局 WeApi - static/js/app.js 重写:保留设计稿全部渲染函数与 CSS 类名, 数据源由 demo-data.js 静态假数据改为真实接口, 补充异步加载器、加载/错误状态机与重试按钮 - static/js/demo-data.js 保留为设计稿原始假数据对照
This commit is contained in:
1 parent
a114f3f407
commit
8af75454a4
5 files changed
+804
-1441
No files matched your search
+13
-208
@@ -1,211 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<!doctype html>
|
||||
<html lang="zh-CN" data-theme="light">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>我的读书数据</title>
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/echarts@5.5.0/dist/echarts.min.js"></script>
|
||||
<!-- 防闪烁:在 CSS 加载后、页面渲染前设置主题 -->
|
||||
<script>
|
||||
(function() {
|
||||
var saved = localStorage.getItem('theme');
|
||||
if (saved) {
|
||||
document.documentElement.setAttribute('data-theme', saved);
|
||||
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>阅间 · 微信读书看板</title>
|
||||
<link rel="stylesheet" href="/static/css/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<!-- 数据库连接告警横幅(MySQL 连接失败时显示) -->
|
||||
<div id="dbAlertBanner" class="db-alert-banner" style="display:none;">
|
||||
<span class="db-alert-icon">⚠️</span>
|
||||
<span class="db-alert-text">MySQL 数据库连接失败,数据可能无法正常加载。请检查 MySQL 服务是否已启动。</span>
|
||||
<span class="db-alert-detail" id="dbAlertDetail"></span>
|
||||
</div>
|
||||
|
||||
<!-- 导航栏 -->
|
||||
<nav class="navbar">
|
||||
<div class="nav-container">
|
||||
<div class="nav-logo" onclick="switchTab('overview')" style="cursor:pointer">
|
||||
<span class="logo-icon">📖</span>
|
||||
<span class="logo-text">我的读书数据</span>
|
||||
</div>
|
||||
<div class="nav-links">
|
||||
<a class="nav-link active" data-tab="overview" onclick="switchTab('overview')">总览</a>
|
||||
<a class="nav-link" data-tab="charts" onclick="switchTab('charts')">数据图表</a>
|
||||
<a class="nav-link" data-tab="top-books" onclick="switchTab('top-books')">读书排行</a>
|
||||
<a class="nav-link" data-tab="shelf" onclick="switchTab('shelf')">书架</a>
|
||||
<a class="nav-link" data-tab="notes" onclick="switchTab('notes')">笔记</a>
|
||||
<a class="nav-link" data-tab="discover" onclick="switchTab('discover')">推荐</a>
|
||||
</div>
|
||||
<div class="nav-right">
|
||||
<span class="nav-update" id="fetchTime"></span>
|
||||
<button class="theme-toggle" onclick="toggleTheme()" title="切换明亮/黑暗模式" aria-label="切换主题">
|
||||
<span class="icon-sun">☀️</span>
|
||||
<span class="icon-moon">🌙</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- 顶部常驻搜索框 -->
|
||||
<div class="global-search-bar">
|
||||
<div class="container">
|
||||
<div class="global-search-wrapper">
|
||||
<span class="global-search-icon">🔍</span>
|
||||
<input type="text" id="globalSearchInput" class="global-search-input" placeholder="搜索图书..." onkeydown="if(event.key==='Enter')globalSearch()">
|
||||
<button class="global-search-btn" onclick="globalSearch()">搜索</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===== 主视图(标签页切换) ===== -->
|
||||
<main id="mainView">
|
||||
|
||||
<!-- 总览标签页 -->
|
||||
<section id="tab-overview" class="tab-panel active">
|
||||
<div class="hero-section">
|
||||
<div class="hero-bg"></div>
|
||||
<div class="hero-content">
|
||||
<h1 class="hero-title">阅读,是一场漫长的旅行</h1>
|
||||
<p class="hero-subtitle" id="heroSubtitle">正在加载数据...</p>
|
||||
<div class="hero-stats" id="heroStats"></div>
|
||||
</div>
|
||||
</div>
|
||||
<section class="stats-cards-section">
|
||||
<div class="container">
|
||||
<div class="stats-grid" id="statsGrid"></div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<!-- 数据图表标签页 -->
|
||||
<section id="tab-charts" class="tab-panel">
|
||||
<div class="container" style="padding-top:40px;padding-bottom:60px">
|
||||
<h2 class="section-title">📊 阅读数据可视化</h2>
|
||||
<div class="charts-grid">
|
||||
<div class="chart-card large">
|
||||
<h3 class="chart-title">年度阅读时长趋势</h3>
|
||||
<div id="chart-yearly" class="chart-container"></div>
|
||||
</div>
|
||||
<div class="chart-card">
|
||||
<h3 class="chart-title">24小时阅读时段分布</h3>
|
||||
<div id="chart-hours" class="chart-container"></div>
|
||||
</div>
|
||||
<div class="chart-card">
|
||||
<h3 class="chart-title">偏好阅读分类</h3>
|
||||
<div id="chart-categories" class="chart-container"></div>
|
||||
</div>
|
||||
<div class="chart-card large">
|
||||
<h3 class="chart-title">偏好作者 TOP 10</h3>
|
||||
<div id="chart-authors" class="chart-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 读书排行标签页 -->
|
||||
<section id="tab-top-books" class="tab-panel">
|
||||
<div class="container" style="padding-top:40px;padding-bottom:60px">
|
||||
<h2 class="section-title">🏆 阅读时长排行</h2>
|
||||
<div class="top-books-list" id="topBooksGrid"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 书架标签页 -->
|
||||
<section id="tab-shelf" class="tab-panel">
|
||||
<div class="container" style="padding-top:40px;padding-bottom:60px">
|
||||
<h2 class="section-title">📚 我的书架</h2>
|
||||
<div class="shelf-controls">
|
||||
<div class="shelf-filters">
|
||||
<input type="text" id="shelfSearch" class="shelf-search" placeholder="搜索书名、作者...">
|
||||
<label class="filter-checkbox">
|
||||
<input type="checkbox" id="finishedOnly"> 仅看已读完
|
||||
</label>
|
||||
<button class="shelf-refresh-btn" id="shelfRefreshBtn" onclick="refreshShelf()" title="重新加载书架数据">
|
||||
<span class="btn-icon">⟳</span>
|
||||
<span class="btn-text">刷新</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="shelf-info" id="shelfInfo"></div>
|
||||
</div>
|
||||
<div class="shelf-categories" id="shelfCategories"></div>
|
||||
<div class="book-grid" id="bookGrid"></div>
|
||||
<div class="pagination" id="pagination"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 笔记标签页 -->
|
||||
<section id="tab-notes" class="tab-panel">
|
||||
<div class="container" style="padding-top:40px;padding-bottom:60px">
|
||||
<h2 class="section-title">✍️ 笔记概览</h2>
|
||||
<div class="notes-summary" id="notesSummary"></div>
|
||||
<div class="notebooks-grid" id="notebooksGrid"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 推荐标签页 -->
|
||||
<section id="tab-discover" class="tab-panel">
|
||||
<div class="container" style="padding-top:40px;padding-bottom:60px">
|
||||
<h2 class="section-title">🔍 推荐发现</h2>
|
||||
<div class="discover-tabs">
|
||||
<button class="discover-tab active" id="tabRecommend" onclick="switchDiscoverTab('recommend')">为你推荐</button>
|
||||
<button class="discover-tab" id="tabSearch" onclick="switchDiscoverTab('search')">搜索书籍</button>
|
||||
</div>
|
||||
<div id="recommendPanel" class="discover-panel">
|
||||
<div class="discover-controls">
|
||||
<button class="btn-primary" onclick="loadRecommend(0)">刷新推荐</button>
|
||||
<button class="btn-secondary" onclick="loadMoreRecommend()">换一批</button>
|
||||
</div>
|
||||
<div class="discover-grid" id="recommendGrid"></div>
|
||||
</div>
|
||||
<div id="searchPanel" class="discover-panel" style="display:none">
|
||||
<div class="search-box">
|
||||
<input type="text" id="searchInput" class="search-input" placeholder="输入书名、作者或关键词..." onkeydown="if(event.key==='Enter')doSearch()">
|
||||
<button class="btn-primary" onclick="doSearch()">搜索</button>
|
||||
</div>
|
||||
<div class="discover-grid" id="searchGrid"></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<!-- ===== 想法详情独立页面 ===== -->
|
||||
<div id="thoughtsPage" class="thoughts-page" style="display:none">
|
||||
<div class="thoughts-page-header">
|
||||
<div class="container">
|
||||
<button class="back-btn" onclick="closeThoughtsPage()">← 返回</button>
|
||||
<div class="thoughts-book-header" id="thoughtsBookHeader"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container thoughts-content" id="thoughtsContent">
|
||||
<div class="loading"><div class="loading-spinner"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 书籍详情弹窗 -->
|
||||
<div class="modal-overlay" id="bookDetailModal" onclick="closeModal('bookDetailModal')">
|
||||
<div class="modal-content book-detail-modal" onclick="event.stopPropagation()">
|
||||
<span class="modal-close" onclick="closeModal('bookDetailModal')">×</span>
|
||||
<div id="bookDetailBody" class="modal-body"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 回到顶部按钮 -->
|
||||
<button id="backToTop" class="back-to-top" onclick="scrollToTop()" title="回到顶部" aria-label="回到顶部">↑</button>
|
||||
|
||||
<!-- 页脚 -->
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<p>数据来源:微信读书 · 数据存储:本地 MySQL · 更新时间:<span id="footerTime"></span></p>
|
||||
<p class="footer-hint">点击书籍封面可在微信读书 App 中打开</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="/static/js/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
<svg style="display:none" aria-hidden="true"><defs>
|
||||
<symbol id="book" viewBox="0 0 24 24"><path d="M3 4c4-1 6 0 9 2 3-2 5-3 9-2v15c-4-1-6 0-9 2-3-2-5-3-9-2zM12 6v15"/></symbol><symbol id="grid" viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></symbol><symbol id="note" viewBox="0 0 24 24"><path d="M13 4H5v16h14v-8M11 13l1-4 7-7 3 3-7 7z"/></symbol><symbol id="search-icon" viewBox="0 0 24 24"><circle cx="10" cy="10" r="6.5"/><path d="m15 15 6 6"/></symbol><symbol id="chart" viewBox="0 0 24 24"><path d="M4 3v17h17M8 15v-4m5 4V7m5 8V4"/></symbol><symbol id="clock" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M12 6v6l4 2"/></symbol><symbol id="moon" viewBox="0 0 24 24"><path d="M20 14A9 9 0 0 1 10 3a9 9 0 1 0 10 11Z"/></symbol><symbol id="sun" viewBox="0 0 24 24"><circle cx="12" cy="12" r="4"/><path d="M12 2v2m0 16v2M2 12h2m16 0h2M5 5l1 1m12 12 1 1M5 19l1-1M18 6l1-1"/></symbol><symbol id="sync" viewBox="0 0 24 24"><path d="M20 7v5h-5M4 17v-5h5M6 6a8 8 0 0 1 14 6M4 12a8 8 0 0 0 14 6"/></symbol><symbol id="flag" viewBox="0 0 24 24"><path d="M5 21V3c5-4 9 4 14 0v11c-5 4-9-4-14 0"/></symbol>
|
||||
</defs></svg>
|
||||
<aside class="sidebar"><div class="logo"><div class="logo-mark"><svg><use href="#book"/></svg></div><div>阅间<small>READING SPACE</small></div></div><div class="navlabel">我的阅读空间</div><nav class="nav" aria-label="主导航"><button class="active" data-page="overview" title="阅读概览"><svg><use href="#grid"/></svg><span>阅读概览</span></button><button data-page="shelf" title="我的书架"><svg><use href="#book"/></svg><span>我的书架</span><em>8</em></button><button data-page="goals" title="阅读目标"><svg><use href="#flag"/></svg><span>阅读目标</span></button><button data-page="notes" title="笔记与划线"><svg><use href="#note"/></svg><span>笔记与划线</span></button><button data-page="discover" title="发现好书"><svg><use href="#search-icon"/></svg><span>发现好书</span></button></nav><div class="sidebar-bottom"><div class="connection"><span class="dot"></span>微信读书 · 个人空间<small>让每一页,都留下痕迹</small></div><div class="profile"><div class="avatar">读</div><div>我的阅读空间<small>数据来自你的微信读书账号</small></div></div></div></aside>
|
||||
<main class="main"><header class="topbar"><div class="breadcrumb">我的空间 <span>/ <b id="crumb" style="font-weight:400">阅读概览</b></span></div><div class="top-actions"><label class="searchbox"><svg><use href="#search-icon"/></svg><input id="global-search" placeholder="搜索书籍、书单…" aria-label="全局搜索"><span class="key">⌘ K</span></label><button class="iconbtn" id="theme" aria-label="切换至暗色主题"><svg><use href="#moon"/></svg></button><div class="avatar">L</div></div></header><div class="demo-banner"><span><span class="dot"></span><span id="conn-state">正在连接微信读书…</span></span><span>阅读目标保存在当前浏览器</span></div><div id="page-content"></div><footer class="footer"><span>阅间 · 与好书相伴,与自己相遇</span><span id="footer-state">数据来自微信读书个人账号</span></footer></main>
|
||||
<dialog id="detail" aria-label="内容详情"><div class="dialog-top"><h2 id="detail-title">书籍详情</h2><button class="iconbtn" data-action="close-detail" aria-label="关闭详情">✕</button></div><div id="detail-content"></div></dialog>
|
||||
<dialog id="goal-editor" aria-label="编辑阅读目标"><form id="goal-form"><div class="dialog-top"><div><div class="eyebrow">MAKE ROOM FOR READING</div><h2 id="editor-title">新建阅读目标</h2></div><button type="button" class="iconbtn" data-action="close-editor" aria-label="关闭目标编辑">✕</button></div><label class="field">目标名称<input id="goal-name" maxlength="60" placeholder="例如:秋季文学计划" required></label><div class="date-fields"><label class="field">开始日期<input id="goal-start" type="date" required></label><label class="field">结束日期<input id="goal-end" type="date" required></label></div><div class="section-head picker-head"><h3>想读些什么?</h3><span id="selection-count" class="pill"></span></div><p class="hint">选择书籍或加入书单当前书目,重复书籍只算一本,已读完直接计入完成。</p><label class="field"><input id="picker-search" placeholder="筛选书名、作者或书单…" aria-label="筛选目标书目"></label><div id="goal-picker"></div><p id="goal-error" class="form-error" role="alert"></p><div class="editor-footer"><span>仅保存在此浏览器</span><button class="primary" type="submit">保存阅读目标</button></div></form></dialog>
|
||||
<div id="toast" class="hidden" role="status"></div><script src="/static/js/weapi.js"></script><script src="/static/js/app.js"></script></body></html>
|
||||
Reference in new issue
Block a user