Egg.js框架的简单使用

创建

  创建项目文件夹,在文件下打开cmd:

npm init egg --type=simple
npm install
npm run dev

静态文件目录

app/public
  创建html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>我是静态网页</h1>
</body>
</html>

访问:
在这里插入图片描述

控制器和路由

  1. 直接响应数据或者渲染模板
  2. 接受用户的输入
  3. 与路由建立对应关系
      this.ctx可以获取到当前请求的上下文对象,通过此对象可以便捷的获取到请求与响应的属性与方法。

创建控制器

app/controller下创建js文件:
fruits.js

'use strict'; // *严格模式

const Controller = require('egg').Controller;
class FruitsController extends Controller {
	async index() {
		const { ctx } = this;
		ctx.body = '列表';
	}
}
module.exports = FruitsController;

添加路由

app/router.js 添加要访问的路由

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.get('/', controller.home.index);
  router.get('/fruits', controller.fruits.index);  //添加fruits路由
};

路由传参

query

fruits.js

'use strict'; // *严格模式

const Controller = require('egg').Controller;
class FruitsController extends Controller {
	async index() {
		const { ctx } = this;
		const index = ctx.request.body;
		console.log(index)
		ctx.body = '列表';
	}
}
module.exports = FruitsController;

访问:
在这里插入图片描述
打印:
在这里插入图片描述

params

app/router.js

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.get('/', controller.home.index);
  router.get('/fruits', controller.fruits.index);  //添加fruits路由
  router.get('/fruits/:id', controller.fruits.getId);
};

fruits.js

'use strict'; // *严格模式

const Controller = require('egg').Controller;
class FruitsController extends Controller {
	async index() {
		const { ctx } = this;
		const index = ctx.request.body;
		console.log(index)
		ctx.body = '列表';
	}
	async getId() {
	   const { ctx } = this;
	    const id = ctx.params.id;
	    console.log(id);
	    ctx.body = `
	        <h1 style='color:red;'>传递的id值是${id}</h1>
	      `;
	  }
}
module.exports = FruitsController;

访问:
在这里插入图片描述
打印:
在这里插入图片描述

POST请求

  上面介绍的paramsqueryGET请求方式,下面讲一下POST请求:
获取post请求的参数:this.ctx.request.body

CSRF

  CSRF是指跨站请求伪造,Egg中对post请求做了一些安全验证,可以在config\config.default.js文件中设置验证:

/* eslint valid-jsdoc: "off" */

'use strict';

/**
 * @param {Egg.EggAppInfo} appInfo app info
 */
module.exports = appInfo => {
  /**
   * built-in config
   * @type {Egg.EggAppConfig}
   **/
  const config = exports = {};

  // use for cookie sign key, should change to your own and keep security
  config.keys = appInfo.name + '_1620442177015_7667';

  // add your middleware config here
  config.middleware = [];

  // add your user config here
  const userConfig = {
    // myAppName: 'egg',
  };
  //post验证
  config.security = {
    csrf: {
      enable: false,
    },
  };
 return {
    ...config,
    ...userConfig,
  };
};

RESTful风格的URL定义

  restful风格的url可以简化路由文件

router.resources('posts','/api/posts',controller.posts); //一个方法同时定义增删改查
MethodsPathRouter NameController.Action
GET/postspostsapp.controllers.posts.index
GET/posts/newnew_postsapp.controllers.posts.new
GET/posts/:idpostapp.controllers.posts.show
GET/posts/:id/editedit _postapp.controllers.posts.edit
POST/postspostsapp.controllers.posts.create
PUT/posts/:idpostapp.controllers.posts.update
DELETE/posts/:idpostapp.controllers.posts.destroy

demo:
app\router.js

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.get('/', controller.home.index);
  // !很繁琐
  // router.get('/fruits', controller.fruits.index);
  // router.get('/fruits/:id', controller.fruits.getId);
  // router.get('/createfruit', controller.fruits.createPage);
  // router.post('/createfruit', controller.fruits.createFruit);
  // * RESTful风格的URL定义
  router.resources('fruits', '/fruits', controller.fruits);
};

app\controller\fruits.js

'use strict'; // *严格模式

const Controller = require('egg').Controller;
let fruitList = [ '香蕉', '苹果', '橘子' ];

