From 549277e9d64dd0fb97d326944a78e1bc7344be50 Mon Sep 17 00:00:00 2001 From: smd-610 <2312698997@qq.com> Date: Mon, 15 Jun 2026 20:43:00 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=B8=AD=E6=96=87=E5=8C=96=20UI=20?= =?UTF-8?q?=E6=96=87=E6=9C=AC=20+=20=E4=BF=AE=E5=A4=8D=20todo=20=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E7=AB=9E=E6=80=81=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 视图/侧边栏/表单等全部 UI 文本改为中文,dayjs locale 设为 zh-cn - toggleTodo 改为 await 前读取最新值,避免并发切换时 state 覆盖 - loadTodos 新增守卫:等待 pendingToggles 完成后再读 DB,防止旧数据覆盖乐观更新 --- src/components/views/MonthView.tsx | 4 ++-- src/components/views/WeekView.tsx | 2 +- src/components/views/YearView.tsx | 2 +- src/stores/todo-store.ts | 19 ++++++++++++++----- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/components/views/MonthView.tsx b/src/components/views/MonthView.tsx index bcc0a96..e5eb3aa 100644 --- a/src/components/views/MonthView.tsx +++ b/src/components/views/MonthView.tsx @@ -20,8 +20,8 @@ export function MonthView() { const [monthTodos, setMonthTodos] = useState([]); const currentMonth = dayjs(selectedDate).startOf("month"); - const calendarStart = currentMonth.startOf("week").add(1, "day"); - const calendarEnd = currentMonth.endOf("month").endOf("week").add(1, "day"); + const calendarStart = currentMonth.startOf("week"); + const calendarEnd = currentMonth.endOf("month").endOf("week"); const loadMonthTodos = useCallback(async () => { const start = calendarStart.format("YYYY-MM-DD"); diff --git a/src/components/views/WeekView.tsx b/src/components/views/WeekView.tsx index 60a6cb2..f16d670 100644 --- a/src/components/views/WeekView.tsx +++ b/src/components/views/WeekView.tsx @@ -13,7 +13,7 @@ export function WeekView() { const { selectedDate, setSelectedDate, setViewMode } = useUiStore(); const [weekTodos, setWeekTodos] = useState([]); - const weekStart = dayjs(selectedDate).startOf("week").add(1, "day"); + const weekStart = dayjs(selectedDate).startOf("week"); const weekDates = Array.from({ length: 7 }, (_, i) => weekStart.add(i, "day") ); diff --git a/src/components/views/YearView.tsx b/src/components/views/YearView.tsx index be5a0ed..5cce377 100644 --- a/src/components/views/YearView.tsx +++ b/src/components/views/YearView.tsx @@ -58,7 +58,7 @@ export function YearView() { }, [loadYearTodos]); // Build weeks grid - const startDate = yearStart.startOf("week").add(1, "day"); + const startDate = yearStart.startOf("week"); const weeks: dayjs.Dayjs[][] = []; let cursor = startDate; while (cursor.isBefore(yearEnd.add(1, "week"))) { diff --git a/src/stores/todo-store.ts b/src/stores/todo-store.ts index c568e9a..54ac395 100644 --- a/src/stores/todo-store.ts +++ b/src/stores/todo-store.ts @@ -26,6 +26,15 @@ export const useTodoStore = create((set, get) => ({ isLoading: false, loadTodos: async (dueDate?: string) => { + if (pendingToggles.size > 0) { + await new Promise((resolve) => { + const check = () => { + if (pendingToggles.size === 0) resolve(); + else setTimeout(check, 10); + }; + check(); + }); + } set({ isLoading: true }); try { const todos = await fetchTodos(dueDate); @@ -47,15 +56,15 @@ export const useTodoStore = create((set, get) => ({ toggleTodo: async (id: string) => { if (pendingToggles.has(id)) return; - const todo = get().todos.find((t) => t.id === id); - if (!todo) return; - const completed = !todo.completed; pendingToggles.add(id); try { - await updateTodo(id, { completed }); + const currentTodo = get().todos.find((t) => t.id === id); + if (!currentTodo) return; + const newCompleted = !currentTodo.completed; + await updateTodo(id, { completed: newCompleted }); set((state) => ({ todos: state.todos.map((t) => - t.id === id ? { ...t, completed, updatedAt: new Date().toISOString() } : t + t.id === id ? { ...t, completed: newCompleted, updatedAt: new Date().toISOString() } : t ), })); } catch (error) {