feat: 集成 AI 对话与只读查询工具
This commit is contained in:
@@ -36,5 +36,6 @@ import { DashboardController } from './dashboard.controller';
|
||||
],
|
||||
controllers: [DashboardController],
|
||||
providers: [DashboardService],
|
||||
exports: [DashboardService],
|
||||
})
|
||||
export class DashboardModule {}
|
||||
|
||||
@@ -15,6 +15,11 @@ import { ClassroomRental } from '../entities/classroom-rental.entity';
|
||||
import { ClassTeacher } from '../entities/class-teacher.entity';
|
||||
import { ClassStudent } from '../entities/class-student.entity';
|
||||
|
||||
interface AgentAttendanceStatusRow {
|
||||
status: string;
|
||||
count: string | number;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class DashboardService {
|
||||
constructor(
|
||||
@@ -39,6 +44,32 @@ export class DashboardService {
|
||||
return [...new Set(assignments.map((assignment) => assignment.classId))];
|
||||
}
|
||||
|
||||
async agentGetDashboardStats(userId: number, canManageAll: boolean) {
|
||||
const accessibleClassIds = await this.getAccessibleClassIds(userId, canManageAll);
|
||||
const today = this.getChinaDate(new Date());
|
||||
const totalStudents = accessibleClassIds
|
||||
? await this.countStudentsInClasses(accessibleClassIds)
|
||||
: await this.studentRepo.count({ where: { status: 'active' } });
|
||||
const classCount = accessibleClassIds ? accessibleClassIds.length : await this.classRepo.count({ where: { isArchived: false } });
|
||||
const attendanceQb = this.attendanceRepo
|
||||
.createQueryBuilder('attendance')
|
||||
.select('attendance.status', 'status')
|
||||
.addSelect('COUNT(attendance.id)', 'count')
|
||||
.where('attendance.attendanceDate = :today', { today });
|
||||
this.applyClassScope(attendanceQb, 'attendance', accessibleClassIds);
|
||||
const rows = await attendanceQb.groupBy('attendance.status').getRawMany<AgentAttendanceStatusRow>();
|
||||
const attendanceByStatus = rows.reduce((result, row) => {
|
||||
result[String(row.status)] = Number(row.count || 0);
|
||||
return result;
|
||||
}, {} as Record<string, number>);
|
||||
const attendanceTotal = Object.values(attendanceByStatus).reduce<number>(
|
||||
(sum, count) => sum + Number(count),
|
||||
0,
|
||||
);
|
||||
const present = attendanceByStatus.present ?? 0;
|
||||
return { date: today, totalStudents, classCount, attendanceTotal, present, attendanceRate: attendanceTotal ? Number(((present / attendanceTotal) * 100).toFixed(1)) : 0, attendanceByStatus };
|
||||
}
|
||||
|
||||
async getStats(accessibleClassIds?: number[]) {
|
||||
const todayStr = this.getChinaDate(new Date());
|
||||
const currentMonth = todayStr.slice(0, 7); // YYYY-MM
|
||||
|
||||
Reference in New Issue
Block a user