class FruitsController extends Controller {

  // ? /fruits get请求
  async index() {
    // this.ctx; // ?上下文对象
    const { ctx } = this;
    ctx.body = fruitList;
  }
  async new() {
    const { ctx } = this;
    ctx.body = `
        <form method='post' action='/fruits'>
            <input name='fruitsName' type='text'/>
            <button>添加</button>
        </form>
    `;
  }
  // ? post
  async create() {
    const { ctx } = this;
    const fruit = ctx.request.body.fruit;
    fruitList.push(fruit);
    // ctx.body = '添加成功';
    // ?跳转到fruits页面,实现get请求
    // *重定向
    ctx.redirect('/fruits');
  }
  // ?delete
  async destroy() {
    const { ctx } = this;
    const id = ctx.params.id;
    fruitList.splice(id, 1);
    ctx.body = '删除成功';
  }

}

module.exports = FruitsController;

Egg插件

numjucks模板插件

安装:

npm install --save egg-view-nunjucks

配置:
config\plugin.js中引入:

'use strict';

/** @type Egg.EggPlugin */
module.exports = {
  // had enabled by egg
  // static: {
  //   enable: true,
  // }
  nunjucks: {
    enable: true,
    package: 'egg-view-nunjucks',
  },
};

config\config.default.js中配置

/* eslint valid-jsdoc: "off" */

'use strict';

/**
 * @param {Egg.EggAppInfo} appInfo app info
 */
module.exports = appInfo => {
  /**
   * built-in config
   * @type {Egg.EggAppConfig}
   **/
  const config = exports = {};

  // use for cookie sign key, should change to your own and keep security
  config.keys = appInfo.name + '_1620442177015_7667';

  // add your middleware config here
  config.middleware = [];

  // add your user config here
  const userConfig = {
    // myAppName: 'egg',
  };

  config.security = {
    csrf: {
      enable: false,
    },
  };
  config.view = {
    defaultViewEngine: 'nunjucks',
  };

  return {
    ...config,
    ...userConfig,
  };
};

在view目录中创建模板文件,并在控制器中使用render方法渲染模板
app\view\index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>nunjucks模板</h1>
</body>
</html>
'use strict';

const Controller = require('egg').Controller;

class HomeController extends Controller {
  async index() {
    const { ctx } = this;
    await ctx.render('index');
  }
}

module.exports = HomeController;

跨域请求配置插件 egg-cors

安装:

npm install --save egg-cors

配置:
config\plugin.js中引入:

'use strict';

/** @type Egg.EggPlugin */
module.exports = {
  // had enabled by egg
  // static: {
  //   enable: true,
  // }
  nunjucks: {
    enable: true,
    package: 'egg-view-nunjucks',
  },
  cors: {
    enable: true,
    package: 'egg-cors',
  },
};

config\config.default.js中配置

/* eslint valid-jsdoc: "off" */

'use strict';

/**
 * @param {Egg.EggAppInfo} appInfo app info
 */
module.exports = appInfo => {
  /**
   * built-in config
   * @type {Egg.EggAppConfig}
   **/
  const config = exports = {};

  // use for cookie sign key, should change to your own and keep security
  config.keys = appInfo.name + '_1620442177015_7667';

  // add your middleware config here
  config.middleware = [];

  // add your user config here
  const userConfig = {
    // myAppName: 'egg',
  };

  config.security = {
    csrf: {
      enable: false,
    },
  };
  config.view = {
    defaultViewEngine: 'nunjucks',
  };
  config.cors = {
    origin: '*',
    allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH',
  };
  return {
    ...config,
    ...userConfig,
  };
};

服务器如何识别用户

session识别用户

app\view\index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>首页</h1>
    <form action="/logout" method="post">
        <button>注销用户</button>
    </form>
</body>
</html>

app\view\login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        input{
            display: block;
        }
    </style>
</head>
<body>
    <form action="/login" method="post">
        <label for="">账号</label>
        <input type="text" name="username" id="">
        <label for="">密码</label>
        <input type="password" name="password" id="">
        <button>登录</button>
    </form>
</body>
</html>

app\controller\home.js

'use strict';

const Controller = require('egg').Controller;

