import type { AdminStats, Course, CourseStatus, User } from './types' const token = () => localStorage.getItem('xinghen_token') async function request(path: string, init: RequestInit = {}): Promise { const headers = new Headers(init.headers) if (token()) headers.set('Authorization', `Bearer ${token()}`) const response = await fetch(`/api${path}`, { ...init, headers }) if (!response.ok) { const body = await response.json().catch(() => ({ message: '请求失败,请稍后重试' })) if (response.status === 401) { localStorage.removeItem('xinghen_token') window.dispatchEvent(new Event('auth-expired')) } throw new Error(body.message || '请求失败,请稍后重试') } return response.json() as Promise } export const api = { // 用户鉴权与信息 register: (phone: string, password: string) => request<{ token: string; user: User }>('/auth/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ phone, password }) }), login: (phone: string, password: string) => request<{ token: string; user: User }>('/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ phone, password }) }), logout: () => request<{ ok: boolean }>('/auth/logout', { method: 'POST' }), me: () => request<{ user: User }>('/me'), updateMe: (body: Pick) => request<{ user: User }>('/me', { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }), changePassword: (currentPassword: string, newPassword: string) => request<{ ok: boolean }>('/me/password', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ currentPassword, newPassword }) }), // 普通用户课程操作 listCourses: () => request<{ courses: Course[] }>('/courses'), createCourse: (body: Pick) => request<{ course: Course }>('/courses', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }), getCourse: (id: string) => request<{ course: Course }>(`/courses/${id}`), uploadAssets: (id: string, files: File[]) => { const form = new FormData() files.forEach((f) => form.append('assets', f)) return request<{ course: Course }>(`/courses/${id}/assets`, { method: 'POST', body: form }) }, deleteAsset: (id: string, assetId: string) => request<{ course: Course }>(`/courses/${id}/assets/${assetId}`, { method: 'DELETE' }), addInstructor: ( id: string, data: { name: string; organization: string; introduction: string; image?: File } ) => { const f = new FormData() f.append('name', data.name) f.append('organization', data.organization) f.append('introduction', data.introduction) if (data.image) f.append('image', data.image) return request<{ course: Course }>(`/courses/${id}/instructors`, { method: 'POST', body: f }) }, deleteInstructor: (id: string, instructorId: string) => request<{ course: Course }>(`/courses/${id}/instructors/${instructorId}`, { method: 'DELETE' }), submitCourse: (id: string) => request<{ course: Course }>(`/courses/${id}/submit`, { method: 'POST' }), // 管理员后台专区 API admin: { login: (phone: string, password: string) => request<{ token: string; user: User }>('/admin/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ phone, password }) }), getStats: () => request('/admin/stats'), listCourses: (params?: { status?: string; keyword?: string }) => { const q = new URLSearchParams() if (params?.status) q.set('status', params.status) if (params?.keyword) q.set('keyword', params.keyword) const qs = q.toString() ? `?${q.toString()}` : '' return request<{ courses: Course[]; total: number }>(`/admin/courses${qs}`) }, getCourse: (id: string) => request<{ course: Course }>(`/admin/courses/${id}`), updateStatus: (id: string, status: CourseStatus) => request<{ course: Course }>(`/admin/courses/${id}/status`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status }) }), uploadDeliverables: (id: string, files: File[]) => { const form = new FormData() files.forEach((f) => form.append('deliverables', f)) return request<{ course: Course }>(`/admin/courses/${id}/deliverables`, { method: 'POST', body: form }) }, deleteDeliverable: (id: string, delivId: string) => request<{ course: Course }>(`/admin/courses/${id}/deliverables/${delivId}`, { method: 'DELETE' }), completeCourse: (id: string, productionNotes: string) => request<{ course: Course }>(`/admin/courses/${id}/complete`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ productionNotes }) }), listUsers: (keyword?: string) => { const qs = keyword ? `?keyword=${encodeURIComponent(keyword)}` : '' return request<{ users: User[] }>(`/admin/users${qs}`) }, updateUserRole: (id: string, role: 'USER' | 'ADMIN') => request<{ user: User }>(`/admin/users/${id}/role`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ role }) }) } }