fix: 返回键失效的根因 + 同步页重做 + 连接池会永久阻塞线程
返回键
- 根因是 Framework7 的页面过渡由动画事件驱动:push 时把 allowPageChange
置 false,等动画报告结束再恢复。这个报告不来,路由就永久卡住,之后每次
导航都被静默丢弃,back() 还会把上一页重建一份而不是弹出。
实测对照:navigate({animate:false}) 前后状态完全正确,带动画则必卡。
因此关掉页面过渡动画——导航同步完成,处处正确。动效改由内容承担
(卡片入场、hero 揭示、顶部进度条),这个取舍里正确性优先。
- Screen 的返回改为显式 handler,先清掉残留过渡状态再 back(),
不依赖路由自己的闸门。注意只清视图上的 router-transition 类:
页面自身的 page-previous 是 F7 判断「回到哪一页」的依据,
一并清掉会导致重建出一个重复的页面(中途踩过这个坑)。
同步页
- .btn 系列样式原本只定义在 pages/Pages.css,而那个文件只被一个没有路由的
遗留页面引用,所以真实页面上按钮全都退化成 Framework7 的默认样式——
就是你看到的三条链接。样式移进每个界面都会加载的 Screen.css。
- 主次分明:一个填充主按钮 + 两个带副标题的次按钮;补上「同步会取哪些数据」
说明,页面不再是一大片空白。
- 进度条显示当前阶段(每日数据 2026-08-01 / 运动详情 12/174 / 身体成分…),
原来只有「0 / 730 天」,几分钟里完全看不出在做什么。
后端
- MariaDB 连接池:_mariadb_release 用的是阻塞 put(),而队列 maxsize=10,
_mariadb_acquire 在池空时又会新建连接。并发超过 10 之后,归还的线程会
永久停在 put() 上,请求就此挂死。改为 put_nowait,多出来的连接直接关闭。
- 进程重启会带走同步线程却留下 status=syncing 的行,界面上是一个永远不动
的进度条,还拒绝开始新同步。启动时清理。
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -333,7 +333,7 @@ function SyncPage() {
|
||||
{syncing ? (
|
||||
<section className="sync-card">
|
||||
<div className="progress-head">
|
||||
<span>正在同步…</span>
|
||||
<span>{syncStatus?.stage || '正在同步…'}</span>
|
||||
<span className="progress-count">{current} / {total} 天</span>
|
||||
</div>
|
||||
<div
|
||||
@@ -351,27 +351,38 @@ function SyncPage() {
|
||||
</p>
|
||||
</section>
|
||||
) : (
|
||||
<div className="sync-actions-row">
|
||||
<>
|
||||
<button
|
||||
className="btn btn-primary btn-large"
|
||||
className="btn btn-primary btn-large sync-primary"
|
||||
onClick={syncLatest}
|
||||
disabled={busy}
|
||||
>
|
||||
{loading ? '同步中…' : '同步最新数据'}
|
||||
</button>
|
||||
<button className="btn btn-plain" onClick={syncHistory} disabled={busy}>
|
||||
同步历史({historyLabel(settings?.historyDays ?? 365)})
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-plain"
|
||||
onClick={syncDetails}
|
||||
disabled={busy || !!details?.running}
|
||||
>
|
||||
{details?.running
|
||||
? `正在补运动详情 ${details.done}/${details.total || '…'}`
|
||||
: '补齐运动详情'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="sync-secondary">
|
||||
<button className="btn btn-plain" onClick={syncHistory} disabled={busy}>
|
||||
<span className="sync-btn-label">同步历史</span>
|
||||
<span className="sync-btn-sub">
|
||||
{historyLabel(settings?.historyDays ?? 365)}
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-plain"
|
||||
onClick={syncDetails}
|
||||
disabled={busy || !!details?.running}
|
||||
>
|
||||
<span className="sync-btn-label">
|
||||
{details?.running ? '补齐中…' : '补齐详细数据'}
|
||||
</span>
|
||||
<span className="sync-btn-sub">
|
||||
{details?.running
|
||||
? `${details.stage ?? ''} ${details.done}/${details.total || '…'}`
|
||||
: '运动详情与全天曲线'}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="sync-facts">
|
||||
@@ -387,9 +398,9 @@ function SyncPage() {
|
||||
{auto?.account?.autoSync === false
|
||||
? '已关闭'
|
||||
: auto?.account
|
||||
? `每 ${auto.account.intervalMinutes >= 60
|
||||
? `${auto.account.intervalMinutes / 60} 小时`
|
||||
: `${auto.account.intervalMinutes} 分钟`}`
|
||||
? auto.account.intervalMinutes >= 60
|
||||
? `每 ${auto.account.intervalMinutes / 60} 小时`
|
||||
: `每 ${auto.account.intervalMinutes} 分钟`
|
||||
: '—'}
|
||||
</span>
|
||||
</div>
|
||||
@@ -399,6 +410,19 @@ function SyncPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section className="sync-note">
|
||||
<h3 className="sec-title">同步会取哪些数据</h3>
|
||||
<ul className="sync-list">
|
||||
<li>每日指标:步数、心率、HRV、压力、身体电量、血氧、呼吸、睡眠、训练准备度</li>
|
||||
<li>运动记录与每次运动的完整详情(分段、心率区间、采样曲线)</li>
|
||||
<li>全天曲线:心率、压力、身体电量、呼吸、血氧</li>
|
||||
<li>身体成分、成绩预测、爬坡分、饮水、挑战赛、设备</li>
|
||||
</ul>
|
||||
<p className="field-hint">
|
||||
数据只保存在自建数据库,打开页面时读的是本机,不会再回源 Garmin。
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{syncStatus?.lastError && !syncing && (
|
||||
<p className="sync-lasterror">上次错误:{syncStatus.lastError}</p>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user