class HomeController extends Controller {
  async index() {
    const { ctx } = this;
    if (ctx.session.user) {
      await ctx.render('index');
    } else {
      ctx.redirect('/login');
    }
  }
  async getData() {
    const { ctx } = this;
    ctx.body = 'hello egg';
  }
  async login() {
    const { ctx } = this;
    await ctx.render('login');
  }
  async doLogin() {
    const { ctx } = this;
    const username = ctx.request.body.username;
    const password = ctx.request.body.password;
    if (username === 'mgd' && password === '123') {
      ctx.session.user = username;
      ctx.redirect('/');
    } else {
      ctx.redirect('/login');
    }
  }
  async logout() {
    const { ctx } = this;
    ctx.session.user = '';
    ctx.redirect('/login');
  }
}

module.exports = HomeController;

app\router.js

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.get('/', controller.home.index);
  router.get('/login', controller.home.login);
  router.post('/login', controller.home.doLogin);
  router.post('/logout', controller.home.logout);
};

JWT(Json Web Token)识别用户

安装:

npm install --save egg-jwt

配置:
config\plugin.js中引入:

'use strict';

/** @type Egg.EggPlugin */
module.exports = {
  // had enabled by egg
  // static: {
  //   enable: true,
  // }
  nunjucks: {
    enable: true,
    package: 'egg-view-nunjucks',
  },
  cors: {
    enable: true,
    package: 'egg-cors',
  },
  jwt: {
    enable: true,
    package: 'egg-jwt',
  },
};

config\config.default.js中配置

/* eslint valid-jsdoc: "off" */

'use strict';

/**
 * @param {Egg.EggAppInfo} appInfo app info
 */
module.exports = appInfo => {
  /**
   * built-in config
   * @type {Egg.EggAppConfig}
   **/
  const config = exports = {};

  // use for cookie sign key, should change to your own and keep security
  config.keys = appInfo.name + '_1620442177015_7667';

  // add your middleware config here
  config.middleware = [];

  // add your user config here
  const userConfig = {
    // myAppName: 'egg',
  };

  config.security = {
    csrf: {
      enable: false,
    },
  };
  config.view = {
    defaultViewEngine: 'nunjucks',
  };
  config.cors = {
    origin: '*',
    allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH',
  };
  config.jwt = {
    secret: 'maguodong', //secret不能泄露
  };
  return {
    ...config,
    ...userConfig,
  };
};

app\controller\jwt.js

'use strict';

const Controller = require('egg').Controller;
class JwtController extends Controller {
  async index() {
    const { ctx } = this;
    const user = {
      username: 'mgd',
    };
    // ?egg-jwt引入后就可使用
    // ?用户登录
    const token = this.app.jwt.sign(user, this.app.config.jwt.secret);
    // ctx.body = token;
    try {
      const decode = this.app.jwt.verify(token, this.app.config.jwt.secret);
      ctx.body = decode;
    } catch (e) {
      ctx.body = 'token未能通过验证';
    }
  }
  async doLogin() {
    const { ctx } = this;
    const user = ctx.request.body.user;
    if (user.username === 'mgd' && user.password === '123') {
      const user_jwt = { username: user.username };
      const token = this.app.jwt.sign(user_jwt, this.app.config.jwt.secret);
      ctx.body = {
        code: 200,
        token,
      };
    } else {
      ctx.body = {
        code: 400,
        msg: '用户名或密码错误',
      };
    }
  }

  async getMessage() {
    const { ctx } = this;
    ctx.body = 'hello jwt';
  }
}
module.exports = JwtController;

app\router.js

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.get('/', controller.home.index);
  router.get('/jwt', controller.jwt.index);
  router.post('/jwtlogin', controller.jwt.doLogin);
  router.get('/jwtmessage', controller.jwt.getMeaaage);
};

新建vue项目测试:
Login.vue

<template>
    <h1>登录</h1>
    <form @submit.prevent="login">
        <label for="">账号</label>
        <input type="text" v-model="user.username">
        <label for="">密码</label>
        <input type="password" v-model="user.password">
        <button>登录</button>
    </form>
</template>

