// src/api/admin.ts import { api } from './apiClient'; export type PracticeLevel = 'keyword' | 'basic' | 'intermediate' | 'advanced'; export interface User { _id: string; username: string; email: string; fullname: string; isAdmin: boolean; createdAt: string; status?: string; } export interface CodeExample { _id: string; title: string; content: string; level: PracticeLevel; description?: string; difficulty?: number; createdAt?: Date; updatedAt?: Date; } export interface UserUpdateData extends Partial { password?: string; // 添加可选的密码字段 } export interface CreateUserData { username: string; email: string; fullname: string; password: string; isAdmin?: boolean; } // 添加练习记录相关的接口 export interface PracticeRecord { _id: string; userId: string; username: string; fullname: string; type: string; stats: { totalWords: number; correctWords: number; accuracy: number; wordsPerMinute: number; startTime: string; endTime: string; duration: number; }; createdAt: string; } // 添加 OAuth2Client 接口 export interface OAuth2Client { _id: string; clientId: string; clientSecret: string; name: string; redirectUris: string[]; grants: string[]; scope: string[]; createdAt: string; updatedAt?: Date; } export interface CreateOAuth2ClientData { name: string; redirectUris: string[]; scope: string; } // 添加词汇相关接口 export interface WordSet { _id: string; name: string; description?: string; totalWords: number; createdAt: string; owner: { _id: string; username: string; fullname: string; }; } export interface Word { _id: string; word: string; translation: string; pronunciation?: string; example?: string; wordSet: string; createdAt: string; } export interface VocabularyPassSummaryItem { userId: string; username: string; fullname: string; email?: string; passedWords: number; uniqueWords: number; testRecords: number; totalRecords?: number; validRecords?: number; invalidatedRecords?: number; wordSets: number; testTypes: string[]; riskFlags?: string[]; firstPassedAt: string; lastPassedAt: string; firstRecordAt?: string; lastRecordAt?: string; } export interface VocabularyPassSummaryResponse { start: string; end: string; totalStudents: number; totalPassedWords: number; totalRecords?: number; invalidatedRecords?: number; items: VocabularyPassSummaryItem[]; } export interface VocabularyAuditQueryParams { start: string; end: string; studentNo?: string; minUniqueWords?: string; } export interface ClearVocabularyPassSummaryResponse { message: string; userId?: string; username?: string; fullname?: string; deletedRecords: number; removedPassedWords: number; affectedWords: number; rebuiltWords: number; } export interface VocabularyAuditWordBrief { _id: string; word?: string; translation?: string; pronunciation?: string; example?: string; } export interface VocabularyAuditUserBrief { _id?: string; userId?: string; username?: string; fullname?: string; email?: string; } export interface VocabularyAuditInteractionSummary { keyCount: number; inputCount: number; pasteCount: number; focusCount: number; blurCount: number; pointerCount: number; firstEventOffset: number; lastEventOffset: number; } export interface VocabularyAuditResultDetail { index: number; wordId: string; word: VocabularyAuditWordBrief | null; userAnswer: string; correctAnswer: string; isCorrect: boolean; } export interface VocabularyAuditAnswerDetail extends VocabularyAuditResultDetail { questionToken: string; submittedAt?: string; duration?: number; riskFlags: string[]; interactionSummary?: VocabularyAuditInteractionSummary | null; } export interface VocabularyAuditAttemptDetail { attemptId: string; status: string; testType: string; wordSetId: string; issuedAt?: string; expiresAt?: string; submittedAt?: string; riskFlags: string[]; reviewDecision?: string; reviewedAt?: string; reviewedBy?: VocabularyAuditUserBrief | null; reviewNote?: string; questionWordIds: string[]; questionTokens: string[]; optionTokens: string[][]; optionTexts: string[][]; answeredQuestionTokens: string[]; answerDurations: number[]; answers: VocabularyAuditAnswerDetail[]; } export interface VocabularyAuditRecordDetail { recordId: string; attemptId: string; wordSet: { _id: string; name?: string; description?: string; } | null; testType: string; stats: { totalWords: number; correctWords: number; accuracy: number; startTime: string; endTime: string; duration: number; }; invalidated: boolean; riskFlags: string[]; reviewDecision?: string; reviewedAt?: string; reviewedBy?: VocabularyAuditUserBrief | null; reviewNote?: string; createdAt: string; results: VocabularyAuditResultDetail[]; attempt: VocabularyAuditAttemptDetail | null; } export interface VocabularyPassSummaryDetailsResponse { start: string; end: string; user: VocabularyAuditUserBrief; totalRecords: number; totalPassedWords: number; invalidatedRecords: number; approvedRecords: number; records: VocabularyAuditRecordDetail[]; } export interface ApproveVocabularyTestRecordResponse { message: string; recordId: string; attemptId?: string; totalWords?: number; correctWords?: number; accuracy?: number; riskFlags?: string[]; affectedWords?: number; rebuiltWords?: number; alreadyEffective?: boolean; } export const adminApi = { getUsers: async (): Promise => { return api.get('/admin/users'); }, createUser: async (userData: CreateUserData): Promise => { return api.post('/admin/users', userData); }, updateUser: async (userId: string, userData: Partial): Promise => { return api.put(`/admin/users/${userId}`, userData); }, deleteUser: async (userId: string): Promise => { await api.delete(`/admin/users/${userId}`); }, // Code example methods getCodeExamples: async (): Promise => { return api.get('/code-examples'); }, createCodeExample: async (codeData: Omit): Promise => { return api.post('/code-examples', codeData); }, updateCodeExample: async (id: string, codeData: Partial): Promise => { return api.put(`/code-examples/${id}`, codeData); }, deleteCodeExample: async (id: string): Promise => { await api.delete(`/code-examples/${id}`); }, // 获取所有练习记录 getPracticeRecords: async (params?: { date?: string; userId?: string }): Promise => { return api.get('/practice-records/all', { params }); }, // OAuth2 相关方法 getOAuth2Clients: async (): Promise => { return api.get('/admin/oauth2/clients'); }, createOAuth2Client: async (data: CreateOAuth2ClientData): Promise => { return api.post('/admin/oauth2/clients', data); }, updateOAuth2Client: async (id: string, clientData: Partial): Promise => { return api.put(`/admin/oauth2/clients/${id}`, clientData); }, deleteOAuth2Client: async (id: string): Promise => { await api.delete(`/admin/oauth2/clients/${id}`); }, // 词汇管理相关方法 getVocabularyWordSets: async (): Promise => { return api.get('/admin/vocabulary/word-sets'); }, getVocabularyWordSetDetails: async (id: string): Promise<{ wordSet: WordSet, words: Word[] }> => { return api.get<{ wordSet: WordSet, words: Word[] }>(`/admin/vocabulary/word-sets/${id}/words`); }, uploadVocabularyFile: async (formData: FormData): Promise<{ message: string, wordSet: WordSet }> => { return api.post<{ message: string, wordSet: WordSet }>('/admin/vocabulary/upload', formData, { headers: { 'Content-Type': 'multipart/form-data', }, }); }, deleteVocabularyWordSet: async (id: string): Promise<{ message: string }> => { return api.delete<{ message: string }>(`/admin/vocabulary/word-sets/${id}`); }, // 获取单词集单词的方法 getWordsByWordSetId: async (wordSetId: string) => { return api.get(`/vocabulary/word-set/${wordSetId}/words`); }, // 更新单词的方法 updateWords: async (words: any[]) => { return api.put('/api/vocabulary/words', { words }); }, getVocabularyPassSummary: async (params: VocabularyAuditQueryParams): Promise => { return api.get('/admin/vocabulary/test-pass-summary', { params }); }, clearVocabularyPassSummary: async (data: { userId: string; start: string; end: string; studentNo?: string; minUniqueWords?: string }): Promise => { return api.post('/admin/vocabulary/test-pass-summary/clear', data); }, getVocabularyPassSummaryDetails: async (params: { userId: string } & VocabularyAuditQueryParams): Promise => { const { userId, ...query } = params; return api.get(`/admin/vocabulary/test-pass-summary/${userId}/details`, { params: query }); }, approveVocabularyTestRecord: async (recordId: string, data: { note?: string } = {}): Promise => { return api.post(`/admin/vocabulary/test-records/${recordId}/approve`, data); }, };