# Node Core Framework 使用说明 ## 📋 概述 `node-core-framework.js` 是一个基于 Koa2 + Sequelize + MySQL 的企业级 Node.js 后端框架,提供了完整的 MVC 架构、数据库管理、API 文档生成、权限验证等功能。 ## 🚀 快速开始 ### 1. 环境要求 - **Node.js**: >= 16.0.0 - **MySQL**: >= 5.7 - **Redis**: >= 5.0 (可选,用于缓存) ### 2. 安装依赖 ```bash # 安装核心依赖 npm install koa koa-body koa-router koa-static koa2-cors koa2-swagger-ui npm install sequelize mysql2 redis jsonwebtoken dayjs swagger-jsdoc ``` ### 3. 基础使用 ```javascript // app.js const Framework = require('./dist/node-core-framework.js'); // 配置文件 const config = { // 数据库配置 db: { username: "your_username", password: "your_password", database: "your_database", host: "localhost", port: 3306, dialect: "mysql", timezone: '+08:00' }, // Redis配置(可选) redis: { host: 'localhost', port: 6379, password: '', db: 0 }, // 日志路径 logPath: './logs', // 基础URL baseUrl: 'http://localhost:3001', // API路径配置 apiPaths: [ { path: './controllers', prefix: '/api', authType: 'applet' } ], // 模型路径 modelPaths: './models', // 允许的URL(无需认证) allowUrls: [ '/api/users/login', '/api/health', '/api/docs' ], // 授权文件路径 license: { licensePath: './license.lic' } }; // 启动应用 async function startApp() { try { // 创建框架实例 const framework = await Framework.init(config); // 启动服务器 const server = await framework.start(3001); console.log('🎉 应用启动成功!'); console.log(`📚 API 文档: http://localhost:3001/api/docs`); // 使用日志服务 const logsService = Framework.getServices().logsService; logsService.log('应用启动成功', { port: 3001, time: new Date() }); } catch (error) { console.error('❌ 启动失败:', error); // 记录启动错误 const logsService = Framework.getServices().logsService; logsService.error('应用启动失败', error); } } startApp(); ``` ## 🏗️ 框架架构 ### 核心组件 1. **Framework**: 主框架类,负责整体协调 2. **ModelManager**: 数据库模型管理器 3. **ServiceManager**: 服务层管理器 4. **RequestManager**: 请求处理器管理器 5. **RegistrationService**: 授权验证服务 ### 目录结构 ``` project/ ├── dist/ │ └── node-core-framework.js # 打包后的框架文件 ├── controllers/ # 控制器目录 │ ├── user_controller.js │ ├── article_controller.js │ └── admin/ │ ├── sys_user.js # 系统用户管理 │ └── sys_log.js # 日志管理接口 ├── models/ # 数据模型目录 │ ├── user.js │ └── article.js ├── config.js # 配置文件 ├── app.js # 应用入口 └── logs/ # 日志目录 ├── log_2024.01.15.log # 普通日志文件 ├── logError_2024.01.15.log # 错误日志文件 └── log_2024.01.15_1.log # 分割后的日志文件 ``` ## 📝 详细配置说明 ### 数据库配置 ```javascript const config = { db: { username: "root", // 数据库用户名 password: "password", // 数据库密码 database: "myapp", // 数据库名 host: "localhost", // 数据库主机 port: 3306, // 数据库端口 dialect: "mysql", // 数据库类型 timezone: '+08:00', // 时区 pool: { // 连接池配置 max: 10, // 最大连接数 min: 0, // 最小连接数 acquire: 30000, // 获取连接超时时间 idle: 10000 // 连接空闲时间 }, logging: true // 是否打印SQL日志 } }; ``` ### API路径配置 ```javascript const config = { apiPaths: [ { path: './controllers', // 控制器目录路径 prefix: '/api', // API前缀 authType: 'applet' // 认证类型:applet | admin }, { path: './controllers_admin', // 管理端控制器 prefix: '/admin_api', // 管理端API前缀 authType: 'admin' } ] }; ``` ### 权限配置 ```javascript const config = { // 允许的URL(无需认证) allowUrls: [ '/api/users/login', // 登录接口 '/api/users/register', // 注册接口 '/api/health', // 健康检查 '/api/docs', // API文档 '/api/swagger.json' // Swagger配置 ], // 授权文件路径 license: { licensePath: './license.lic' } }; ``` ## 🎯 控制器开发 ### 基础控制器结构 ```javascript // controllers/user_controller.js const { models } = require('../database/db'); module.exports = { /** * @swagger * /api/users: * get: * summary: 获取用户列表 * description: 分页获取用户列表 * tags: * - 用户管理 * parameters: * - in: query * name: page * schema: * type: integer * default: 1 * description: 页码 * - in: query * name: pageSize * schema: * type: integer * default: 20 * description: 每页数量 * responses: * 200: * description: 获取成功 */ "GET /users": async (ctx) => { const { user: UserModel } = models; // 获取分页参数 const { limit, offset } = ctx.getPageSize(); // 查询用户列表 const users = await UserModel.findAndCountAll({ attributes: ['id', 'username', 'email', 'status', 'create_time'], limit, offset, order: [['create_time', 'DESC']] }); // 返回成功响应 ctx.success(users, '获取用户列表成功'); }, /** * @swagger * /api/users: * post: * summary: 创建用户 * description: 创建新用户 * tags: * - 用户管理 * requestBody: * required: true * content: * application/json: * schema: * type: object * required: * - username * - email * - password * properties: * username: * type: string * description: 用户名 * email: * type: string * format: email * description: 邮箱 * password: * type: string * description: 密码 * responses: * 200: * description: 创建成功 */ "POST /users": async (ctx) => { const { user: UserModel } = models; const { username, email, password } = ctx.getBody(); // 参数验证 if (!username || !email || !password) { return ctx.fail('用户名、邮箱和密码不能为空'); } // 检查邮箱是否已存在 const existingUser = await UserModel.findOne({ where: { email } }); if (existingUser) { return ctx.fail('邮箱已存在'); } // 创建用户 const newUser = await UserModel.create({ username, email, password, status: 1 }); ctx.success({ id: newUser.id, username: newUser.username, email: newUser.email }, '用户创建成功'); } }; ``` ### 控制器方法说明 #### 请求方法格式 框架支持 **GET** 和 **POST** 两种请求方法,**推荐统一使用 POST 请求**: - `"POST /users"`: POST 请求(推荐) - 参数通过请求体传递:`{ id: 123, username: "张三", pageOption: { page: 1, pageSize: 20 } }` - 适用场景:所有接口(查询、创建、更新、删除等) - 优点:参数传递统一、支持复杂数据结构、更安全 - `"GET /users"`: GET 请求(不推荐) - 参数通过查询字符串传递:`?id=123&status=1` - 仅在简单查询场景下使用 #### 上下文方法 ```javascript // 获取请求体数据 const body = ctx.getBody(); // 获取查询参数 const query = ctx.getQuery(); // 获取分页参数(从前端的 pageOption 中获取 page 和 pageSize) // 前端发送格式:{ pageOption: { page: 1, pageSize: 20 } } // 返回值:{ limit: 20, offset: 0 } const { limit, offset } = ctx.getPageSize(); // 成功响应 ctx.success(data, message); // 失败响应 ctx.fail(message, code); ``` ## 🗄️ 数据模型开发 ### 模型定义 ```javascript // models/user.js const Sequelize = require('sequelize'); module.exports = (db) => { return db.define("user", { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true, comment: "用户ID" }, username: { type: Sequelize.STRING(50), allowNull: false, comment: "用户名" }, email: { type: Sequelize.STRING(100), allowNull: false, unique: true, comment: "邮箱" }, password: { type: Sequelize.STRING(255), allowNull: false, comment: "密码" }, avatar: { type: Sequelize.STRING(255), comment: "头像URL" }, status: { type: Sequelize.INTEGER, defaultValue: 1, comment: "状态:0-禁用,1-启用" } }); }; ``` ### 模型关联 ```javascript // 在启动文件中定义关联关系 const businessAssociations = (models) => { // 用户和文章的一对多关系 if (models.user && models.article) { models.user.hasMany(models.article, { foreignKey: 'author_id', as: 'articles', constraints: false // 不创建外键约束 }); models.article.belongsTo(models.user, { foreignKey: 'author_id', as: 'author', constraints: false }); } }; // 在框架初始化时传入 const framework = await Framework.init({ // ... 其他配置 businessAssociations: businessAssociations }); ``` ## 🔐 权限验证 ### Token 验证 框架支持两种认证类型: - `applet`: 小程序端认证 - `admin`: 管理端认证 ### 认证中间件 ```javascript // 在控制器中获取当前用户 "POST /profile": async (ctx) => { // 获取当前登录用户信息 const currentUser = ctx.state.user; if (!currentUser) { return ctx.fail('未登录', 401); } ctx.success(currentUser, '获取用户信息成功'); } ``` ## 📊 API 文档 ### Swagger 配置 框架自动生成 API 文档,访问地址:`http://localhost:3001/api/docs` ### 自定义 Schema ```javascript const config = { customSchemas: { "User": { "type": "object", "properties": { "id": { "type": "integer", "description": "用户ID" }, "username": { "type": "string", "description": "用户名" }, "email": { "type": "string", "format": "email", "description": "邮箱" } } } } }; ``` ## 🚀 部署配置 ### 生产环境配置 ```javascript const config = { env: 'production', db: { // 生产数据库配置 username: process.env.DB_USERNAME, password: process.env.DB_PASSWORD, database: process.env.DB_DATABASE, host: process.env.DB_HOST, port: process.env.DB_PORT, dialect: "mysql", logging: false // 生产环境关闭SQL日志 }, redis: { host: process.env.REDIS_HOST, port: process.env.REDIS_PORT, password: process.env.REDIS_PASSWORD }, server: { port: process.env.PORT || 3001, host: '0.0.0.0' } }; ``` ### PM2 部署 ```javascript // ecosystem.config.js module.exports = { apps: [{ name: 'myapp', script: 'app.js', instances: 'max', exec_mode: 'cluster', env: { NODE_ENV: 'production', PORT: 3001 } }] }; ``` ```bash # 启动应用 pm2 start ecosystem.config.js # 查看状态 pm2 status # 查看日志 pm2 logs myapp ``` ## 🔧 常用功能 ### 日志服务 框架内置了完整的日志服务,支持普通日志、错误日志和请求日志记录。 #### 获取日志服务 ```javascript // 在控制器中获取日志服务 const Framework = require('./dist/node-core-framework.js'); const logsService = Framework.getServices().logsService; #### 基本日志记录 ```javascript // 普通日志 logsService.log('用户登录成功', { userId: 123, username: 'admin' }); logsService.log('数据更新完成', '用户信息已更新'); // 错误日志 try { // 业务逻辑 throw new Error('数据库连接失败'); } catch (error) { logsService.error('数据库操作失败', error); } // 上下文错误日志(包含请求信息) logsService.ctxError(error, ctx); ``` #### 日志文件管理 ```javascript // 日志文件自动管理 // - 按日期分割:log_2024.01.15.log // - 错误日志:logError_2024.01.15.log // - 文件大小超过5MB自动分割:log_2024.01.15_1.log // - 自动创建日志目录 ``` #### 日志API接口 框架提供了日志管理的API接口: ```javascript // 获取所有日志文件列表 GET /admin_api/sys_log/all // 查看日志文件内容 GET /admin_api/sys_log/detail?title=log_2024.01.15.log // 删除指定日志文件 GET /admin_api/sys_log/delete?title=log_2024.01.15.log // 删除所有日志文件 GET /admin_api/sys_log/delete_all ``` #### 日志配置 ```javascript const config = { // 日志目录配置 logPath: './logs', // 相对路径,基于项目根目录 // 其他配置... }; // 日志目录结构 // project/ // ├── logs/ // │ ├── log_2024.01.15.log # 普通日志 // │ ├── logError_2024.01.15.log # 错误日志 // │ └── log_2024.01.15_1.log # 分割后的日志 ``` #### 实际使用示例 ```javascript // controller/user.js const Framework = require('../framework'); const logsService = Framework.getServices().logsService; module.exports = { "POST /login": async (ctx) => { try { const { username, password } = ctx.getBody(); // 记录登录尝试 logsService.log('用户登录尝试', { username, ip: ctx.ip }); // 验证用户 const user = await UserModel.findOne({ where: { username } }); if (!user) { logsService.log('登录失败:用户不存在', { username }); return ctx.fail('用户名或密码错误'); } // 验证密码 const isValid = await bcrypt.compare(password, user.password); if (!isValid) { logsService.log('登录失败:密码错误', { username }); return ctx.fail('用户名或密码错误'); } // 登录成功 logsService.log('用户登录成功', { userId: user.id, username: user.username, ip: ctx.ip }); ctx.success({ token: generateToken(user) }, '登录成功'); } catch (error) { // 记录系统错误 logsService.ctxError(error, ctx); ctx.fail('登录失败,请稍后重试'); } } }; ``` ### Token服务 框架内置了JWT Token服务,支持Token生成、验证、解析和微信数据解密。 #### 获取Token服务 ```javascript // 在控制器中获取Token服务 const Framework = require('./dist/node-core-framework.js'); const tokenService = Framework.getServices().tokenService; // 或者通过框架实例获取 const framework = await Framework.init(config); const tokenService = Framework.getServices().tokenService; ``` #### 基本Token操作 ```javascript // 创建Token const userInfo = { id: 123, username: 'admin', role: 'admin' }; const token = tokenService.create(userInfo); // 解析Token(获取用户信息) const userData = tokenService.parse(token); console.log(userData); // { id: 123, username: 'admin', role: 'admin' } // 验证Token(检查是否有效) const isValid = tokenService.verify(token); console.log(isValid); // true 或 false ``` #### 微信数据解密 ```javascript // 解密微信小程序数据 const encryptedData = 'encrypted_data_from_wechat'; const sessionKey = 'session_key_from_wechat'; const iv = 'iv_from_wechat'; const decryptedData = tokenService.decryptWxData(encryptedData, sessionKey, iv); console.log(decryptedData); // 解密后的用户信息 ``` #### MD5加密 ```javascript // MD5加密 const password = '123456'; const encryptedPassword = tokenService.getMd5(password); console.log(encryptedPassword); // e10adc3949ba59abbe56e057f20f883e ``` #### 实际使用示例 ```javascript // controller/auth.js const Framework = require('../framework'); const tokenService = Framework.getServices().tokenService; module.exports = { "POST /login": async (ctx) => { try { const { username, password } = ctx.getBody(); // 验证用户 const user = await UserModel.findOne({ where: { username } }); if (!user) { return ctx.fail('用户不存在'); } // 验证密码 const isValidPassword = await bcrypt.compare(password, user.password); if (!isValidPassword) { return ctx.fail('密码错误'); } // 生成Token const userInfo = { id: user.id, username: user.username, role: user.role }; const token = tokenService.create(userInfo); ctx.success({ token, user: userInfo }, '登录成功'); } catch (error) { ctx.fail('登录失败'); } }, "POST /verify": async (ctx) => { const { token } = ctx.getBody(); if (!token) { return ctx.fail('缺少Token'); } const userData = tokenService.parse(token); if (!userData) { return ctx.fail('Token无效'); } ctx.success(userData, 'Token验证成功'); } }; ``` ### Redis服务 框架内置了Redis缓存服务,支持数据缓存、分布式锁等功能。 #### 获取Redis服务 ```javascript // 在控制器中获取Redis服务 const Framework = require('./dist/node-core-framework.js'); const redisService = Framework.getServices().redisService; // 或者通过框架实例获取 const framework = await Framework.init(config); const redisService = Framework.getServices().redisService; ``` #### 基本缓存操作 ```javascript // 设置缓存(默认12小时过期) await redisService.set('user:123', JSON.stringify({ name: '张三', age: 25 })); // 设置缓存(自定义过期时间,单位:秒) await redisService.set('session:abc', 'session_data', 3600); // 1小时 // 获取缓存 const userData = await redisService.get('user:123'); console.log(JSON.parse(userData)); // { name: '张三', age: 25 } // 删除缓存 await redisService.del('user:123'); ``` #### 原子操作 ```javascript // 原子设置(仅当key不存在时设置) const success = await redisService.setIfAbsent('lock:order:123', 'locked', 300); if (success) { console.log('获取锁成功'); // 执行业务逻辑 await redisService.del('lock:order:123'); // 释放锁 } else { console.log('获取锁失败,资源被占用'); } ``` #### 连接状态管理 ```javascript // 检查Redis连接状态 const isConnected = redisService.isConnected(); console.log('Redis连接状态:', isConnected); // 手动重连 redisService.reconnect(); // 关闭连接 redisService.close(); ``` #### 实际使用示例 ```javascript // controller/cache.js const Framework = require('../framework'); const redisService = Framework.getServices().redisService; module.exports = { "POST /cache/user/detail": async (ctx) => { const { id } = ctx.getBody(); // 从请求体获取 id if (!id) { return ctx.fail('用户ID不能为空'); } const cacheKey = `user:${id}`; try { // 先尝试从缓存获取 let userData = await redisService.get(cacheKey); if (userData) { // 缓存命中 console.log('从缓存获取用户数据'); return ctx.success(JSON.parse(userData)); } // 缓存未命中,从数据库获取 const user = await UserModel.findByPk(id); if (!user) { return ctx.fail('用户不存在'); } // 存入缓存(1小时过期) await redisService.set(cacheKey, JSON.stringify(user.toJSON()), 3600); ctx.success(user); } catch (error) { ctx.fail('获取用户信息失败'); } }, "POST /cache/clear": async (ctx) => { const { pattern } = ctx.getBody(); // 清除指定模式的缓存 // 注意:这里需要根据实际需求实现模式匹配删除 await redisService.del(pattern); ctx.success(null, '缓存清除成功'); } }; ``` ### Swagger服务 框架内置了Swagger API文档服务,支持自动生成API文档和Schema。 #### 获取Swagger服务 ```javascript // 在控制器中获取Swagger服务 const Framework = require('./dist/node-core-framework.js'); const swaggerService = Framework.getServices().createSwaggerService(); // 或者通过框架实例获取 const framework = await Framework.init(config); const swaggerService = Framework.getServices().createSwaggerService(); ``` #### 生成API文档 ```javascript // 生成Swagger规范 const swaggerSpec = swaggerService.generateSpecs(req, res); // 获取Swagger配置 const swaggerConfig = swaggerService.generateSwaggerConfig(req, res); // 获取Swagger选项 const swaggerOptions = swaggerService.getSwaggerOptions(); ``` #### 安全配置管理 ```javascript // 获取当前安全配置 const securityConfig = swaggerService.getCurrentSecurityConfig(req, res); // 更新安全配置 const newConfig = [ { 'admin-token': [] }, { 'applet-token': [] } ]; const result = swaggerService.updateSecurityConfig(req, res, newConfig); // 清除安全配置 swaggerService.clearSecurityConfigCookie(res); ``` #### 实际使用示例 ```javascript // controller/docs.js const Framework = require('../framework'); module.exports = { "POST /api-docs": async (ctx) => { const swaggerService = Framework.getServices().createSwaggerService(); // 生成Swagger规范 const swaggerSpec = swaggerService.generateSpecs(ctx.request, ctx.response); ctx.response.type = 'application/json'; ctx.response.body = swaggerSpec; }, "POST /swagger-ui": async (ctx) => { // 返回Swagger UI页面 const swaggerUIManager = Framework.getSwaggerUIManager(); const html = swaggerUIManager.getSwaggerUIHTML(); ctx.response.type = 'text/html'; ctx.response.body = html; } }; ``` ### 平台项目服务 框架内置了平台项目服务,支持与外部平台的交互。 #### 获取平台项目服务 ```javascript // 在控制器中获取平台项目服务 const Framework = require('./dist/node-core-framework.js'); const platformService = Framework.getServices().platformProjectService; // 或者通过框架实例获取 const framework = await Framework.init(config); const platformService = Framework.getServices().platformProjectService; ``` #### 基本平台操作 ```javascript // 获取所有模型 const models = await platformService.modelAll(); // 生成表单 const formData = await platformService.formGenerate({ id: 'form_id' }); // 创建表单 const createResult = await platformService.createForm({ name: '用户表单', fields: ['name', 'email', 'phone'] }); // 更新表单 const updateResult = await platformService.updateForm({ id: 'form_id', name: '更新后的表单' }); // 删除表单 const deleteResult = await platformService.delteForm({ id: 'form_id' }); // 重新生成模型 const modelResult = await platformService.modelGenerate({ id: 'model_id' }); ``` #### 文件下载 ```javascript // 下载平台文件 const downloadResult = await platformService.downloadPlatformFile('/path/to/file'); ``` #### 实际使用示例 ```javascript // controller/platform.js const Framework = require('../framework'); const platformService = Framework.getServices().platformProjectService; module.exports = { "POST /platform/models": async (ctx) => { try { const models = await platformService.modelAll(); ctx.success(models); } catch (error) { ctx.fail('获取模型列表失败'); } }, "POST /platform/form": async (ctx) => { try { const formData = ctx.getBody(); const result = await platformService.createForm(formData); ctx.success(result, '表单创建成功'); } catch (error) { ctx.fail('表单创建失败'); } } }; ``` ### HTTP服务 框架内置了HTTP请求服务,支持各种HTTP请求方法。 #### 获取HTTP服务 ```javascript // 直接引入HTTP服务 const { postPlatformUrl, downloadPlatformFile, post, get } = require('./services/http'); ``` #### 基本HTTP操作 ```javascript // GET请求 const getData = await get('https://api.example.com/users', { page: 1, limit: 10 }); // POST请求 const postData = await post('https://api.example.com/users', { name: '张三', email: 'zhangsan@example.com' }); // POST表单数据 const formData = await postFormData('https://api.example.com/upload', { file: 'file_content', name: 'filename.jpg' }); ``` #### 平台API调用 ```javascript // 调用平台API const platformData = await postPlatformUrl('/form/generate', { id: 'form_id' }); // 下载平台文件 await downloadPlatformFile('/path/to/file', './local/path/file'); ``` #### 实际使用示例 ```javascript // controller/external.js const { post, get } = require('../services/http'); module.exports = { "POST /external/users": async (ctx) => { try { // 调用外部API const users = await get('https://jsonplaceholder.typicode.com/users'); ctx.success(users); } catch (error) { ctx.fail('获取外部数据失败'); } }, "POST /external/sync": async (ctx) => { try { const { data } = ctx.getBody(); // 同步数据到外部系统 const result = await post('https://api.external.com/sync', data); ctx.success(result, '数据同步成功'); } catch (error) { ctx.fail('数据同步失败'); } } }; ``` ### 分页查询 框架提供了 `ctx.getPageSize()` 方法来获取分页参数。 **前端发送格式**: ```javascript // 方式1: 通过 POST 请求体发送 { pageOption: { page: 1, // 页码,从1开始 pageSize: 20 // 每页数量 } } // 方式2: 通过 GET 查询参数发送 // GET /api/users?pageOption[page]=1&pageOption[pageSize]=20 ``` **后端使用示例**: ```javascript "POST /users/list": async (ctx) => { // ctx.getPageSize() 从前端的 pageOption 中获取 page 和 pageSize // 返回值:{ limit: 20, offset: 0 } // limit: 每页数量 (pageSize) // offset: 跳过的记录数 ((page - 1) * pageSize) const { limit, offset } = ctx.getPageSize(); const { username, status } = ctx.getBody(); // 从请求体获取查询条件 // 构建查询条件 const where = {}; if (username) { where.username = { [Op.like]: `%${username}%` }; } if (status !== undefined) { where.status = status; } const users = await UserModel.findAndCountAll({ where, limit, offset, order: [['create_time', 'DESC']] }); ctx.success(users, '获取用户列表成功'); } ``` ### 文件上传 ```javascript "POST /upload": async (ctx) => { const file = ctx.request.files.file; if (!file) { return ctx.fail('请选择文件'); } // 处理文件上传逻辑 const fileName = `${Date.now()}_${file.name}`; const filePath = `./upload/${fileName}`; // 保存文件 const fs = require('fs'); fs.writeFileSync(filePath, file.buffer); ctx.success({ fileName, filePath, size: file.size }, '文件上传成功'); } ``` ### 错误处理 ```javascript // 全局错误处理 framework.app.on('error', (err, ctx) => { console.error('服务器错误:', err); // 记录错误日志 const logger = require('./services/logs'); logger.error('服务器错误', { error: err.message, stack: err.stack, url: ctx.url, method: ctx.method }); }); ``` ## 📝 最佳实践 ### 1. 控制器设计 ```javascript // 好的实践:统一使用 POST 请求,清晰的路由命名 module.exports = { "POST /users/list": getUserList, // 获取用户列表 "POST /users/detail": getUserDetail, // 获取用户详情 "POST /users/create": createUser, // 创建用户 "POST /users/update": updateUser, // 更新用户 "POST /users/delete": deleteUser // 删除用户 }; // 查询列表示例:支持分页和条件查询 async function getUserList(ctx) { const { limit, offset } = ctx.getPageSize(); // 从 pageOption 获取分页参数 const { username, status } = ctx.getBody(); // 从请求体获取查询条件 // 构建查询条件 const where = {}; if (username) { where.username = { [Op.like]: `%${username}%` }; } if (status !== undefined) { where.status = status; } const users = await UserModel.findAndCountAll({ where, limit, offset, order: [['create_time', 'DESC']] }); ctx.success(users, '获取用户列表成功'); } // 查询详情示例 async function getUserDetail(ctx) { const { id } = ctx.getBody(); // 从请求体获取 id if (!id) { return ctx.fail('用户ID不能为空'); } const user = await UserModel.findByPk(id); if (!user) { return ctx.fail('用户不存在'); } ctx.success(user, '获取成功'); } // 创建示例 async function createUser(ctx) { const { username, email, password } = ctx.getBody(); if (!username || !email || !password) { return ctx.fail('用户名、邮箱和密码不能为空'); } const newUser = await UserModel.create({ username, email, password }); ctx.success(newUser, '创建成功'); } // 更新示例 async function updateUser(ctx) { const { id, username, email } = ctx.getBody(); if (!id) { return ctx.fail('用户ID不能为空'); } await UserModel.update({ username, email }, { where: { id } }); ctx.success(null, '更新成功'); } // 删除示例 async function deleteUser(ctx) { const { id } = ctx.getBody(); if (!id) { return ctx.fail('用户ID不能为空'); } await UserModel.destroy({ where: { id } }); ctx.success(null, '删除成功'); } ``` ### 2. 数据验证 ```javascript // 好的实践:参数验证 "POST /users": async (ctx) => { const { username, email, password } = ctx.getBody(); // 参数验证 if (!username || !email || !password) { return ctx.fail('用户名、邮箱和密码不能为空'); } // 邮箱格式验证 const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(email)) { return ctx.fail('邮箱格式不正确'); } // 业务逻辑... } ``` ### 3. 错误处理 ```javascript // 好的实践:统一的错误处理 "POST /users": async (ctx) => { try { const { username, email, password } = ctx.getBody(); // 验证参数 validateUserInput({ username, email, password }); // 检查用户是否存在 await checkUserExists(email); // 创建用户 const user = await createUser({ username, email, password }); ctx.success(user, '用户创建成功'); } catch (error) { // 统一错误处理 if (error.code === 'VALIDATION_ERROR') { return ctx.fail(error.message, 400); } if (error.code === 'USER_EXISTS') { return ctx.fail(error.message, 409); } // 未知错误 console.error('创建用户失败:', error); ctx.fail('服务器内部错误', 500); } } ``` ## ❓ 常见问题 ### Q1: 数据库连接失败 **解决方案**: 1. 检查数据库服务是否启动 2. 验证配置文件中的数据库连接信息 3. 确认数据库用户权限 ### Q2: 端口被占用 **解决方案**: ```bash # 查看端口占用 netstat -ano | findstr :3001 # 终止进程 taskkill /PID <进程ID> /F ``` ### Q3: 模块找不到 **解决方案**: ```bash # 重新安装依赖 npm install # 清除缓存 npm cache clean --force ``` ### Q4: 权限验证失败 **解决方案**: 1. 检查请求头中的 token 2. 确认 token 格式正确 3. 验证 token 是否过期 ## 📚 更多资源 - [框架源码](https://github.com/your-repo/node-core-framework) - [API 文档](http://localhost:3001/api/docs) - [示例项目](./examples/) --- **🎉 恭喜!你已经掌握了 Node Core Framework 的基本使用方法!** 如有问题,请查看项目文档或提交 Issue。