import { http, HttpResponse, delay } from 'msw'; import { mockMenus } from '../data'; import type { MockMenu } from '../data'; // Mutable in-memory store let menus = [...mockMenus]; let nextId = Math.max(...menus.map((m) => m.id)) + 1; export const menuHandlers = [ // List (returns all menus as flat array) http.get('/admin-api/system/menu/list', async ({ request }) => { await delay(300); const url = new URL(request.url); const name = url.searchParams.get('name') || ''; const status = url.searchParams.get('status'); let filtered = [...menus]; if (name) { filtered = filtered.filter((m) => m.name.includes(name)); } if (status !== null && status !== '') { filtered = filtered.filter((m) => m.status === Number(status)); } return HttpResponse.json({ code: 0, data: filtered, message: 'ok', }); }), // Get by ID http.get('/admin-api/system/menu/get', async ({ request }) => { await delay(200); const url = new URL(request.url); const id = Number(url.searchParams.get('id')); const menu = menus.find((m) => m.id === id); if (!menu) { return HttpResponse.json( { code: 1, data: null, message: '菜单不存在' }, ); } return HttpResponse.json({ code: 0, data: menu, message: 'ok', }); }), // Create http.post('/admin-api/system/menu/create', async ({ request }) => { await delay(300); const body = (await request.json()) as Record; const newMenu: MockMenu = { id: nextId++, name: body.name as string, permission: (body.permission as string) || '', type: body.type as number, sort: (body.sort as number) ?? 0, parentId: (body.parentId as number) ?? 0, path: (body.path as string) || '', icon: (body.icon as string) || '', component: (body.component as string) || '', status: (body.status as number) ?? 0, visible: (body.visible as boolean) ?? true, keepAlive: (body.keepAlive as boolean) ?? true, createTime: new Date().toISOString().replace('T', ' ').slice(0, 19), }; menus.push(newMenu); return HttpResponse.json({ code: 0, data: newMenu.id, message: 'ok' }); }), // Update http.put('/admin-api/system/menu/update', async ({ request }) => { await delay(300); const body = (await request.json()) as Record; const index = menus.findIndex((m) => m.id === body.id); if (index === -1) { return HttpResponse.json( { code: 1, data: null, message: '菜单不存在' }, ); } // Prevent setting parent to self if (body.parentId !== undefined && body.parentId === body.id) { return HttpResponse.json( { code: 1, data: null, message: '上级菜单不能是自己' }, ); } menus[index] = { ...menus[index], ...(body.name !== undefined && { name: body.name as string }), ...(body.permission !== undefined && { permission: body.permission as string }), ...(body.type !== undefined && { type: body.type as number }), ...(body.sort !== undefined && { sort: body.sort as number }), ...(body.parentId !== undefined && { parentId: body.parentId as number }), ...(body.path !== undefined && { path: body.path as string }), ...(body.icon !== undefined && { icon: body.icon as string }), ...(body.component !== undefined && { component: body.component as string }), ...(body.status !== undefined && { status: body.status as number }), ...(body.visible !== undefined && { visible: body.visible as boolean }), ...(body.keepAlive !== undefined && { keepAlive: body.keepAlive as boolean }), }; return HttpResponse.json({ code: 0, data: true, message: 'ok' }); }), // Delete http.delete('/admin-api/system/menu/delete', async ({ request }) => { await delay(200); const url = new URL(request.url); const id = Number(url.searchParams.get('id')); // Check if menu has children const hasChildren = menus.some((m) => m.parentId === id); if (hasChildren) { return HttpResponse.json( { code: 1, data: null, message: '存在子菜单,不允许删除' }, ); } menus = menus.filter((m) => m.id !== id); return HttpResponse.json({ code: 0, data: true, message: 'ok' }); }), ];