# admin-server-egg **Repository Path**: BluesYoung-web/admin-server-egg ## Basic Information - **Project Name**: admin-server-egg - **Description**: 后台管理系统的配套后端(基于egg) - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2021-11-10 - **Last Updated**: 2022-05-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # admin-server-koa - 后台管理系统配套的后端查询(egg版) - 正在开发中...... ## sequelize 使用步骤 ### 前期准备 ```bash # 创建数据库 mysql -u root -e 'CREATE DATABASE IF NOT EXISTS `数据库名称`;' # 项目根目录新建 .sequelizerc 文件,内容如下: ### 'use strict'; const path = require('path'); module.exports = { config: path.join(__dirname, 'database/config.json'), 'migrations-path': path.join(__dirname, 'database/migrations'), 'seeders-path': path.join(__dirname, 'database/seeders'), 'models-path': path.join(__dirname, 'app/model'), }; ### # 生成配置文件和目录 npx sequelize init:config npx sequelize init:migrations # 修改配置文件的内容(database/confg.json)为对应的数据库配置 # 生成 users 表迁移文件 npx sequelize migration:generate --name=init-users ### 'use strict'; module.exports = { // 在执行数据库升级时调用的函数,创建 users 表 up: async (queryInterface, Sequelize) => { const { INTEGER, DATE, STRING } = Sequelize; await queryInterface.createTable('users', { id: { type: INTEGER, primaryKey: true, autoIncrement: true }, name: STRING(30), age: INTEGER, created_at: DATE, updated_at: DATE, }); }, // 在执行数据库降级时调用的函数,删除 users 表 down: async queryInterface => { await queryInterface.dropTable('users'); }, }; ### # 升级数据库 npx sequelize db:migrate # 如果有问题需要回滚,可以通过 `db:migrate:undo` 回退一个变更 # npx sequelize db:migrate:undo # 可以通过 `db:migrate:undo:all` 回退到初始状态 # npx sequelize db:migrate:undo:all ``` ### 代码编写 - 在 `app/model/` 目录下实现对应的 `Model` - 编写之后可以通过 `app.model.User` 或者 `ctx.model.User` 访问 ```js 'use strict'; // app/model/user.js module.exports = app => { const { STRING, INTEGER, DATE } = app.Sequelize; const User = app.model.define('user', { id: { type: INTEGER, primaryKey: true, autoIncrement: true }, name: STRING(30), age: INTEGER, created_at: DATE, updated_at: DATE, }); return User; }; ``` - 编写 `service` 进行数据库的读写 - 编写之后可以通过 `ctx.service.user` 进行调用 - 推荐使用顺序:`router -> controller -> service` ```js const { Service } = require('egg'); module.exports = class UserService extends Service { async getAll() { const { ctx } = this; const users = await ctx.model.User.findAll(); /* 分页 const query = { limit: 10, offset: 1 }; ctx.body = await ctx.model.User.findAll(query); */ return users; } async add(name, age) { const { ctx } = this; const user = await ctx.model.User.create({ name, age }); return user; } async getById(id) { const { ctx } = this; const user = await ctx.model.User.findByPk(id); return user; } async update(id, name, age) { const user = await this.getById(id); if (user) { await user.update({ name, age }); return user; } else { return '查无此人'; } } async delById(id) { const user = await this.getById(id); if (user) { await user.destroy(); return '删除成功'; } else { return '查无此人'; } } } ``` ### 单元测试 - 初始化测试数据库 `cross-env NODE_ENV test npx sequelize db:migrate:up` - 安装假数据依赖 `yarn add -D factory-girl` - 定义 factory-girl 的数据模型到 `test/factories.js` 中 ```js // test/factories.js 'use strict'; const { factory } = require('factory-girl'); module.exports = app => { // 可以通过 app.factory 访问 factory 实例 app.factory = factory; // 定义 user 和默认数据 factory.define('user', app.model.User, { name: factory.sequence('User.name', n => `name_${n}`), age: 18, }); }; ``` - 初始化文件 `test/.setup.js`,引入 factory,并确保测试执行完后清理数据,避免被影响 ```js const { app } = require('egg-mock/bootstrap'); const factories = require('./factories'); before(() => factories(app)); afterEach(async () => { // clear database after each test case await Promise.all([ app.model.User.destroy({ truncate: true, force: true }), ]); }); ``` - 编写测试用例(内容源自官网,与实际代码存在出入,待修正) ```js // test/app/controller/users.test.js const { assert, app } = require('egg-mock/bootstrap'); describe('test/app/controller/users.test.js', () => { describe('GET /users', () => { it('should work', async () => { // 通过 factory-girl 快速创建 user 对象到数据库中 await app.factory.createMany('user', 3); const res = await app.httpRequest().get('/users?limit=2'); assert(res.status === 200); assert(res.body.length === 2); assert(res.body[0].name); assert(res.body[0].age); }); }); describe('GET /users/:id', () => { it('should work', async () => { const user = await app.factory.create('user'); const res = await app.httpRequest().get(`/users/${user.id}`); assert(res.status === 200); assert(res.body.age === user.age); }); }); describe('POST /users', () => { it('should work', async () => { app.mockCsrf(); let res = await app.httpRequest().post('/users') .send({ age: 10, name: 'name', }); assert(res.status === 201); assert(res.body.id); res = await app.httpRequest().get(`/users/${res.body.id}`); assert(res.status === 200); assert(res.body.name === 'name'); }); }); describe('DELETE /users/:id', () => { it('should work', async () => { const user = await app.factory.create('user'); app.mockCsrf(); const res = await app.httpRequest().delete(`/users/${user.id}`); assert(res.status === 200); }); }); }); ```