时间线操作行补真实计数(评论数 / 浏览数),classic 首页同步加操作行

- posts 表加 view_count 列(迁移自动补列),公开文章详情每被拉取 +1;
  列表接口子查询带出非删除评论数
- classic 首页文章卡补上操作行(回复 / 赞 / 查看),与 vivid 同行为:
  回复跳评论区锚点、赞本机 localStorage、查看进详情;
  卡片底部 meta 行的日期不再重复包「查看」链接
- vivid 操作行的回复 / 查看旁展示对应计数(万以上缩写)
This commit is contained in:
Sakurasan committed 2026-10-08 00:15:34 +08:00
1 parent 7171c95275
commit 916dd74034
6 files changed
+102 -12

No files matched your search

+11 -2
View File
@@ -164,6 +164,8 @@ func (s *Store) migrate() error {
`ALTER TABLE posts ADD COLUMN images TEXT NOT NULL DEFAULT '[]'`,
// 正文首个外链的预览卡片(og 标题/描述/封面),JSON 对象或空串
`ALTER TABLE posts ADD COLUMN link_card TEXT NOT NULL DEFAULT ''`,
// 浏览数:公开文章详情每被拉取一次 +1(不区分访客,博客场景够用)
`ALTER TABLE posts ADD COLUMN view_count INTEGER NOT NULL DEFAULT 0`,
// 账号角色:owner(站主,全库唯一)/ reader(评论区访客)
`ALTER TABLE users ADD COLUMN role TEXT NOT NULL DEFAULT 'reader'`,
// 后台账号密码(provider=admin 的行才有值):多用户改造后密码上库,
@@ -580,7 +582,9 @@ const postCols = `id, kind, title, slug, summary, cover_url, content_md, content
const listCols = `id, kind, title, slug, summary, cover_url,
'' AS content_md,
CASE WHEN kind = 'short' THEN content_html ELSE substr(content_html, 1, 600) END AS content_html,
status, published_at, created_at, updated_at, reading_minutes, LENGTH(content_md), images, link_card`
status, published_at, created_at, updated_at, reading_minutes, LENGTH(content_md), images, link_card,
(SELECT COUNT(*) FROM comments c WHERE c.post_id = posts.id AND c.is_deleted = 0) AS comment_count,
view_count`
// images 列的 JSON 编解码(列存 '[]',Go 侧 []string;坏数据静默为空)。
func decodeImages(s string) []string {
@@ -634,7 +638,7 @@ func scanPost(rows interface{ Scan(...any) error }) (model.Post, error) {
var imgs, card string
err := rows.Scan(&p.ID, &p.Kind, &p.Title, &p.Slug, &p.Summary, &p.CoverURL,
&p.ContentMd, &p.ContentHTML, &p.Status, &p.PublishedAt, &p.CreatedAt, &p.UpdatedAt,
&p.ReadingMinutes, &p.ContentLen, &imgs, &card)
&p.ReadingMinutes, &p.ContentLen, &imgs, &card, &p.CommentCount, &p.ViewCount)
p.Tags = []string{}
p.Images = decodeImages(imgs)
p.LinkCard = decodeLinkCard(card)
@@ -1473,6 +1477,11 @@ func (s *Store) Archive() ([]model.ArchiveYear, error) {
return years, nil
}
// BumpViewCount 浏览数自增。静默失败:计数器不该影响文章可读性。
func (s *Store) BumpViewCount(id int64) {
_, _ = s.db.Exec(s.db.Q(`UPDATE posts SET view_count = view_count + 1 WHERE id = ?`), id)
}
func splitDate(rfc3339 string) (string, string) {
if len(rfc3339) < 7 {
return "", ""