import { mockAdminUsers, mockCategories, mockDashboardData, mockPlatformComments, mockPlatformUsers, mockPlatformVideos, mockStatistics, mockTags, paginate } from './data' const delay = (ms = 120) => new Promise((resolve) => setTimeout(resolve, ms)) const mockStore = { adminUsers: [...mockAdminUsers], users: [...mockPlatformUsers], videos: [...mockPlatformVideos], comments: [...mockPlatformComments], categories: [...mockCategories], tags: [...mockTags] } function normalize(url: string) { return url.replace(/^\/api\/admin/, '') } function matchPath(path: string, pattern: string) { const pathParts = path.split('/').filter(Boolean) const patternParts = pattern.split('/').filter(Boolean) if (pathParts.length !== patternParts.length) return false return patternParts.every((part, index) => part.startsWith(':') || part === pathParts[index]) } function pathParam(path: string, indexFromEnd = 1) { const parts = path.split('/').filter(Boolean) return Number(parts[parts.length - indexFromEnd]) } function filterByKeyword(list: T[], getter: (item: T) => string, keyword?: string) { if (!keyword) return list const needle = keyword.toLowerCase() return list.filter((item) => getter(item).toLowerCase().includes(needle)) } export async function mockRequest(url: string, options: any = {}) { const method = (options.method || 'GET').toUpperCase() const path = normalize(url).split('?')[0] const params = options.params || {} const body = options.body || {} await delay() if (method === 'GET' && path === '/auth/captcha') { return ok({ captchaKey: `admin-captcha-${Date.now()}`, captchaImage: `data:image/svg+xml;utf8,${encodeURIComponent(` 2 4 6 8 `)}` }) } if (method === 'POST' && path === '/auth/login') { return ok({ accessToken: `admin-token-${Date.now()}`, refreshToken: `admin-refresh-${Date.now()}`, tokenType: 'Bearer', expiresIn: 7200, adminId: 1, username: body.username || 'admin' }) } if (method === 'POST' && path === '/auth/logout') { return ok(null) } if (method === 'GET' && path === '/auth/info') { return ok(mockStore.adminUsers[0]) } if (method === 'GET' && path === '/statistics/dashboard') { return ok(mockDashboardData) } if (method === 'GET' && path === '/statistics/overview') { return ok(mockStatistics) } if (method === 'GET' && path === '/statistics/user/trend') { return ok(mockStatistics.userTrend) } if (method === 'GET' && path === '/statistics/video/trend') { return ok(mockStatistics.videoTrend) } if (method === 'GET' && path === '/statistics/view/trend') { return ok(mockStatistics.viewTrend) } if (method === 'GET' && path === '/platform/user/stats') { const { totalUsers, newUsersToday, activeUsersToday, userGrowthRate } = mockStatistics return ok({ totalUsers, newUsersToday, activeUsersToday, userGrowthRate }) } if (method === 'GET' && path === '/platform/content/video/stats') { const { totalVideos, newVideosToday, pendingReview, videoGrowthRate } = mockStatistics return ok({ totalVideos, newVideosToday, pendingReview, videoGrowthRate }) } if (method === 'GET' && path === '/admin/stats') { return ok({ totalComments: mockStatistics.totalComments, commentsToday: 84, commentGrowthRate: 5.8 }) } if (method === 'GET' && path === '/platform/user/list') { let list = [...mockStore.users] list = filterByKeyword(list, (item) => `${item.username} ${item.nickname} ${item.phone}`, params.keyword) if (params.status !== undefined && params.status !== '') { list = list.filter((item) => item.status === Number(params.status)) } return ok(paginate(list, Number(params.page || 1), Number(params.size || 10))) } if (method === 'GET' && matchPath(path, '/platform/user/:id')) { return ok(mockStore.users.find((item) => item.id === pathParam(path)) || mockStore.users[0]) } if (method === 'PUT' && matchPath(path, '/platform/user/:id/status/:status')) { const user = mockStore.users.find((item) => item.id === pathParam(path, 2)) if (user) user.status = pathParam(path) return ok(null) } if (method === 'PUT' && matchPath(path, '/platform/user/:id/reset-password')) { return ok(null) } if (method === 'GET' && path === '/platform/content/video/list') { let list = [...mockStore.videos] list = filterByKeyword(list, (item) => item.title, params.keyword) if (params.status !== undefined && params.status !== '') { list = list.filter((item) => item.status === Number(params.status)) } if (params.auditStatus !== undefined && params.auditStatus !== '') { list = list.filter((item) => item.auditStatus === Number(params.auditStatus)) } if (params.categoryId) { list = list.filter((item) => item.categoryId === Number(params.categoryId)) } return ok(paginate(list, Number(params.page || 1), Number(params.size || 10))) } if (method === 'GET' && matchPath(path, '/platform/content/video/:id')) { return ok(mockStore.videos.find((item) => item.id === pathParam(path)) || mockStore.videos[0]) } if (method === 'POST' && matchPath(path, '/platform/content/video/review/:id')) { const video = mockStore.videos.find((item) => item.id === pathParam(path)) if (video) { video.auditStatus = Number(body.status) video.auditReason = body.reason || '' video.status = Number(body.status) === 1 ? 1 : 2 video.publishTime = Number(body.status) === 1 ? '2026-03-22 10:30:00' : '' } return ok(null) } if (method === 'PUT' && matchPath(path, '/platform/content/video/disable/:id')) { const video = mockStore.videos.find((item) => item.id === pathParam(path)) if (video) video.status = 3 return ok(null) } if (method === 'GET' && path === '/admin/list') { let list = [...mockStore.comments] list = filterByKeyword(list, (item) => item.content, params.keyword) if (params.status !== undefined && params.status !== '') { list = list.filter((item) => item.status === Number(params.status)) } return ok(paginate(list, Number(params.page || 1), Number(params.size || 10))) } if (method === 'DELETE' && matchPath(path, '/admin/:id')) { const comment = mockStore.comments.find((item) => item.id === pathParam(path)) if (comment) comment.status = 0 return ok(null) } if (method === 'GET' && path === '/platform/content/category/list') { return ok([...mockStore.categories].sort((a, b) => a.sort - b.sort)) } if (method === 'POST' && path === '/platform/content/category') { mockStore.categories.push({ id: mockStore.categories.length + 10, name: body.name, parentId: body.parentId || 0, sort: body.sort || 0, icon: body.icon || '' }) return ok(null) } if (method === 'PUT' && path === '/platform/content/category') { const category = mockStore.categories.find((item) => item.id === body.id) if (category) Object.assign(category, body) return ok(null) } if (method === 'DELETE' && matchPath(path, '/platform/content/category/:id')) { mockStore.categories = mockStore.categories.filter((item) => item.id !== pathParam(path)) return ok(null) } if (method === 'GET' && path === '/content/tag/page') { const list = filterByKeyword([...mockStore.tags], (item) => item.name, params.keyword) return ok(paginate(list, Number(params.page || 1), Number(params.size || 10))) } if (method === 'POST' && path === '/content/tag') { mockStore.tags.unshift({ id: mockStore.tags.length + 1, name: body.name, useCount: 0, createTime: '2026-03-22 10:00:00' }) return ok(null) } if (method === 'PUT' && path === '/content/tag') { const tag = mockStore.tags.find((item) => item.id === body.id) if (tag) tag.name = body.name return ok(null) } if (method === 'DELETE' && matchPath(path, '/content/tag/:id')) { mockStore.tags = mockStore.tags.filter((item) => item.id !== pathParam(path)) return ok(null) } if (method === 'GET' && path === '/user/list') { const list = filterByKeyword([...mockStore.adminUsers], (item) => `${item.username} ${item.nickname}`, params.keyword) return ok(paginate(list, Number(params.page || 1), Number(params.size || 10))) } if (method === 'POST' && path === '/user') { mockStore.adminUsers.push({ id: mockStore.adminUsers.length + 1, username: body.username, nickname: body.nickname, avatar: 'https://picsum.photos/seed/newadmin/120/120', email: body.email || '', phone: body.phone || '', role: body.role || 'manager', status: 1, lastLoginTime: '', lastLoginIp: '', createTime: '2026-03-22 10:00:00' }) return ok(null) } if (method === 'PUT' && path === '/user') { const admin = mockStore.adminUsers.find((item) => item.id === body.id) if (admin) Object.assign(admin, body) return ok(null) } if (method === 'PUT' && matchPath(path, '/user/:id/status/:status')) { const admin = mockStore.adminUsers.find((item) => item.id === pathParam(path, 2)) if (admin) admin.status = pathParam(path) return ok(null) } if (method === 'PUT' && matchPath(path, '/user/:id/reset-password')) { return ok(null) } return { code: 404, message: `未找到 Mock 处理器: ${method} ${path}`, data: null } } function ok(data: any) { return { code: 200, message: 'success', data } } export function isMockEnabled() { return import.meta.env.VITE_MOCK === 'true' || import.meta.env.VITE_MOCK === true }