diff --git a/apps/web/src/views/StatsView.vue b/apps/web/src/views/StatsView.vue
index 5f8b87b..dbabaab 100644
--- a/apps/web/src/views/StatsView.vue
+++ b/apps/web/src/views/StatsView.vue
@@ -176,11 +176,13 @@ const totals = computed(() => summarize(entries.value));
const convertedEntries = computed(() => entries.value.filter((entry) => entry.baseAmount !== null));
const pendingConversionCount = computed(() => entries.value.length - convertedEntries.value.length);
const calendarCursorMonth = ref(selectedMonth.value);
+const calendarCursorYear = ref(selectedYear.value);
watch([rangeMode, selectedMonth, selectedYear, customStart, customEnd], () => {
const bounds = rangeBounds.value;
if (!bounds) return;
calendarCursorMonth.value = `${bounds.start.getFullYear()}-${String(bounds.start.getMonth() + 1).padStart(2, "0")}`;
+ calendarCursorYear.value = bounds.start.getFullYear();
});
const dailyStats = computed(() => {
@@ -243,17 +245,14 @@ const calendarDays = computed(() => {
});
const calendarMonthCells = computed(() => {
- const bounds = rangeBounds.value;
- if (!bounds) return [];
+ if (!rangeBounds.value) return [];
const summary = new Map(flowStats.value.map((item) => [item.date, item]));
const cells: Array<{ date: string; label: string; income: number; expense: number }> = [];
- const cursor = new Date(bounds.start.getFullYear(), bounds.start.getMonth(), 1);
- const end = new Date(bounds.end.getFullYear(), bounds.end.getMonth(), 1);
- while (cursor < end) {
+ for (let month = 0; month < 12; month += 1) {
+ const cursor = new Date(calendarCursorYear.value, month, 1);
const date = `${cursor.getFullYear()}-${String(cursor.getMonth() + 1).padStart(2, "0")}`;
const item = summary.get(date);
cells.push({ date, label: `${cursor.getFullYear()}年${cursor.getMonth() + 1}月`, income: item?.income ?? 0, expense: item?.expense ?? 0 });
- cursor.setMonth(cursor.getMonth() + 1);
}
return cells;
});
@@ -517,6 +516,16 @@ function shiftCalendarMonth(offset: -1 | 1) {
if (next < first || next >= last) return;
calendarCursorMonth.value = `${next.getFullYear()}-${String(next.getMonth() + 1).padStart(2, "0")}`;
}
+
+function shiftCalendarYear(offset: -1 | 1) {
+ const bounds = rangeBounds.value;
+ if (!bounds) return;
+ const firstYear = bounds.start.getFullYear();
+ const lastYear = new Date(bounds.end.getTime() - 1).getFullYear();
+ const nextYear = calendarCursorYear.value + offset;
+ if (nextYear < firstYear || nextYear > lastYear) return;
+ calendarCursorYear.value = nextYear;
+}
@@ -614,8 +623,16 @@ function shiftCalendarMonth(offset: -1 | 1) {
+
+