fix(stats): 页脚时间标签改成「快照时间」,去掉重复的「数据基准日」

原来四行时间里,前两行说的是同一件事:
「数据基准日:2026-10-24」+「计算于:2026-10-24 14:05:22」。
`DataDate` 就是 `UpdatedAt` 的日期部分(同一个 now 格式化出来的),
两行并列只是把同一个值拆成粗/细两种粒度。

而且「计算于」没有主语:读者站在页脚最底部看到它,会当成「整页数据
算到这一刻」,可今日两项恰恰不在这份快照里 —— 命中缓存时
`withToday` 会用更新的读数替换它们,页面上就出现「标注 14:05、
今日提问却是 22:35 的数」。

改成三行:
  快照时间:     2026-10-24 14:05:22
  最后一条提问: ...
  最后一条回答: ...
「快照只含累计数字与图表、今日两项实时」由下面那条 cacheNote 说明,
不塞进标签里(标签越短越好扫)。词条同步:快照时间 / 快照時間 /
Snapshot: / 集計時刻。

顺带删掉 `Overview.DataDate` 字段:模板不用它之后就没有读者了,
留着它会诱使以后的人再拼出「基准日 + 计算于」这种重复行。

无 schema/接口变更,纯展示层。i18n 有词条数量对等测试,四个语言已
一起改;`go build ./...` 与 i18n / stats / template / templates /
route 测试全绿。
This commit is contained in:
tamakyi
2026-10-24 22:39:47 +08:00
parent 219adefc95
commit af39651734
9 changed files with 91 additions and 15 deletions
+17 -2
View File
@@ -40,6 +40,12 @@ db.Analytics.SiteAnalytics(ctx, now) // 纯 SQL 聚合,无缓存
句式用「上月提问量环比 %s%%」(带符号),不要写「比前一个月 -69.6%」。
- 累计与图表是**当天重算一次**的快照(当天首访时算,重启也会重算;不是「0 点快照」),
「今日提问/回答」两项实时(60 秒 TTL,见下)。
- 页脚时间标签因此叫「快照时间」而不是「计算于」:它只覆盖累计与图表,
今日两项会被 `withToday` 换掉。原先另有「数据基准日」一行,与它是 100% 重复
(`Overview.DataDate` 就是 `UpdatedAt` 的日期部分),已删。
- 今日两项的 60s TTL **不要**为了省查询改成 30 分钟:每分钟最多 2 条 COUNT,
20 万行实测 38ms/条 → 最坏 109 秒 DB 时间/天(0.13%),换不到什么;
而 30 分钟会让「(实时)」变成假话、提问者自己看不见刚发的那条。
- 日/周/时分组必须在 SQL 里 `AT TIME ZONE INTERVAL '+08:00'` 显式换算,
不能依赖数据库会话时区 —— 见「时区」一节。
@@ -78,8 +84,17 @@ totals + 字数分布 + 回答耗时合并成一条 SQL(都是同一张表的
站点为消除一个 1.6KB 外部 defer 就把页脚计时器内联了,这里不再挂 60KB 图表库。
- 折线:`Polyline` / `AreaPath` 模板函数算坐标,SVG `viewBox` + `preserveAspectRatio="none"`
+ `vector-effect: non-scaling-stroke`(否则窄屏描边被压细)。
- 折线:`NewLineChart` 一个函数给出 `{Max, Points, Area, Ticks}`,
SVG `viewBox` + `preserveAspectRatio="none"` + `vector-effect: non-scaling-stroke`
(否则窄屏描边被压细)。
- **坐标 / 面积 / 刻度必须同一次调用算出**:分开算会各按自己看到的峰值归一化,
线和刻度就错开半格。
- 纵轴上限 `niceMax(峰值)`(1/2/1.5/3/4/6/8×10^n),刻度 = 上限 / 一半 / 0;
上限恒为偶数 → 中间刻度必是整数。1.5 倍只在 mag≥100 时参与(否则是 7.5 半格)。
- 刻度文字放 SVG **外面**:viewBox 横向被拉伸,里面的文字会跟着变扁。
做法是左列绝对定位的 HTML 标签(top 用 Go 算好的 `TopPct`)+ 看不见的占位元素撑列宽。
- 面积沿基线(`h-padBottom`)闭合,别落到 viewBox 底边(那是轴标签的留白)。
- 全零/空数据只出轴不出线,否则贴基线的直线看着像「数据都是 0」。
- 柱状 / 分布条:`style="height:{{printf "%.1f" $pct}}%"`,CSS 直接用百分比。
- 环形:`<circle pathLength="100" stroke-dasharray="{{pct}} 100">` + `rotate(-90)`,
不用算周长。