已读完的书卡改成和「在读」同一套样式,补开始/读完时间

可行性(先说结论)
- 「开始阅读时间」在官方文档里没列,但 /book/getprogress 的原始回包里有
  book.startReadingTime,6 本已读完的全都有
- 顺带纠正我上一轮的错误结论:真正常为 0 的是 recordReadingTime,
  book.readingTime 是有值的(西线无战事 6190 秒 = 103 分),
  已存进 JSON 的 readingSeconds,卡片暂未展示

抽公共组件
- 新增 src/components/reading-card.astro,在读和已读完共用,样式强制统一:
  横版卡片、封面在左、信息在右
- 两处只在底部两行不同:
    在读   进度条 + 百分比 / 最近阅读 X
    已读完 开始 X / 读完 Y(无进度条)

数据层
- fetch-reading.mjs 每个条目新增 startedAt / finishedAt / readingSeconds
- src/lib/reading.ts 的 ReadingBook 类型同步补上(都可选,老数据不会炸)
- startReadingTime / finishTime 缺失时卡片自动少一行,不会渲染出「开始 —」

时间显示走 Asia/Shanghai。所以西线无战事的 startReadingTime
1786207913(UTC 08-08T15:31Z)在页面上是「开始 2026-08-09」,
这才是本地日期。

静态验证(dist/bookshelf/index.html)
- 在读区 20 张卡 / 20 条进度条 / 20 个「最近阅读」
- 已读完区 6 张卡 / 0 条进度条 / 6 个「开始 X」/ 6 个「读完 X」
- 抽一张:西线无战事(译文经典) 雷马克 · 文学-外国文学
  开始 2026-08-09 读完 2026-09-06,确认不含进度条
- 搜索/领域筛选的 data-weread-card 仍挂在新卡片上,筛选不受影响
This commit is contained in:
dsh
2026-09-15 10:51:50 +08:00
parent 4df235ea21
commit 8a867132de
6 changed files with 208 additions and 98 deletions
+17 -1
View File
@@ -15,7 +15,8 @@
* 两处实测得到的结论,别被直觉带偏:
* 1. /shelf/sync 一次就给全了封面/书名/作者/分类/最近阅读时间/跳转链接,
* 只有「阅读进度」要额外调 /book/getprogress,所以请求数 = 1 + N
* 2. book.recordReadingTime 恒为 0,拿不到累计时长,所以卡片不做这一项
* 2. book.recordReadingTime 恒为 0,但 book.readingTime 是真数据,累计时长取后者
* 3. 官方文档没列 book.startReadingTime,但回包里有,是「开始阅读时间」
*/
import fs from "node:fs"
@@ -104,6 +105,12 @@ async function fetchReading() {
progress: null,
finished: false,
lastReadAt: new Date(Number(book.readUpdateTime) * 1000).toISOString(),
// 下面三个来自 /book/getprogress。官方文档没列 startReadingTime,
// 但原始回包里确实有(读完的 6 本全都有),是「开始阅读时间」。
startedAt: null,
finishedAt: null,
/** 累计阅读秒数。注意是 readingTime,不是恒为 0 的 recordReadingTime */
readingSeconds: null,
deepLink: book.deepLink ?? "",
}
@@ -115,6 +122,15 @@ async function fetchReading() {
// progress 是 0-100 的整数,只有正好 100 才算读完
entry.finished = reading.progress === 100
}
if (reading.startReadingTime) {
entry.startedAt = new Date(reading.startReadingTime * 1000).toISOString()
}
if (reading.finishTime) {
entry.finishedAt = new Date(reading.finishTime * 1000).toISOString()
}
if (typeof reading.readingTime === "number") {
entry.readingSeconds = reading.readingTime
}
} catch (error) {
// 单本节失败不该让整次抓取挂掉,卡片退化成「不显示进度条」
console.warn(` ⚠️ ${book.title}:进度获取失败 — ${error.message}`)