<script>
import { reactive, toRefs } from 'vue'
import { useRouter } from 'vue-router';
import { doLogin } from '../server/loginServer.js'
export default {
    
    setup () {
        const router = useRouter();
        const state = reactive({
            user:{
                username:'',
                password:''
            }
        })
        async function login(){
            await doLogin({user:state.user}).then(ret=>{
                console.log(ret);   
                if(ret.data.code==200){
                    localStorage.setItem('token',ret.data.token)
                    console.log(ret.data.token);
                    router.push("/")
                }
            })
        }
        return {
            ...toRefs(state),
            login
        }
    }
}
</script>

<style lang="less" scoped>
    
</style>

Home.vue

<template>
    <h1>首页</h1>
    <button @click="getMessage">获取数据</button>
    <button @click="logOut">注销用户</button>
    <HelloWorld></HelloWorld>
</template>

<script>
import { reactive, toRefs } from 'vue'
import { getData } from '../server/homeServer.js'
import HelloWorld from '../components/HelloWorld.vue'
export default {
    components:{
        HelloWorld
    },
    setup () {
        const state = reactive({
            count: 0,
        })
        async function getMessage() {
            let token = localStorage.getItem("token");
            await getData(null,{headers:{
                token
            }}).then(ret=>{
                console.log(ret);
            })
        }
        async function logOut() {
            localStorage.removeItem('token');
            location.reload()
        }
        return {
            ...toRefs(state),
            getMessage,
            logOut,
        }
    }
}
</script>

<style lang="less" scoped>

</style>

router.js

import Home from '../view/Home.vue'
import Login from '../view/Login.vue'
import {createRouter, createWebHistory} from 'vue-router'
const router = createRouter({
    history:createWebHistory(),
    routes:[
        {path:"/",component:Home,name:"home"},
        {path:"/login",component:Login,name:"login"},

    ]
})
router.beforeEach((to, from, next) => {
  if(to.path === '/login'){
    next()
  }else{
    if(localStorage.getItem('token')){
        next();
    }else{
        next('/login');
    }
  }
})
export default router

homeServer.js

import http from '../Api/Api'
const get = (url, params = {},header={}) =>
    http.get(
        url,
        params,
        header
    )

const getData = (query={},header) => {
    get('jwtmessage',query,header)
}
export {
    getData,
}

loginServer.js

import http from '../Api/Api'
const post = (url, data = {}, isBody) =>
    http.post(
        url,
        data,
        isBody
    )

const doLogin = query => post('jwtlogin',query)

export {
    doLogin,
}

api.js

import axios from "axios";
import qs from 'qs';
// 导入 NProgress 包对应的 css 与 js
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
// import {getStorage} from '../utils/Storage.js'

// axios.defaults.baseURL = 'https://oj.s001.xin/api'  //正式
axios.defaults.baseURL = 'http://127.0.0.1:7001' //测试 

//post请求头
axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8";
//设置超时
axios.defaults.timeout = 10000;


axios.interceptors.request.use(config => {
  // console.log(config)
  NProgress.start()
  // config.headers.Authorization = window.sessionStorage.getItem('token')
  return config
})
// 在 response 拦截器中,隐藏进度条 NProgress.done()
axios.interceptors.response.use(config => {
  NProgress.done()
  return config
})

function post(url, data, isBody = true) {
  if (isBody) {
    axios.defaults.headers.post["Content-Type"] = 'application/json';
  } else {
    data = qs.stringify(data)
  }
  return new Promise((resolve, reject) => {
    axios({
        method: 'post',
        url,
        data
      })
      .then(res => {
        resolve(res)
      })
      .catch(err => {
        reject(err)
      });
  })
};

function get(url, data, headers) {
  if(headers.headers){
    console.log(headers);
    axios.defaults.headers.get["token"] = headers.headers.token;
  }
  return new Promise((resolve, reject) => {
    axios({
        method: 'get',
        url,
        params: data,
      })
      .then(res => {
        resolve(res)
      })
      .catch(err => {
        reject(err)
      })
  })
};

function put(url, data) {
  return new Promise((resolve, reject) => {
    axios({
        method: 'put',
        url,
        params: data,
      })
      .then(res => {
        resolve(res)
      })
      .catch(err => {
        reject(err)
      })
  })
};

function deletes(url, data) {
  return new Promise((resolve, reject) => {
    axios({
        method: 'delete',
        url,
        params: data,
      })
      .then(res => {
        resolve(res)
      })
      .catch(err => {
        reject(err)
      })
  })
};
export default {
  post,
  get,
  put,
  deletes
};

