const express = require('express'); const bodyParser = require('body-parser'); const Mock = require('mockjs'); const fs = require('fs-extra'); const dayjs = require('dayjs'); // ✅ 引入 swagger 组件 const swaggerUi = require('swagger-ui-express'); const swaggerJSDoc = require('swagger-jsdoc'); const app = express(); const PORT = 3000; const CONFIG_PATH = './mock-config.json'; app.use(bodyParser.json()); // 加载配置文件 let mockConfigs = fs.existsSync(CONFIG_PATH) ? fs.readJsonSync(CONFIG_PATH) : []; // ✅ 统一响应结构 function formatResponse(data, code = 200, message = 'success') { return { code, type: code === 200 ? 'success' : 'error', message, result: data, extras: null, time: dayjs().format('YYYY-MM-DD HH:mm:ss') }; } // ✅ 注册 mock 接口 function registerMockApi(config) { const { method, path, response } = config; const methodName = method.toLowerCase(); app[methodName](path, (req, res) => { try { const data = Mock.mock(response); res.json(formatResponse(data)); } catch (err) { res.json(formatResponse(null, 500, err.message)); } }); } // 初始注册全部 mockConfigs.forEach(registerMockApi); // ✅ 添加新接口 app.post('/mock-api/add', async (req, res) => { const config = req.body; if (!config.method || !config.path || !config.response) { return res.json(formatResponse(null, 400, '参数不完整')); } registerMockApi(config); mockConfigs.push(config); await fs.writeJson(CONFIG_PATH, mockConfigs, { spaces: 2 }); res.json(formatResponse({ path: config.path }, 200, '接口已添加')); }); // ✅ 获取全部 mock 定义 app.get('/mock-api/list', (req, res) => { res.json(formatResponse(mockConfigs)); }); // ✅ 获取所有 URL 路由(简版) app.get('/mock-api/routes', (req, res) => { const list = mockConfigs.map(({ method, path }) => ({ method, path })); res.json(list); }); // ✅ Swagger 配置 const swaggerDefinition = { openapi: '3.0.0', info: { title: 'Mock API Docs', version: '1.0.0', description: 'Dynamically registered mock APIs' }, servers: [{ url: `http://192.168.100.138:${PORT}`, description: 'Local server' }] }; function buildSwaggerSpecFromMocks(configs) { const paths = {}; configs.forEach(({ method, path }) => { const cleanPath = path.replace(/:([^/]+)/g, '{$1}'); const methodName = method.toLowerCase(); paths[cleanPath] = paths[cleanPath] || {}; paths[cleanPath][methodName] = { summary: `Mocked ${method} ${path}`, responses: { 200: { description: 'Mock response', content: { 'application/json': { schema: { type: 'object' } } } } } }; }); return { ...swaggerDefinition, paths }; } // ✅ Swagger UI 路由 app.use('/swagger', swaggerUi.serve, (req, res, next) => { const spec = buildSwaggerSpecFromMocks(mockConfigs); swaggerUi.setup(spec)(req, res, next); }); // ✅ 启动服务 app.listen(PORT, () => { console.log(`✅ Mock Server is running at http://localhost:${PORT}`); console.log(`📚 Swagger UI available at http://localhost:${PORT}/swagger`); });