From 7905f1ee23b2e41422ec6efb56f9fbd723b5d506 Mon Sep 17 00:00:00 2001 From: wangziqi Date: Sat, 8 Aug 2026 17:58:16 +0800 Subject: [PATCH] =?UTF-8?q?fix(server):=20=E4=B8=9A=E5=8A=A1=E6=97=A5?= =?UTF-8?q?=E6=9C=9F'=E4=BB=8A=E5=A4=A9'=E7=BB=9F=E4=B8=80=E4=B8=BA?= =?UTF-8?q?=E4=B8=AD=E5=9B=BD=E6=97=A5=E6=9C=9F=EF=BC=8C=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E5=87=8C=E6=99=A8=20UTC=20=E5=81=8F=E4=B8=80=E5=A4=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit joinDate/leaveDate/checkInDate/sync 起始日等业务日期默认值原来用 dayjs().utc()(UTC 今天),在国内 00:00-07:59 会取到昨天。 统一改为 dayjs().utcOffset(8)(固定 UTC+8 中国日期),与考勤周边界 修复保持一致;pending-tasks/controller-base 的本地 dayjs() 也显式化。 --- apps/server/src/agent-context/pending-tasks.service.ts | 4 ++-- apps/server/src/ai-chat/ai-review.import-relations.ts | 2 +- apps/server/src/attendance/attendance.controller-base.ts | 2 +- apps/server/src/classes/classes-queries.service.ts | 2 +- apps/server/src/classes/classes.service.ts | 6 +++--- apps/server/src/occupancies/occupancy-import.service.ts | 2 +- apps/server/src/sync/schedule-sync.service.ts | 2 +- apps/server/src/sync/sync.service.ts | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/server/src/agent-context/pending-tasks.service.ts b/apps/server/src/agent-context/pending-tasks.service.ts index c8f34de..9593a50 100644 --- a/apps/server/src/agent-context/pending-tasks.service.ts +++ b/apps/server/src/agent-context/pending-tasks.service.ts @@ -56,11 +56,11 @@ function teacherScopedCountSql(sql: (scope: StudentAccessScope) => string): SqlB } function today(): string { - return dayjs().format('YYYY-MM-DD'); + return dayjs().utcOffset(8).format('YYYY-MM-DD'); } function inDays(days: number): string { - return dayjs().add(days, 'day').format('YYYY-MM-DD'); + return dayjs().utcOffset(8).add(days, 'day').format('YYYY-MM-DD'); } const TASKS: readonly TaskDefinition[] = [ diff --git a/apps/server/src/ai-chat/ai-review.import-relations.ts b/apps/server/src/ai-chat/ai-review.import-relations.ts index ea6c334..de66653 100644 --- a/apps/server/src/ai-chat/ai-review.import-relations.ts +++ b/apps/server/src/ai-chat/ai-review.import-relations.ts @@ -250,7 +250,7 @@ async function importCheckins( continue; } - const checkInDate = toDateString(row.checkInDate) ?? dayjs().utc().format('YYYY-MM-DD'); + const checkInDate = toDateString(row.checkInDate) ?? dayjs().utcOffset(8).format('YYYY-MM-DD'); const billingStartDate = toDateString(row.billingStartDate) ?? checkInDate; const checkOutDate = toDateString(row.checkOutDate); const isHistoricalRecord = Boolean(checkOutDate); diff --git a/apps/server/src/attendance/attendance.controller-base.ts b/apps/server/src/attendance/attendance.controller-base.ts index ea77673..8eb0233 100644 --- a/apps/server/src/attendance/attendance.controller-base.ts +++ b/apps/server/src/attendance/attendance.controller-base.ts @@ -33,7 +33,7 @@ export abstract class AttendanceControllerBase { ) {} protected getTodayDateOnly(): string { - return dayjs().format('YYYY-MM-DD'); + return dayjs().utcOffset(8).format('YYYY-MM-DD'); } protected canManageAllAttendance(req: { user: RequestUser }): boolean { diff --git a/apps/server/src/classes/classes-queries.service.ts b/apps/server/src/classes/classes-queries.service.ts index fcd93a6..50c42ca 100644 --- a/apps/server/src/classes/classes-queries.service.ts +++ b/apps/server/src/classes/classes-queries.service.ts @@ -81,7 +81,7 @@ export class ClassesQueriesService { const existingByStudentId = new Map( existingClassStudents.map((classStudent) => [classStudent.studentId, classStudent]), ); - const today = dayjs().utc().format('YYYY-MM-DD'); + const today = dayjs().utcOffset(8).format('YYYY-MM-DD'); let skipped = 0; const memberships = studentIds.flatMap((studentId) => { const existing = existingByStudentId.get(studentId); diff --git a/apps/server/src/classes/classes.service.ts b/apps/server/src/classes/classes.service.ts index 152e485..0508438 100644 --- a/apps/server/src/classes/classes.service.ts +++ b/apps/server/src/classes/classes.service.ts @@ -185,7 +185,7 @@ export class ClassesService { this.classStudentRepo.create({ classId: saved.id, studentId: sid, - joinDate: dayjs().utc().format('YYYY-MM-DD'), + joinDate: dayjs().utcOffset(8).format('YYYY-MM-DD'), }), ); await this.classStudentRepo.save(entries); @@ -306,7 +306,7 @@ export class ClassesService { const existingByStudentId = new Map( existing.map((classStudent) => [classStudent.studentId, classStudent]), ); - const today = dayjs().utc().format('YYYY-MM-DD'); + const today = dayjs().utcOffset(8).format('YYYY-MM-DD'); let skipped = 0; const memberships = uniqueStudentIds.flatMap((studentId) => { const current = existingByStudentId.get(studentId); @@ -342,7 +342,7 @@ export class ClassesService { if (membership.status !== 'active') throw new BadRequestException('学生已离班'); membership.status = 'left'; - membership.leaveDate = dayjs().utc().format('YYYY-MM-DD'); + membership.leaveDate = dayjs().utcOffset(8).format('YYYY-MM-DD'); await this.classStudentRepo.save(membership); return { success: true }; } diff --git a/apps/server/src/occupancies/occupancy-import.service.ts b/apps/server/src/occupancies/occupancy-import.service.ts index b6eea7e..8723378 100644 --- a/apps/server/src/occupancies/occupancy-import.service.ts +++ b/apps/server/src/occupancies/occupancy-import.service.ts @@ -133,7 +133,7 @@ export class OccupancyImportService { ); } - const checkInDate = row.checkInDate?.trim() || dayjs().utc().format('YYYY-MM-DD'); + const checkInDate = row.checkInDate?.trim() || dayjs().utcOffset(8).format('YYYY-MM-DD'); const checkOutDate = row.checkOutDate?.trim(); const billingStartDate = row.billingStartDate?.trim() || checkInDate; const isHistoricalRecord = Boolean(checkOutDate); diff --git a/apps/server/src/sync/schedule-sync.service.ts b/apps/server/src/sync/schedule-sync.service.ts index 8fa3f8c..837b311 100644 --- a/apps/server/src/sync/schedule-sync.service.ts +++ b/apps/server/src/sync/schedule-sync.service.ts @@ -46,7 +46,7 @@ export class ScheduleSyncService { opUserId = 'manager', attendanceMachineOnly = false, ): Promise { - const startDate = dateFrom || dayjs().utc().format('YYYY-MM-DD'); + const startDate = dateFrom || dayjs().utcOffset(8).format('YYYY-MM-DD'); const normalizedDays = Number.isFinite(days) ? Math.max(1, Math.floor(days)) : 30; const endDate = addDays(startDate, normalizedDays - 1); diff --git a/apps/server/src/sync/sync.service.ts b/apps/server/src/sync/sync.service.ts index ed6ed2f..e1bf143 100644 --- a/apps/server/src/sync/sync.service.ts +++ b/apps/server/src/sync/sync.service.ts @@ -305,7 +305,7 @@ export class SyncService { } async getScheduleSyncStatus(date?: string) { - return this.scheduleSyncService.getStatus(date || dayjs().utc().format('YYYY-MM-DD')); + return this.scheduleSyncService.getStatus(date || dayjs().utcOffset(8).format('YYYY-MM-DD')); } /**