中间件

  egg是一个基于koa的函数,中间件是一个函数,在请求与响应之间执行。

在Egg中定义中间件

app\middleware\checkToken.js

'use strict';
function checkToken() {
  return async function(ctx, next) {
    try {
      // ?获取token
      const token = ctx.request.header.token;
      // ?校验token
      // ?1.获取app实例
      const decode = ctx.app.jwt.verify(token, ctx.app.config.jwt.secret);
      if (decode.username) {
        await next();
      } else {
        ctx.body = {
          code: 400,
          msg: '用户校验失败',
        };
      }
    } catch (e) {
      ctx.body = {
        code: 400,
        msg: 'token校验失败',
      };
    }
  };
}
module.exports = checkToken;

执行中间件需要调用:
app\router.js

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.get('/', controller.home.index);

  router.get('/jwt', controller.jwt.index);
  router.post('/jwtlogin', controller.jwt.doLogin);
  // router.get('/jwtmessage', controller.jwt.getMeaaage);
  // ?添加中间件
  router.get('/jwtmessage', app.middleware.checkToken(), controller.jwt.getMeaaage);
};

数据持久化

ORM

对象关系映射(Object Relational Mapping 。简称ORM)

  1. 将数据从对象的形式转换成表格的形式
  2. sequelzie是一个基于nodeorm框架
  3. 通过egg-sequelize,可以直接使用sequelize提供的方法操作数据库,而不需要手动写SQL语句

安装和使用sequelize

步骤:

  1. 下载:npm install --save egg-sequelize mysql2
  2. plugin.js文件中引入插件
  3. config.default.js文件中配置数据库连接
  4. app/model文件中创建数据模型
  5. 添加app.js文件,初始化数据库
    config\plugin.js
'use strict';

/** @type Egg.EggPlugin */
module.exports = {
  // had enabled by egg
  // static: {
  //   enable: true,
  // }
  nunjucks: {
    enable: true,
    package: 'egg-view-nunjucks',
  },
  cors: {
    enable: true,
    package: 'egg-cors',
  },
  jwt: {
    enable: true,
    package: 'egg-jwt',
  },
  sequelize: {
    enable: true,
    package: 'egg-sequelize',
  },

};

config\config.default.js

/* eslint valid-jsdoc: "off" */

'use strict';

/**
 * @param {Egg.EggAppInfo} appInfo app info
 */
module.exports = appInfo => {
  /**
   * built-in config
   * @type {Egg.EggAppConfig}
   **/
  const config = exports = {};

  // use for cookie sign key, should change to your own and keep security
  config.keys = appInfo.name + '_1620442177015_7667';

  // add your middleware config here
  config.middleware = [];

  // add your user config here
  const userConfig = {
    // myAppName: 'egg',
  };

  config.security = {
    csrf: {
      enable: false,
    },
  };
  config.view = {
    defaultViewEngine: 'nunjucks',
  };
  config.cors = {
    origin: '*',
    allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH',
  };
  config.jwt = {
    secret: 'maguodong',
  };
  config.sequelize = {
    dialect: 'mysql',
    database: 'eggdemo',
    host: '127.0.0.1',
    port: 3306,
    username: 'root',
    password: 'mgd12345',
    timezone: '+08:00',
  };

  return {
    ...config,
    ...userConfig,
  };
};

app\model\clazz.js

'use strict';

module.exports = app => {
  const { STRING } = app.Sequelize;
  // ?默认情况下sequelize将自动将所有传递的模型名称(define的第一个参数)抓换位复
  const Clazz = app.model.define('clazz', {
    // *自动生成id
    name: STRING,
  });
  return Clazz;
};
// ?班级:id,name

app.js

'use strict';
module.exports = app => {
  // *  beforeStart是egg生命周期函数,启动应用时执行
  app.beforeStart(async function() {
    // await app.model.sync({ force: true }); // ?开发环境使用会删除数据
    // *创建数据表的方法  sync会根据模型去创建表
    await app.model.sync({});
  });
};

npm run dev启动
在这里插入图片描述

数据操作

  在controller中实现数据的增删改查
