From 2840aca69b20285db6c3235e3d5764314ae90e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E9=97=BB=E9=A3=8E?= Date: Tue, 16 Jun 2026 20:56:50 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=AD=BE=E5=88=B0=E6=97=A5?= =?UTF-8?q?=E5=8E=86=E4=BA=BA=E6=95=B0=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude --- db_test.go | 30 +++++++++++++++++++ .../src/components/SignedPage.vue | 3 +- meshmap_frontend/src/style.css | 7 +++++ sign_store.go | 4 +-- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/db_test.go b/db_test.go index 49e24de..6adc8a2 100644 --- a/db_test.go +++ b/db_test.go @@ -7,6 +7,7 @@ import ( "path/filepath" "strings" "testing" + "time" "gorm.io/gorm" ) @@ -34,6 +35,35 @@ func TestOpenStoreCreatesTables(t *testing.T) { } } +func TestCountSignsByDayFormatsDateString(t *testing.T) { + st := openTestStore(t) + defer st.Close() + + if _, err := st.CreateSign("!11111111", nil, nil, "first", time.Date(2026, 6, 15, 10, 0, 0, 0, time.UTC)); err != nil { + t.Fatalf("CreateSign() error = %v", err) + } + if _, err := st.CreateSign("!22222222", nil, nil, "second", time.Date(2026, 6, 15, 11, 0, 0, 0, time.UTC)); err != nil { + t.Fatalf("CreateSign() error = %v", err) + } + if _, err := st.CreateSign("!33333333", nil, nil, "third", time.Date(2026, 6, 16, 9, 0, 0, 0, time.UTC)); err != nil { + t.Fatalf("CreateSign() error = %v", err) + } + + rows, err := st.CountSignsByDay(listOptions{}) + if err != nil { + t.Fatalf("CountSignsByDay() error = %v", err) + } + if len(rows) != 2 { + t.Fatalf("CountSignsByDay() length = %d, want 2", len(rows)) + } + if rows[0].Date != "2026-06-16" || rows[0].Count != 1 { + t.Fatalf("first day count = %#v, want 2026-06-16 count 1", rows[0]) + } + if rows[1].Date != "2026-06-15" || rows[1].Count != 2 { + t.Fatalf("second day count = %#v, want 2026-06-15 count 2", rows[1]) + } +} + func TestUpsertNodeInfoInsertsAndUpdatesSameNode(t *testing.T) { st := openTestStore(t) defer st.Close() diff --git a/meshmap_frontend/src/components/SignedPage.vue b/meshmap_frontend/src/components/SignedPage.vue index a2e2baa..7d1cf70 100644 --- a/meshmap_frontend/src/components/SignedPage.vue +++ b/meshmap_frontend/src/components/SignedPage.vue @@ -14,6 +14,7 @@ const calendarMonth = ref(new Date()) const dailyCounts = ref>({}) const selectedDate = ref('') const weekdays = ['日', '一', '二', '三', '四', '五', '六'] +const todayDate = formatDateKey(new Date()) const calendarDays = computed(() => monthDays(calendarMonth.value)) @@ -150,7 +151,7 @@ onMounted(() => { v-else type="button" class="signed-calendar-day" - :class="{ selected: selectedDate === day, 'has-signs': dailyCounts[day] }" + :class="{ selected: selectedDate === day, today: todayDate === day, 'has-signs': dailyCounts[day] }" @click="selectDate(day)" > {{ Number(day.slice(8, 10)) }} diff --git a/meshmap_frontend/src/style.css b/meshmap_frontend/src/style.css index 0fe83de..84a9ae6 100644 --- a/meshmap_frontend/src/style.css +++ b/meshmap_frontend/src/style.css @@ -1291,6 +1291,13 @@ button.signed-calendar-day:not(:disabled):hover { background: var(--color-primary-soft); } +.signed-calendar-day.today { + border-color: var(--color-warning); + color: color-mix(in srgb, var(--color-warning) 72%, var(--color-heading)); + background: var(--color-warning-soft); + box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-warning) 36%, transparent); +} + .signed-calendar-day.selected { border-color: var(--color-primary); color: #fff; diff --git a/sign_store.go b/sign_store.go index 0e81753..e5ebe0b 100644 --- a/sign_store.go +++ b/sign_store.go @@ -32,9 +32,9 @@ func (s *store) CountSigns(opts listOptions) (int64, error) { func (s *store) CountSignsByDay(opts listOptions) ([]signDayCount, error) { var rows []signDayCount - dateExpr := "date(sign_time)" + dateExpr := "strftime('%Y-%m-%d', sign_time)" if s.driver == databaseDriverMySQL { - dateExpr = "DATE(sign_time)" + dateExpr = "DATE_FORMAT(sign_time, '%Y-%m-%d')" } q := applySignFilters(s.db.Model(&signRecord{}), opts). Select(dateExpr + " AS sign_date, COUNT(*) AS count").