+30
@@ -7,6 +7,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"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) {
|
func TestUpsertNodeInfoInsertsAndUpdatesSameNode(t *testing.T) {
|
||||||
st := openTestStore(t)
|
st := openTestStore(t)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ const calendarMonth = ref(new Date())
|
|||||||
const dailyCounts = ref<Record<string, number>>({})
|
const dailyCounts = ref<Record<string, number>>({})
|
||||||
const selectedDate = ref('')
|
const selectedDate = ref('')
|
||||||
const weekdays = ['日', '一', '二', '三', '四', '五', '六']
|
const weekdays = ['日', '一', '二', '三', '四', '五', '六']
|
||||||
|
const todayDate = formatDateKey(new Date())
|
||||||
|
|
||||||
const calendarDays = computed(() => monthDays(calendarMonth.value))
|
const calendarDays = computed(() => monthDays(calendarMonth.value))
|
||||||
|
|
||||||
@@ -150,7 +151,7 @@ onMounted(() => {
|
|||||||
v-else
|
v-else
|
||||||
type="button"
|
type="button"
|
||||||
class="signed-calendar-day"
|
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)"
|
@click="selectDate(day)"
|
||||||
>
|
>
|
||||||
<span class="signed-calendar-date">{{ Number(day.slice(8, 10)) }}</span>
|
<span class="signed-calendar-date">{{ Number(day.slice(8, 10)) }}</span>
|
||||||
|
|||||||
@@ -1291,6 +1291,13 @@ button.signed-calendar-day:not(:disabled):hover {
|
|||||||
background: var(--color-primary-soft);
|
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 {
|
.signed-calendar-day.selected {
|
||||||
border-color: var(--color-primary);
|
border-color: var(--color-primary);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|||||||
+2
-2
@@ -32,9 +32,9 @@ func (s *store) CountSigns(opts listOptions) (int64, error) {
|
|||||||
|
|
||||||
func (s *store) CountSignsByDay(opts listOptions) ([]signDayCount, error) {
|
func (s *store) CountSignsByDay(opts listOptions) ([]signDayCount, error) {
|
||||||
var rows []signDayCount
|
var rows []signDayCount
|
||||||
dateExpr := "date(sign_time)"
|
dateExpr := "strftime('%Y-%m-%d', sign_time)"
|
||||||
if s.driver == databaseDriverMySQL {
|
if s.driver == databaseDriverMySQL {
|
||||||
dateExpr = "DATE(sign_time)"
|
dateExpr = "DATE_FORMAT(sign_time, '%Y-%m-%d')"
|
||||||
}
|
}
|
||||||
q := applySignFilters(s.db.Model(&signRecord{}), opts).
|
q := applySignFilters(s.db.Model(&signRecord{}), opts).
|
||||||
Select(dateExpr + " AS sign_date, COUNT(*) AS count").
|
Select(dateExpr + " AS sign_date, COUNT(*) AS count").
|
||||||
|
|||||||
Reference in New Issue
Block a user