t1
This commit is contained in:
145
management/src/api.ts
Normal file
145
management/src/api.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
const API_BASE = 'http://127.0.0.1:8080/api';
|
||||
|
||||
export interface ClassItem {
|
||||
rkId: number;
|
||||
name: string;
|
||||
classCode: string;
|
||||
type: string;
|
||||
studentCount: number;
|
||||
specializeRkId?: number;
|
||||
specializeName?: string;
|
||||
systemRkId?: number;
|
||||
systemCode?: string;
|
||||
systemName?: string;
|
||||
isStudying: boolean;
|
||||
courses: { courseRkId: number; courseName: string }[];
|
||||
}
|
||||
|
||||
export interface StudentItem {
|
||||
id: number;
|
||||
rkId: number;
|
||||
studentCode: string;
|
||||
fullName: string;
|
||||
phone?: string;
|
||||
email: string;
|
||||
dateOfBirth?: string;
|
||||
gender?: number;
|
||||
status?: string;
|
||||
location?: string;
|
||||
systemId?: number;
|
||||
systemName?: string;
|
||||
}
|
||||
|
||||
export interface StatsResponse {
|
||||
totalClasses: number;
|
||||
activeClasses: number;
|
||||
totalStudents: number;
|
||||
}
|
||||
|
||||
export interface PaginatedResponse<T> {
|
||||
data: T[];
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
}
|
||||
|
||||
export interface SyncStatus {
|
||||
running: boolean;
|
||||
done: boolean;
|
||||
error?: string;
|
||||
total: number;
|
||||
synced: number;
|
||||
updatedAt: number;
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
}
|
||||
|
||||
export const api = {
|
||||
getStats: async (): Promise<StatsResponse> => {
|
||||
const res = await fetch(`${API_BASE}/stats`);
|
||||
if (!res.ok) throw new Error('Failed to fetch dashboard stats');
|
||||
return res.json();
|
||||
},
|
||||
|
||||
getClasses: async (params: {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
q?: string;
|
||||
systemRkId?: number;
|
||||
studyingOnly?: boolean;
|
||||
}): Promise<PaginatedResponse<ClassItem>> => {
|
||||
const query = new URLSearchParams({
|
||||
page: String(params.page),
|
||||
pageSize: String(params.pageSize),
|
||||
});
|
||||
if (params.q) query.set('q', params.q);
|
||||
if (params.systemRkId) query.set('systemRkId', String(params.systemRkId));
|
||||
if (params.studyingOnly) query.set('studyingOnly', 'true');
|
||||
|
||||
const res = await fetch(`${API_BASE}/classes?${query}`);
|
||||
if (!res.ok) throw new Error('Failed to fetch classes');
|
||||
return res.json();
|
||||
},
|
||||
|
||||
updateClassStudying: async (rkId: number, isStudying: boolean): Promise<any> => {
|
||||
const res = await fetch(`${API_BASE}/classes/${rkId}/studying`, {
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ isStudying }),
|
||||
});
|
||||
if (!res.ok) throw new Error('Failed to update class studying status');
|
||||
return res.json();
|
||||
},
|
||||
|
||||
getClassStudents: async (rkId: number): Promise<{ data: StudentItem[]; total: number }> => {
|
||||
const res = await fetch(`${API_BASE}/classes/${rkId}/students`);
|
||||
if (!res.ok) throw new Error('Failed to fetch class students roster');
|
||||
return res.json();
|
||||
},
|
||||
|
||||
getStudents: async (params: {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
q?: string;
|
||||
}): Promise<PaginatedResponse<StudentItem>> => {
|
||||
const query = new URLSearchParams({
|
||||
page: String(params.page),
|
||||
pageSize: String(params.pageSize),
|
||||
});
|
||||
if (params.q) query.set('q', params.q);
|
||||
|
||||
const res = await fetch(`${API_BASE}/students?${query}`);
|
||||
if (!res.ok) throw new Error('Failed to fetch students');
|
||||
return res.json();
|
||||
},
|
||||
|
||||
startClassesSync: async (): Promise<{ ok: boolean; message: string }> => {
|
||||
const res = await fetch(`${API_BASE}/sync/classes/start`, { method: 'POST' });
|
||||
if (!res.ok) {
|
||||
const errData = await res.json().catch(() => ({}));
|
||||
throw new Error(errData.error || 'Failed to start classes sync');
|
||||
}
|
||||
return res.json();
|
||||
},
|
||||
|
||||
getClassesSyncStatus: async (): Promise<SyncStatus> => {
|
||||
const res = await fetch(`${API_BASE}/sync/classes/status`);
|
||||
if (!res.ok) throw new Error('Failed to get classes sync status');
|
||||
return res.json();
|
||||
},
|
||||
|
||||
startStudentsSync: async (): Promise<{ ok: boolean; message: string }> => {
|
||||
const res = await fetch(`${API_BASE}/sync/students/start`, { method: 'POST' });
|
||||
if (!res.ok) {
|
||||
const errData = await res.json().catch(() => ({}));
|
||||
throw new Error(errData.error || 'Failed to start students sync');
|
||||
}
|
||||
return res.json();
|
||||
},
|
||||
|
||||
getStudentsSyncStatus: async (): Promise<SyncStatus> => {
|
||||
const res = await fetch(`${API_BASE}/sync/students/status`);
|
||||
if (!res.ok) throw new Error('Failed to get students sync status');
|
||||
return res.json();
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user