import axios from 'axios'; import type { WorkGroup, UserItem, UserDetail, ActivityItem, Participant, HoursActivityResult, ExportResult, } from '../types'; const api = axios.create({ baseURL: '/api', timeout: 15000, }); api.interceptors.request.use((config) => { const token = localStorage.getItem('volunteer_admin_token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }); api.interceptors.response.use( (res) => res, (err) => { if (err.response?.status === 401) { localStorage.removeItem('volunteer_admin_token'); localStorage.removeItem('volunteer_admin_username'); if (!window.location.pathname.startsWith('/admin/login')) { window.location.href = '/admin/login'; } } return Promise.reject(err); } ); export const errMsg = (e: any, def = '操作失败'): string => { return e?.response?.data?.error || e?.message || def; }; export default api; export const authApi = { login: (username: string, password: string) => api.post<{ token: string; username: string }>('/auth/login', { username, password }).then(r => r.data), changePassword: (oldPassword: string, newPassword: string) => api.post('/auth/change-password', { oldPassword, newPassword }).then(r => r.data), }; export const groupsApi = { list: () => api.get('/groups').then(r => r.data), create: (name: string) => api.post('/groups', { name }).then(r => r.data), update: (id: number, name: string) => api.put(`/groups/${id}`, { name }).then(r => r.data), remove: (id: number) => api.delete(`/groups/${id}`).then(r => r.data), }; export const usersApi = { list: () => api.get('/users').then(r => r.data), search: (name: string) => api.get('/users/search', { params: { name } }).then(r => r.data), detail: (id: number) => api.get(`/users/${id}`).then(r => r.data), create: (data: Partial) => api.post('/users', data).then(r => r.data), update: (id: number, data: Partial) => api.put(`/users/${id}`, data).then(r => r.data), remove: (id: number) => api.delete(`/users/${id}`).then(r => r.data), }; export const activitiesApi = { list: () => api.get('/activities').then(r => r.data), detail: (id: number) => api.get(`/activities/${id}`).then(r => r.data), create: (data: any) => api.post('/activities', data).then(r => r.data), update: (id: number, data: any) => api.put(`/activities/${id}`, data).then(r => r.data), remove: (id: number) => api.delete(`/activities/${id}`).then(r => r.data), participants: (id: number) => api.get<{ activity: ActivityItem; list: Participant[] }>(`/activities/${id}/participants`).then(r => r.data), }; export const hoursApi = { batch: (activity_id: number, items: Array<{ user_id: number; hours: number; remark: string }>) => api.post('/hours/batch', { activity_id, items }).then(r => r.data), byActivity: (id: number) => api.get(`/hours/activity/${id}`).then(r => r.data), }; export const exportApi = { data: (opts: { include_users?: boolean; include_activities?: boolean; include_hours?: boolean; include_user_totals?: boolean; include_user_activities?: boolean; }) => api.post('/export', opts).then(r => r.data), };