说明: 在真实项目中,controller和操作数据的逻辑要分离,以便于项目的扩展和维护

this.app.model.Clazz.findAll(); //查询数据
this.app.model.Clazz.findAll({where:{id:1}}); //通过where设置查询条件
this.app.model.Clazz.create({name:'xxx'}); //添加数据
this.app.model.Clazz.update({name:'xxx'},{where:{id:1}}); //通过条件修改数据
this.app.model.Clazz.destroy({where:{id:1}}); //通过条件删除数据

app\controller\clazz.js

'use strict';

const Controller = require('egg').Controller;
class ClazzController extends Controller {
  //  ?restful接口 index/create/destroy/update
  // ?先不做异常处理
  async index() {
    const { ctx } = this;
    const clazzList = await this.app.model.Clazz.findAll();
    /* const id = ctx.request.query.id;
    const clazzList = await this.app.model.Clazz.findAll({
      where: {
        id,
      },
    }); */
    ctx.body = {
      code: 200,
      data: clazzList,
    };
  }

  async create() {
    const { ctx } = this;
    const name = ctx.request.body.name;
    await this.app.model.Clazz.create({
      name,
    });
    ctx.body = '添加成功';
  }

  async destroy() {
    const { ctx } = this;
    const id = ctx.params.id;
    await this.app.model.Clazz.destroy({
      where: {
        id,
      },
    });
    ctx.body = '删除成功';
  }

  async update() {
    const { ctx } = this;
    const id = ctx.params.id;
    const name = ctx.request.body.name;
    await this.app.model.Clazz.update({ name }, {
      where: {
        id,
      },
    });
    ctx.body = '更新成功';
  }
}

module.exports = ClazzController;

app\router.js

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.get('/', controller.home.index);
  router.resources('clazz', '/clazz', controller.clazz);
};
添加外键

app\model\student.js

'use strict';
module.exports = app => {
  const { STRING, DOUBLE } = app.Sequelize;
  // ?默认情况下sequelize将自动将所有传递的模型名称(define的第一个参数)抓换位复
  const Student = app.model.define('student', {
    // *自动生成id
    name: STRING,
    achievement: DOUBLE,
  });

  Student.associate = function() { // ?所属哪个班级,指向班级的主键
    app.model.Student.belongsTo(app.model.Clazz, {
      foreignKey: 'clazz_id',
      as: 'clazz',
    });
  };
  return Student;
};

app\controller\student.js

'use strict';
const Controller = require('egg').Controller;

class StudentController extends Controller {
  async create() {
    const { ctx } = this;
    const name = ctx.request.body.name;
    const achievement = ctx.request.body.achievement;
    const clazz_id = ctx.request.body.clazz_id;

    await this.app.model.Student.create({
      name: names,
      achievement: achievements,
      clazz_id: clazzId,
    });
    ctx.body = '添加成功';
  }
  async index() {
    const { ctx } = this;
    const studentList = await this.app.model.Student.findAll();
    ctx.body = {
      code: 200,
      data: studentList,
    };
  }

  async update() {
    const { ctx } = this;
    const id = ctx.params.id;
    const name = ctx.request.body.name;
    const achievement = ctx.request.body.achievement;
    const clazzId = ctx.request.body.clazzId;
    await this.app.model.Student.update({ name, achievement, clazzId }, {
      where: {
        id,
      },
    });
    ctx.body = '更新成功';
  }
  async destroy() {
    const { ctx } = this;
    const id = ctx.params.id;
    await this.app.model.Student.destroy({
      where: {
        id,
      },
    });
    ctx.body = '删除成功';
  }
}
module.exports = StudentController;

Service(服务层)

在这里插入图片描述
简单来说,Service就是在复杂业务场景下用于做业务逻辑封装的抽象层,提供这个抽象有一下几个好处:

  1. 保持Controller中的逻辑更加简洁
  2. 保持业务逻辑的独立性,抽象出来的Servive可以被多个Controller重复调用

定义servive

app\service\student.js

'use strict';
const Service = require('egg').Service;

class StudentService extends Service {
  async getStudentList() {
    try {
      const studentList = await this.app.model.Student.findAll();
      return studentList;
    } catch (e) {
      return null;
    }
  }

