// export const API_BASE = 'http://localhost:8081/api' export const API_BASE = '/api' // 通用请求头配置 export const getAuthHeaders = () => { const token = localStorage.getItem('token') return { 'Content-Type': 'application/json', ...(token ? { Authorization: `Bearer ${token}` } : {}) } } // 认证相关类型 export interface User { id: number username: string email: string role: string isActive: number createdAt: string updatedAt: string } export interface LoginRequest { username: string password: string } export interface LoginResponse { token: string user: User expire: number } // 角色相关类型 export interface Role { id: number name: string description: string createdAt: string updatedAt: string } // 作品相关类型 export interface Work { id: string title: string category: string year: string heroImg: string desc: string techStack: { category: string; items: string[] }[] gallery: string[] links: { live?: string; github?: string; demo?: string } next: string } // 分类相关类型 export interface Category { id: number name: string slug: string description: string sortOrder: number createdAt: string updatedAt: string } // 专栏相关类型 export interface Column { id: number name: string description: string cover: string isActive: number sortOrder: number createdAt: string updatedAt: string } // 标签相关类型 export interface Tag { id: number name: string slug: string createdAt: string updatedAt: string } // 文章相关类型 export interface Post { id: number title: string categoryId: number categoryName?: string // Display name categorySlug?: string category?: Category // Optional full object columnId?: number | null columnName?: string tags?: Tag[] date: string excerpt?: string content?: string isPublished?: number readCount?: number } export interface PostHistory { id: number postId: number version: number title: string categoryId: number excerpt?: string content: string isPublished: number modifiedBy: number modifiedAt: string createdAt: string } // 代码片段相关类型 export interface Snippet { id: string title: string code: string type: string description?: string viewCount?: number } // 系统配置相关类型 export interface Setting { id: number keyName: string value: string description: string createdAt: string updatedAt: string } // 操作日志相关类型 export interface OperationLog { id: number userId: number username: string ip: string path: string method: string params: string status: number duration: number createdAt: string } // 分页响应类型 export interface PaginationResponse { list: T[] total: number page: number size: number } // 登录API export const login = async (credentials: LoginRequest): Promise => { try { const response = await fetch(`${API_BASE}/admin/login`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(credentials), }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '登录失败') } const data = await response.json() const result = data.result as { token: string; user: User } return { token: result.token, user: result.user, expire: 24 * 60 * 60 * 1000 // 24小时 } } catch (error) { console.error('Login error:', error) throw error } } // 用户管理API export const getUsers = async (): Promise => { try { const response = await fetch(`${API_BASE}/admin/users`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取用户列表失败') } const data = await response.json() // 后端返回的是分页格式 {list, total, page, size},需要从 result.list 中取值 return (data.result?.list || []) as User[] } catch (error) { console.error('Get users error:', error) throw error } } export const fetchUser = async (id: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/users/${id}`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取用户详情失败') } const data = await response.json() return data.result } catch (error) { console.error(`Error fetching user ${id}:`, error) throw error } } export const createUser = async (userData: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/users`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(userData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '创建用户失败') } } catch (error) { console.error('Create user error:', error) throw error } } export const updateUser = async (id: number, userData: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/users/${id}`, { method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(userData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '更新用户失败') } } catch (error) { console.error('Update user error:', error) throw error } } export const deleteUser = async (id: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/users/${id}`, { method: 'DELETE', headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '删除用户失败') } } catch (error) { console.error('Delete user error:', error) throw error } } // 角色管理API export const getRoles = async (): Promise => { try { const response = await fetch(`${API_BASE}/admin/roles`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取角色列表失败') } const data = await response.json() return data.result || [] } catch (error) { console.error('Get roles error:', error) throw error } } export const createRole = async (roleData: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/roles`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(roleData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '创建角色失败') } } catch (error) { console.error('Create role error:', error) throw error } } export const updateRole = async (id: number, roleData: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/roles/${id}`, { method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(roleData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '更新角色失败') } } catch (error) { console.error('Update role error:', error) throw error } } export const deleteRole = async (id: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/roles/${id}`, { method: 'DELETE', headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '删除角色失败') } } catch (error) { console.error('Delete role error:', error) throw error } } export const fetchRole = async (id: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/roles/${id}`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取角色详情失败') } const data = await response.json() return data.result } catch (error) { console.error(`Error fetching role ${id}:`, error) throw error } } // 作品管理API export const getAdminWorks = async (): Promise => { try { const response = await fetch(`${API_BASE}/admin/works`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取作品列表失败') } const data = await response.json() // 后端返回的是分页格式 {list, total, page, size},需要从 result.list 中取值 // 确保始终返回数组,即使 result 或 result.list 为 null/undefined const list = data.result?.list return (list && Array.isArray(list)) ? list : [] } catch (error) { console.error('Get admin works error:', error) throw error } } export const fetchWorks = async (): Promise => { try { const response = await fetch(`${API_BASE}/works`) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || 'Failed to fetch works') } const data = await response.json() // 确保从 result 字段取值,并确保始终返回数组 const result = data.result if (!result) { return [] } if (!Array.isArray(result)) { return [] } // 确保每个 work 对象的字段格式正确 return result.map((work: any) => ({ id: work.id || '', title: work.title || '', category: work.category || '', year: work.year || '', heroImg: work.heroImg || '', desc: work.desc || '', techStack: Array.isArray(work.techStack) ? work.techStack : [], gallery: Array.isArray(work.gallery) ? work.gallery : [], links: work.links || {}, next: work.next || '' })) as Work[] } catch (error) { console.error('Error fetching works:', error) return [] } } export const fetchWork = async (id: string): Promise => { try { const response = await fetch(`${API_BASE}/works/${id}`) if (!response.ok) throw new Error('Failed to fetch work') const data = await response.json() // 确保从 result 字段取值 const result = data.result as Work if (!result) { throw new Error('Work not found') } // 确保 techStack 和 gallery 始终是数组 if (!Array.isArray(result.techStack)) { result.techStack = [] } if (!Array.isArray(result.gallery)) { result.gallery = [] } return result } catch (error) { console.error(`Error fetching work ${id}:`, error) return { id: 'default', title: '默认作品', category: '默认分类', year: '2024', heroImg: '', desc: '', techStack: [], gallery: [], links: {}, next: '' } } } export const createWork = async (workData: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/works`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(workData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '创建作品失败') } } catch (error) { console.error('Create work error:', error) throw error } } export const updateWork = async (id: string, workData: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/works/${id}`, { method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(workData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '更新作品失败') } } catch (error) { console.error('Update work error:', error) throw error } } export const deleteWork = async (id: string): Promise => { try { const response = await fetch(`${API_BASE}/admin/works/${id}`, { method: 'DELETE', headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '删除作品失败') } } catch (error) { console.error('Delete work error:', error) throw error } } // 文章管理API export const getAdminPosts = async (): Promise> => { try { const response = await fetch(`${API_BASE}/admin/posts?pageSize=1000`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取文章列表失败') } const data = await response.json() return data.result } catch (error) { console.error('Get admin posts error:', error) throw error } } export const fetchPosts = async (query?: string, categoryId?: number, tagId?: number, columnId?: number): Promise => { try { let url = `${API_BASE}/posts` const params = new URLSearchParams() if (query) params.append('q', query) if (categoryId) params.append('category', categoryId.toString()) if (tagId) params.append('tag', tagId.toString()) if (columnId) params.append('column', columnId.toString()) if (params.toString()) { url += `?${params.toString()}` } const response = await fetch(url) if (!response.ok) throw new Error('Failed to fetch posts') const data = await response.json() return data.result || [] } catch (error) { console.error('Error fetching posts:', error) return [] } } export const fetchPost = async (id: number | string): Promise => { try { const response = await fetch(`${API_BASE}/posts/${id}`) if (!response.ok) throw new Error('Failed to fetch post') const data = await response.json() return data.result } catch (error) { console.error(`Error fetching post ${id}:`, error) // Return empty fallback return { id: Number(id), title: '未知文章', categoryId: 0, date: '2024-01-01' } } } export const createPost = async (postData: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/posts`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(postData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '创建文章失败') } } catch (error) { console.error('Create post error:', error) throw error } } export const updatePost = async (id: number | string, postData: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/posts/${id}`, { method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(postData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '更新文章失败') } } catch (error) { console.error('Update post error:', error) throw error } } export const togglePostStatus = async (id: number, isPublished: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/posts/${id}/status`, { method: 'PATCH', headers: getAuthHeaders(), body: JSON.stringify({ isPublished }) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '更新状态失败') } } catch (error) { console.error('Toggle post status error:', error) throw error } } export const deletePost = async (id: number | string): Promise => { try { const response = await fetch(`${API_BASE}/admin/posts/${id}`, { method: 'DELETE', headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '删除文章失败') } } catch (error) { console.error('Delete post error:', error) throw error } } // 分类管理API export const fetchCategories = async (): Promise => { try { const response = await fetch(`${API_BASE}/categories`) if (!response.ok) throw new Error('Failed to fetch categories') const data = await response.json() return data.result || [] } catch (error) { console.error('Fetch categories error:', error) return [] } } export const getAdminCategories = async (): Promise => { try { const response = await fetch(`${API_BASE}/admin/categories`, { headers: getAuthHeaders() }) if (!response.ok) throw new Error('Failed to fetch admin categories') const data = await response.json() return data.result || [] } catch (error) { console.error('Get admin categories error:', error) throw error } } export const createCategory = async (data: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/categories`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(data) }) if (!response.ok) throw new Error('Create category failed') } catch (error) { throw error } } export const updateCategory = async (id: number, data: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/categories/${id}`, { method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(data) }) if (!response.ok) throw new Error('Update category failed') } catch (error) { throw error } } export const deleteCategory = async (id: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/categories/${id}`, { method: 'DELETE', headers: getAuthHeaders() }) if (!response.ok) throw new Error('Delete category failed') } catch (error) { throw error } } // 专栏管理API export const fetchColumns = async (): Promise => { try { const response = await fetch(`${API_BASE}/columns`) if (!response.ok) throw new Error('Failed to fetch columns') const data = await response.json() return data.result || [] } catch (error) { return [] } } export const fetchColumn = async (id: number): Promise => { try { const response = await fetch(`${API_BASE}/columns/${id}`) if (!response.ok) throw new Error('Failed to fetch column') const data = await response.json() return data.result } catch (error) { throw error } } export const getAdminColumns = async (): Promise => { try { const response = await fetch(`${API_BASE}/admin/columns`, { headers: getAuthHeaders() }) if (!response.ok) throw new Error('Failed to fetch admin columns') const data = await response.json() return data.result || [] } catch (error) { throw error } } export const createColumn = async (data: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/columns`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(data) }) if (!response.ok) throw new Error('Create column failed') } catch (error) { throw error } } export const updateColumn = async (id: number, data: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/columns/${id}`, { method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(data) }) if (!response.ok) throw new Error('Update column failed') } catch (error) { throw error } } export const deleteColumn = async (id: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/columns/${id}`, { method: 'DELETE', headers: getAuthHeaders() }) if (!response.ok) throw new Error('Delete column failed') } catch (error) { throw error } } export const fetchColumnPosts = async (id: number): Promise => { try { const response = await fetch(`${API_BASE}/columns/${id}/posts`) if (!response.ok) throw new Error('Failed to fetch column posts') const data = await response.json() return data.result || [] } catch (error) { console.error('Fetch column posts error:', error) return [] } } export const addPostToColumn = async (columnId: number, postId: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/columns/${columnId}/posts`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify({ postId }) }) if (!response.ok) throw new Error('Add post to column failed') } catch (error) { throw error } } export const removePostFromColumn = async (columnId: number, postId: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/columns/${columnId}/posts/${postId}`, { method: 'DELETE', headers: getAuthHeaders() }) if (!response.ok) throw new Error('Remove post from column failed') } catch (error) { throw error } } // 标签管理API (复用现有 Tag 类型) export const fetchTags = async (): Promise => { try { const response = await fetch(`${API_BASE}/tags`) if (!response.ok) throw new Error('Failed to fetch tags') const data = await response.json() return data.result || [] } catch (error) { return [] } } export const adminGetTags = async (): Promise => { try { const response = await fetch(`${API_BASE}/admin/tags`, { headers: getAuthHeaders() }) if (!response.ok) throw new Error('Failed to fetch admin tags') const data = await response.json() return data.result || [] } catch (error) { throw error } } export const adminGetTag = async (id: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/tags/${id}`, { headers: getAuthHeaders() }) if (!response.ok) throw new Error('Failed to fetch admin tag') const data = await response.json() return data.result // Adapt to standard response } catch (error) { throw error } } export const createTag = async (data: { name: string; slug: string }): Promise => { try { const response = await fetch(`${API_BASE}/admin/tags`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(data) }) if (!response.ok) throw new Error('Create tag failed') } catch (error) { throw error } } export const updateTag = async (id: number, data: { name: string; slug: string }): Promise => { try { const response = await fetch(`${API_BASE}/admin/tags/${id}`, { method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(data) }) if (!response.ok) throw new Error('Update tag failed') } catch (error) { throw error } } export const deleteTag = async (id: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/tags/${id}`, { method: 'DELETE', headers: getAuthHeaders() }) if (!response.ok) throw new Error('Delete tag failed') } catch (error) { throw error } } // 文章历史记录API export const getPostHistory = async (postId: number | string): Promise => { try { const response = await fetch(`${API_BASE}/admin/posts/${postId}/history`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取文章历史失败') } const data = await response.json() return data.result || [] } catch (error) { console.error('Get post history error:', error) throw error } } export const getPostHistoryByVersion = async (postId: number | string, version: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/posts/${postId}/history/${version}`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取指定版本文章历史失败') } const data = await response.json() return data.result } catch (error) { console.error('Get post history by version error:', error) throw error } } // 代码片段管理API export const getAdminSnippets = async (): Promise => { try { const response = await fetch(`${API_BASE}/admin/snippets`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取代码片段列表失败') } const data = await response.json() // 后端返回的是分页格式 {list, total, page, size},需要从 result.list 中取值 return (data.result?.list || []) as Snippet[] } catch (error) { console.error('Get admin snippets error:', error) throw error } } export const fetchSnippets = async (): Promise => { try { const response = await fetch(`${API_BASE}/snippets`) if (!response.ok) throw new Error('Failed to fetch snippets') const data = await response.json() return data.result || [] } catch (error) { console.error('Error fetching snippets:', error) return [] } } export const fetchSnippet = async (id: string): Promise => { try { const response = await fetch(`${API_BASE}/snippets/${id}`) if (!response.ok) throw new Error('Failed to fetch snippet') const data = await response.json() return data.result } catch (error) { console.error(`Error fetching snippet ${id}:`, error) return { id: id, title: '默认代码片段', code: 'console.log("Hello World");', type: 'js' } } } export const createSnippet = async (snippetData: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/snippets`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(snippetData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '创建代码片段失败') } } catch (error) { console.error('Create snippet error:', error) throw error } } export const updateSnippet = async (id: string, snippetData: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/snippets/${id}`, { method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(snippetData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '更新代码片段失败') } } catch (error) { console.error('Update snippet error:', error) throw error } } export const deleteSnippet = async (id: string): Promise => { try { const response = await fetch(`${API_BASE}/admin/snippets/${id}`, { method: 'DELETE', headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '删除代码片段失败') } } catch (error) { console.error('Delete snippet error:', error) throw error } } // 系统配置API export const getSettings = async (): Promise => { try { const response = await fetch(`${API_BASE}/admin/settings`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取系统配置失败') } const data = await response.json() // 确保从 result 字段取值,并确保始终返回数组 if (!data.result) { return [] } return Array.isArray(data.result) ? data.result : [] } catch (error) { console.error('Get settings error:', error) throw error } } export const createSetting = async (settingData: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/settings`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(settingData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '创建系统配置失败') } } catch (error) { console.error('Create setting error:', error) throw error } } export const updateSetting = async (settingData: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/settings`, { method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(settingData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '更新系统配置失败') } } catch (error) { console.error('Update setting error:', error) throw error } } export const deleteSetting = async (keyName: string): Promise => { try { const response = await fetch(`${API_BASE}/admin/settings/${keyName}`, { method: 'DELETE', headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '删除系统配置失败') } } catch (error) { console.error('Delete setting error:', error) throw error } } // 公开设置API(前端使用,无需认证) export interface PublicSettings { site_title?: string site_description?: string site_author?: string site_keywords?: string } export const getPublicSettings = async (): Promise => { try { const response = await fetch(`${API_BASE}/settings`) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取网站配置失败') } const data = await response.json() return data.result || {} } catch (error) { console.error('Get public settings error:', error) // 返回空对象,前端使用默认值 return {} } } // 操作日志API export const getOperationLogs = async (page: number = 1, pageSize: number = 10): Promise> => { try { const response = await fetch(`${API_BASE}/admin/operation-logs?page=${page}&pageSize=${pageSize}`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取操作日志失败') } const data = await response.json() return data.result } catch (error) { console.error('Get operation logs error:', error) throw error } } // 访问日志类型 export interface AccessLog { id: number ip: string userAgent: string path: string method: string statusCode: number responseTime: number region: string createdAt: string } // 访问日志API export const getAccessLogs = async (page: number = 1, pageSize: number = 10): Promise> => { try { const response = await fetch(`${API_BASE}/admin/access-logs?page=${page}&pageSize=${pageSize}`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取访问日志失败') } const data = await response.json() return data.result } catch (error) { console.error('Get access logs error:', error) throw error } } // 获取指定文章的访问记录 export const getPostAccessLogs = async (postId: number, page: number = 1, pageSize: number = 20): Promise> => { try { const response = await fetch(`${API_BASE}/admin/posts/${postId}/access-logs?page=${page}&pageSize=${pageSize}`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取文章访问记录失败') } const data = await response.json() return data.result } catch (error) { console.error('Get post access logs error:', error) throw error } } // 仪表盘数据类型 export interface DashboardStats { users: number posts: number works: number snippets: number } // 最近活动类型 export interface RecentActivity { id: number icon: string text: string time: string } // 仪表盘API export const getDashboardStats = async (startDate?: string, endDate?: string): Promise => { try { let url = `${API_BASE}/admin/dashboard/stats` const params = new URLSearchParams() if (startDate) params.append('startDate', startDate) if (endDate) params.append('endDate', endDate) if (params.toString()) url += `?${params.toString()}` const response = await fetch(url, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取仪表盘统计数据失败') } const data = await response.json() return data.result } catch (error) { console.error('Get dashboard stats error:', error) throw error } } // 获取最近活动 export const getRecentActivities = async (): Promise => { try { const response = await fetch(`${API_BASE}/admin/dashboard/activities`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取最近活动失败') } const data = await response.json() return data.result || [] } catch (error) { console.error('Get recent activities error:', error) throw error } } // 关于页面相关类型 export interface Experience { year: string role: string company: string } export interface AboutProfile { id: number name: string avatar: string location: string bio: string email: string wechat: string techStack: string[] experiences: Experience[] isPrimary: boolean createdAt: string updatedAt: string } // 关于页面API export const fetchAboutProfile = async (): Promise => { try { const response = await fetch(`${API_BASE}/about`) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取个人资料失败') } const data = await response.json() // 确保从 result 字段取值 if (!data.result) { throw new Error('个人资料数据为空') } const result = data.result as AboutProfile // 确保 techStack 和 experiences 始终是数组 if (!Array.isArray(result.techStack)) { result.techStack = [] } if (!Array.isArray(result.experiences)) { result.experiences = [] } return result } catch (error) { console.error('Fetch about profile error:', error) throw error } } export const getAdminAboutProfiles = async (): Promise => { try { const response = await fetch(`${API_BASE}/admin/about`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取个人资料列表失败') } const data = await response.json() return data.result || [] } catch (error) { console.error('Get admin about profiles error:', error) throw error } } export const createAboutProfile = async (profileData: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/about`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(profileData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '创建个人资料失败') } } catch (error) { console.error('Create about profile error:', error) throw error } } export const updateAboutProfile = async (id: number, profileData: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/about/${id}`, { method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(profileData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '更新个人资料失败') } } catch (error) { console.error('Update about profile error:', error) throw error } } export const deleteAboutProfile = async (id: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/about/${id}`, { method: 'DELETE', headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '删除个人资料失败') } } catch (error) { console.error('Delete about profile error:', error) throw error } } // 客户评价相关类型 export interface Testimonial { id: number content: string author: string role: string avatar: string rating: number createdAt: string updatedAt: string } // 合作伙伴相关类型 export interface Partner { id: number name: string logo: string description: string website: string createdAt: string updatedAt: string } // 客户评价API export const fetchTestimonials = async (): Promise => { try { const response = await fetch(`${API_BASE}/testimonials`) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取客户评价失败') } const data = await response.json() return data.result || [] } catch (error) { console.error('Fetch testimonials error:', error) throw error } } export const createTestimonial = async (data: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/testimonials`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(data) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '创建客户评价失败') } } catch (error) { console.error('Create testimonial error:', error) throw error } } export const updateTestimonial = async (id: number, data: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/testimonials/${id}`, { method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(data) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '更新客户评价失败') } } catch (error) { console.error('Update testimonial error:', error) throw error } } export const deleteTestimonial = async (id: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/testimonials/${id}`, { method: 'DELETE', headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '删除客户评价失败') } } catch (error) { console.error('Delete testimonial error:', error) throw error } } // 合作伙伴API export const fetchPartners = async (): Promise => { try { const response = await fetch(`${API_BASE}/partners`) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取合作伙伴失败') } const data = await response.json() return data.result || [] } catch (error) { console.error('Fetch partners error:', error) throw error } } export const createPartner = async (data: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/partners`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(data) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '创建合作伙伴失败') } } catch (error) { console.error('Create partner error:', error) throw error } } export const updatePartner = async (id: number, data: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/partners/${id}`, { method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(data) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '更新合作伙伴失败') } } catch (error) { console.error('Update partner error:', error) throw error } } export const deletePartner = async (id: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/partners/${id}`, { method: 'DELETE', headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '删除合作伙伴失败') } } catch (error) { console.error('Delete partner error:', error) throw error } } // 咨询相关类型 export interface Inquiry { id?: number name: string company: string contactMethod: string contactValue: string budget: string description: string status?: number // 0-Unread, 1-Read, 2-Contacted createdAt?: string } // OSS配置相关类型 export interface OSSConfig { id: number name: string storageType: string // 通用字段(向后兼容) accessKey?: string secretKey?: string bucket?: string region?: string domain?: string // 阿里云OSS专用字段 ossAccessKeyId?: string ossAccessKeySecret?: string ossEndpoint?: string ossBucket?: string ossDomain?: string // 腾讯云COS专用字段 qcloudSecretId?: string qcloudSecretKey?: string qcloudRegion?: string qcloudBucket?: string qcloudDomain?: string // 七牛云专用字段 qiniuAccessKey?: string qiniuSecretKey?: string qiniuBucket?: string qiniuRegion?: string qiniuDomain?: string isActive: number createdAt: string updatedAt: string } // 向后兼容的旧接口定义(已废弃,保留用于类型兼容) export interface OSSConfigOld { id: number name: string storageType: string // local/qcloud/aliyun/qiniu accessKey: string // 加密存储,返回时显示为 *** secretKey: string // 加密存储,返回时显示为 *** bucket: string region: string domain: string isActive: number createdAt: string updatedAt: string } export interface EmailSuffix { id: number suffix: string isActive: boolean sortOrder: number createdAt: string updatedAt: string } // 咨询相关API export const submitInquiry = async (data: Inquiry): Promise => { try { const response = await fetch(`${API_BASE}/inquiries`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '提交咨询失败') } } catch (error) { console.error('Submit inquiry error:', error) throw error } } export const fetchEmailSuffixes = async (): Promise => { try { const response = await fetch(`${API_BASE}/email-suffixes`) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取邮箱后缀失败') } const data = await response.json() return data.result || [] } catch (error) { console.error('Fetch email suffixes error:', error) throw error } } export const fetchInquiries = async (): Promise => { try { const response = await fetch(`${API_BASE}/admin/inquiries`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取咨询列表失败') } const data = await response.json() return data.result || [] } catch (error) { console.error('Fetch inquiries error:', error) throw error } } // OSS配置相关API export const getOSSConfigs = async (): Promise => { try { const response = await fetch(`${API_BASE}/admin/oss-configs`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取OSS配置失败') } const data = await response.json() return data.result || [] } catch (error) { console.error('Get OSS configs error:', error) throw error } } export const createOSSConfig = async (configData: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/oss-configs`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(configData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '创建OSS配置失败') } const data = await response.json() return data.result } catch (error) { console.error('Create OSS config error:', error) throw error } } export const updateOSSConfig = async (id: number, configData: Partial>): Promise => { try { const response = await fetch(`${API_BASE}/admin/oss-configs/${id}`, { method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(configData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '更新OSS配置失败') } const data = await response.json() return data.result } catch (error) { console.error('Update OSS config error:', error) throw error } } export const deleteOSSConfig = async (id: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/oss-configs/${id}`, { method: 'DELETE', headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '删除OSS配置失败') } } catch (error) { console.error('Delete OSS config error:', error) throw error } } // 附件相关类型 export interface Attachment { id: number categoryId?: number category?: { id: number name: string } originalName: string storedName: string filePath: string fileUrl: string fileSize: number fileType: string mimeType: string storageType: string ossConfigId?: number createdAt: string updatedAt: string } // 附件分类相关类型 export interface AttachmentCategory { id: number name: string description: string sortOrder: number createdAt: string updatedAt: string } // 附件管理API export const getAdminAttachments = async (params?: { page?: number pageSize?: number categoryId?: number fileType?: string keyword?: string }): Promise<{ list: Attachment[], total: number, page: number, size: number }> => { try { const queryParams = new URLSearchParams() if (params?.page) queryParams.append('page', params.page.toString()) if (params?.pageSize) queryParams.append('pageSize', params.pageSize.toString()) if (params?.categoryId) queryParams.append('categoryId', params.categoryId.toString()) if (params?.fileType) queryParams.append('fileType', params.fileType) if (params?.keyword) queryParams.append('keyword', params.keyword) const url = `${API_BASE}/admin/attachments${queryParams.toString() ? '?' + queryParams.toString() : ''}` const response = await fetch(url, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取附件列表失败') } const data = await response.json() return { list: data.result?.list || [], total: data.result?.total || 0, page: data.result?.page || 1, size: data.result?.size || 20 } } catch (error) { console.error('Get admin attachments error:', error) throw error } } export const updateAttachment = async (id: number, data: { categoryId?: number | null }): Promise => { try { const response = await fetch(`${API_BASE}/admin/attachments/${id}`, { method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(data) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '更新附件失败') } const responseData = await response.json() return responseData.result } catch (error) { console.error('Update attachment error:', error) throw error } } // 附件分类管理API export const getAttachmentCategories = async (): Promise => { try { const response = await fetch(`${API_BASE}/admin/attachment-categories`, { headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '获取附件分类列表失败') } const data = await response.json() return data.result || [] } catch (error) { console.error('Get attachment categories error:', error) throw error } } export const createAttachmentCategory = async (categoryData: Omit): Promise => { try { const response = await fetch(`${API_BASE}/admin/attachment-categories`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(categoryData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '创建附件分类失败') } } catch (error) { console.error('Create attachment category error:', error) throw error } } export const updateAttachmentCategory = async (id: number, categoryData: Partial>): Promise => { try { const response = await fetch(`${API_BASE}/admin/attachment-categories/${id}`, { method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(categoryData) }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '更新附件分类失败') } } catch (error) { console.error('Update attachment category error:', error) throw error } } export const deleteAttachmentCategory = async (id: number): Promise => { try { const response = await fetch(`${API_BASE}/admin/attachment-categories/${id}`, { method: 'DELETE', headers: getAuthHeaders() }) if (!response.ok) { const errorData = await response.json() throw new Error(errorData.message || '删除附件分类失败') } } catch (error) { console.error('Delete attachment category error:', error) throw error } }