feat(user/questions): 手机端时间跨年自动补年份,避免省略年份后产生歧义
DateCompact:与当前同一年的渲染「月-日 时:分」,跨年补回完整「年-月-日 时:分」。 只砍年份会让「去年今天」和「今年今天」显示成同一串,逐条补年份比按年分组便宜得多 (列表带游标分页 + 可切排序/筛选,组标题会跨页重复或错位)。 桌面端不受影响,仍显示 Y-m-d H:i:s。 测试覆盖年份边界(同年 1/1 与 12/31、跨年);预览数据里放了一条 2025 年的提问用于肉眼核对。
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
package template
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// dateCompact 是手机端列表的时间格式:同年省略年份,跨年补回年份。
|
||||
// 这条测试盯的是「年份边界」——同一年的 1 月 1 日也要省略年份,
|
||||
// 不能因为「看起来像很久以前」就提前补年。
|
||||
func TestDateCompact(t *testing.T) {
|
||||
now := time.Date(2026, 10, 23, 21, 0, 0, 0, time.Local)
|
||||
|
||||
cases := []struct {
|
||||
in time.Time
|
||||
want string
|
||||
}{
|
||||
{time.Date(2026, 9, 9, 1, 18, 3, 0, time.Local), "09-09 01:18"},
|
||||
{time.Date(2026, 1, 1, 0, 0, 0, 0, time.Local), "01-01 00:00"},
|
||||
{time.Date(2026, 12, 31, 23, 59, 59, 0, time.Local), "12-31 23:59"},
|
||||
{time.Date(2025, 9, 5, 4, 45, 22, 0, time.Local), "2025-09-05 04:45"},
|
||||
{time.Date(2027, 1, 1, 0, 0, 0, 0, time.Local), "2027-01-01 00:00"},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
if got := dateCompact(c.in, now); got != c.want {
|
||||
t.Errorf("dateCompact(%s) = %q, want %q", c.in.Format(time.RFC3339), got, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,9 @@ func FuncMap() []template.FuncMap {
|
||||
format = replacer.Replace(format)
|
||||
return t.Format(format)
|
||||
},
|
||||
"DateCompact": func(t time.Time) string {
|
||||
return dateCompact(t, time.Now())
|
||||
},
|
||||
"QuestionFormat": func(input string) template.HTML {
|
||||
input = html.EscapeString(input)
|
||||
input = strings.ReplaceAll(input, "\n", "</br>")
|
||||
@@ -236,3 +239,15 @@ func FuncMap() []template.FuncMap {
|
||||
func Safe(raw string) template.HTML {
|
||||
return template.HTML(raw)
|
||||
}
|
||||
|
||||
// dateCompact 手机端列表用的紧凑时间:与 now 同一年的只给「月-日 时:分」。
|
||||
// 手机一行的宽度放不下「Y-m-d H:i:s」(单它就要 127px),但只砍年份会让
|
||||
// 「去年的今天」和「今年今天」渲染成同一串,所以在跨年时自动补回年份。
|
||||
// 注意:这是「逐条补年份」,不是「按年分组」—— 列表带游标分页、可切排序与筛选,
|
||||
// 分组标题会跨页重复/错位,收益不如补年份直接。
|
||||
func dateCompact(t, now time.Time) string {
|
||||
if t.Year() == now.Year() {
|
||||
return t.Format("01-02 15:04")
|
||||
}
|
||||
return t.Format("2006-01-02 15:04")
|
||||
}
|
||||
|
||||
@@ -283,8 +283,9 @@
|
||||
<div class="uk-flex uk-flex-middle uk-flex-wrap" style="gap: 6px;">
|
||||
<!-- 手机端只显示「月-日 时:分」:完整时间占 127px,配合状态标签 + 操作按钮后
|
||||
一行放不下(360/390 宽实测会折行);桌面端仍显示完整年月日时分秒。
|
||||
tb-short / tb-text 与右侧状态标签共用 640px 这一个断点。 -->
|
||||
<span class="uk-text-small uk-text-muted"><span class="tb-short">{{Date .CreatedAt "m-d H:i"}}</span><span class="tb-text">{{Date .CreatedAt "Y-m-d H:i:s"}}</span></span>
|
||||
跨年的条目由 DateCompact 自动补回年份(否则「去年今天」和「今年今天」
|
||||
会渲染成同一串)。tb-short / tb-text 与右侧状态标签共用 640px 断点。 -->
|
||||
<span class="uk-text-small uk-text-muted"><span class="tb-short">{{DateCompact .CreatedAt}}</span><span class="tb-text">{{Date .CreatedAt "Y-m-d H:i:s"}}</span></span>
|
||||
{{ if .IsPinned }}
|
||||
<span class="uk-label uk-label-warning qlist-pill" title="{{t $.LangCode "qlist.pinned"}}"><span class="tb-short">{{t $.LangCode "qlist.pinnedShort"}}</span><span class="tb-text">{{t $.LangCode "qlist.pinned"}}</span></span>
|
||||
{{ end }}
|
||||
|
||||
@@ -304,7 +304,7 @@ func writeAdminListPreviews(t *testing.T, outDir string) {
|
||||
Link: "/_/test/1", IsAnswered: true, IsRead: true, QuestionID: 1, IsPinned: true, PinLink: "/_/test/1/pin"},
|
||||
adminItem{Type: "question_private", CreatedAt: time.Now(), Content: "悄悄话:最近还好吗",
|
||||
Link: "/_/test/2", IsAnswered: false, IsPrivate: true, QuestionID: 2, PinLink: "/_/test/2/pin"},
|
||||
adminItem{Type: "question_public", CreatedAt: time.Now(), Content: "光环是什么材质的?",
|
||||
adminItem{Type: "question_public", CreatedAt: time.Date(2025, 9, 5, 4, 45, 22, 0, time.Local), Content: "光环是什么材质的?",
|
||||
Link: "/_/test/3", IsAnswered: true, IsRead: false, QuestionID: 3, PinLink: "/_/test/3/pin"},
|
||||
},
|
||||
"ReceivedChats": []interface{}{
|
||||
|
||||
Reference in New Issue
Block a user