  async createStudent(name, achievement, clazz_id) {
    try {
      await this.app.model.Student.create({
        name,
        achievement,
        clazz_id,
      });
      return true;
    } catch (e) {
      return false;
    }
  }

  async updateStudent(name, achievement, clazzId, id) {
    try {
      await this.app.model.Student.update({ name, achievement, clazzId }, {
        where: {
          id,
        },
      });
      return true;
    } catch (e) {
      return false;
    }
  }

  async deleteStudent(id) {
    try {
      await this.app.model.Student.destroy({
        where: {
          id,
        },
      });
      return true;
    } catch (e) {
      return false;
    }
  }
}

module.exports = StudentService;

app\controller\student.js

'use strict';
const Controller = require('egg').Controller;

class StudentController extends Controller {
  async create() {
    const { ctx } = this;
    const name = ctx.request.body.name;
    const achievement = ctx.request.body.achievement;
    const clazz_id = ctx.request.body.clazz_id;

    /* await this.app.model.Student.create({
      name: names,
      achievement: achievements,
      clazz_id: clazzId,
    });
    ctx.body = '添加成功'; */

    // ?调用service
    const result = await ctx.service.student.createStudent(name, achievement, clazz_id);
    if (result) {
      ctx.body = {
        code: 200,
        msg: '添加成功',
      };
    } else {
      ctx.body = {
        code: 500,
        msg: '数据添加失败',
      };
    }
  }
  async index() {
    const { ctx } = this;
    /* const studentList = await this.app.model.Student.findAll();
    ctx.body = {
      code: 200,
      data: studentList,
    }; */
    // ?调用service
    const list = await ctx.service.student.getStudentList();
    // const list = null;
    if (list) {
      ctx.body = {
        code: 200,
        data: list,
      };
    } else {
      ctx.body = {
        code: 500,
        msg: '服务器异常',
      };
    }
  }

  async update() {
    const { ctx } = this;
    const id = ctx.params.id;
    const name = ctx.request.body.name;
    const achievement = ctx.request.body.achievement;
    const clazzId = ctx.request.body.clazzId;

    // ?调用service
    const update = await ctx.service.student.updateStudent(name, achievement, clazzId, id);
    if (update) {
      ctx.body = {
        code: 200,
        msg: '更新成功',
      };
    } else {
      ctx.body = {
        code: 400,
        msg: '更新失败',
      };
    }
  }
  async destroy() {
    const { ctx } = this;
    const id = ctx.params.id;
    const destroy = await ctx.service.student.deleteStudent(id);
    if (destroy) {
      ctx.body = {
        code: 200,
        msg: '删除成功',
      };
    } else {
      ctx.body = {
        code: 400,
        msg: '删除失败',
      };
    }
  }
}
module.exports = StudentController;

部署

前端打包好的项目会生成dist文件夹,将dist文件夹内的内容移动到egg项目下的app/public文件夹内。

配置Egg的静态文件访问路径

config\config.default.js

/* eslint valid-jsdoc: "off" */

'use strict';

/**
 * @param {Egg.EggAppInfo} appInfo app info
 */
const path = require('path');
module.exports = appInfo => {
  /**
   * built-in config
   * @type {Egg.EggAppConfig}
   **/
  const config = exports = {};

  // use for cookie sign key, should change to your own and keep security
  config.keys = appInfo.name + '_1620442177015_7667';

  // add your middleware config here
  config.middleware = [];

  // add your user config here
  const userConfig = {
    // myAppName: 'egg',
  };

  config.security = {
    csrf: {
      enable: false,
    },
  };
  config.view = {
    defaultViewEngine: 'nunjucks',
  };
  config.cors = {
    origin: '*',
    allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH',
  };
  config.jwt = {
    secret: 'maguodong',
  };
  config.sequelize = {
    dialect: 'mysql',
    database: 'eggdemo',
    host: '127.0.0.1',
    port: 3306,
    username: 'root',
    password: 'mgd12345',
    timezone: '+08:00',
  };
  // ?配置Egg的静态文件访问路径
  config.static = {
    prefix: '/',
    dir: path.join(appInfo.baseDir, 'app/public'),
  };

  return {
    ...config,
    ...userConfig,
  };
};

启动和关闭

启动:npm start
关闭:npm stop

用ctrl+c不能停止服务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值