Files
gongxue-base/apps/server/src/attendance/attendance-time.ts
wangziqi c6e1d94510
All checks were successful
CI / check (pull_request) Successful in 4m11s
Dependency Check / check (pull_request) Successful in 2m30s
fix: 修复 CI 时区测试失败 + 依赖安全升级 + 新增依赖检查 workflow
- fix(server): getCourseClock 固定 UTC+8(Asia/Shanghai),与 attendance-settlement 保持一致,
  修复 CI(UTC 容器)下 attendance.lesson-session.spec.ts 失败
- chore(deps): @ant-design/x 2.9.0 / @ant-design/x-markdown 2.9.0 / mermaid 11.16.1;
  直接依赖 dompurify 3.4.13(修复生产依赖 audit 漏洞,mermaid/x-markdown 复用同一份)
- ci: 新增 dependency-check workflow(生产依赖 moderate+ / 全局 critical 失败,outdated 报告)
2026-08-10 10:05:05 +08:00

44 lines
1.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import dayjs from '../common/dayjs';
export function toMinutes(time: string): number {
const [hour, minute] = time.split(':').map(Number);
return hour * 60 + minute;
}
export function getCourseClock(date: Date): { date: string; minutes: number } {
// Asia/Shanghai 无夏令时,固定 UTC+8与 attendance-settlement 保持一致),
// 避免依赖服务器进程时区导致「课程是否已开始」判断漂移。
const d = dayjs(date).utcOffset(8);
return {
date: d.format('YYYY-MM-DD'),
minutes: d.hour() * 60 + d.minute(),
};
}
export function shiftDate(date: string, days: number): string {
return dayjs.utc(`${date}T00:00:00.000Z`).add(days, 'day').format('YYYY-MM-DD');
}
export function mapLessonScheduleTimeToSession(startTime: string): string {
const hour = parseInt(startTime.slice(0, 2), 10);
if (hour < 8) return 'morning_reading';
if (hour < 12) return 'morning';
if (hour < 17) return 'afternoon';
if (hour < 20) return 'evening_study';
return 'night_check';
}
export function isClassStudentActiveOnDate(
classStudent: Pick<
import('../entities/class-student.entity').ClassStudent,
'joinDate' | 'leaveDate' | 'status'
>,
lessonDate: string,
): boolean {
const status = classStudent.status ?? 'active';
if (!['active', 'left'].includes(status)) return false;
if (classStudent.joinDate && classStudent.joinDate > lessonDate) return false;
if (classStudent.leaveDate && classStudent.leaveDate < lessonDate) return false;
return true;
}