Egg.js搭建项目过程与问题

1 篇文章 0 订阅
1 篇文章 0 订阅

逐步搭建

为了让自己更好的了解Egg.js,全部手动一步步搭建(前面都是参考的官网上的内容)。

初始化项目

初始化目录结构:

$ mkdir egg-example
$ cd egg-example
$ npm init
$ npm i egg --save
$ npm i egg-bin --save-dev

添加 npm scripts 到 package.json

{
  "name": "egg-example",
  "scripts": {
    "dev": "egg-bin dev"
  }
}

编写Controller

// app/controller/home.js
const Controller = require('egg').Controller;

class HomeController extends Controller {
  async index() {
    this.ctx.body = 'Hello world';
  }
}
module.exports = HomeController;

配置路由映射

// app/router.js
module.exports = app => {
  const { router, controller } = app;
  router.get('/', controller.home.index);
};

加一个配置文件:

// config/config.default.js
exports.keys = <此处改为你自己的 Cookie 安全字符串>;

此时目录结构如下:

egg-example
├── app
│   ├── controller
│   │   └── home.js
│   └── router.js
├── config
│   └── config.default.js
└── package.json

好,现在可以启动应用来体验下

$ npm run dev
$ open http://127.0.0.1:7001

项目初步搭建已完成。

Egg.js是基于MVC模式的,

  1. app.router.js: 用于配置URL路由规则;
  2. app/controller/… : 用于解析用户的输入,处理返回相应的结果;
  3. app/service/… : 用户编写业务逻辑层,关于数据库处理的操作;
  4. app/model/… : 存放实体类,与数据库中的属性值基本保持一致;
  5. app/public/… : 用于放置静态资源;
  6. config/config.config.{env}.js: 用于编写配置文件;
  7. config/plugin.js 用于配置需要加载的插件;

Sequelize

使用 sequelize 插件自动管理数据层代码。(在此之前本机上已经安装好了MySQL)

安装

安装并配置 egg-sequelize-auto 插件(它会辅助我们将定义好的 Model 对象加载到 app 和 ctx 上)和 mysql2 模块:

npm install -g egg-sequelize-auto mysql2

config/pulgin.js 中引入 egg-sequelize插件

exports.sequelize = {
  enable: true,
  package: 'egg-sequelize',
};

在 config/config.default.js 中编写 sequelize 配置

config.sequelize = {
  dialect: 'mysql',
  host: '127.0.0.1',
  port: 3306,
  database: 'egg-sequelize-doc-default',
};
  1. dialect : 数据库类型;
  2. host : 数据库的IP地址;
  3. port : 端口号;
  4. database: 数据库名

自动创建Model

这里跳过了数据库初始化的过程,我使用的工具已经创建好了数据库和表,现在通过插件自动创建 Model 。

egg-sequelize-auto -o "./app/model" -d glsx_audit -h 192.168.*.*** -u root -p 3308 -x 123456   -e mysql

参数说明

  1. -h 数据库的IP地址;
  2. -d 数据库名;
  3. -u 用户名;
  4. -x 密码;
  5. -p 端口;
  6. -e 数据库类型;
  7. -t 表名, 不指定-t , 为所有表;

在创建时碰到的问题,数据库error:1045

sqlMessage: 'Access denied for user \'root\'@'192.168.*.***\' (using passwork: YES)'

原因:密码为字符串;
解决办法:字符串要使用双引号,不可以使单引号;

egg接收请求参数

get请求

async getList() {
	const query = this.ctx.query
	...代码
}

或者

async getList(query) {
	...代码
}

post请求

async create() {
	const data = this.ctx.request.body
	...代码
}

或者

async create({request: { body } }) {
	const data = this.ctx.request.body
	...代码
}

接口返回值

this.ctx.body = {
	code: 0,
	data: '返回的数据',
	msg: '返回状态信息'	
}

增删改查

查询

service.js

分页查询

async findAll({pager = {},searcher = {}}) {
    const { current = 1, size = 10 } = pager
    const {projectName } = searcher
    const offset = (current - 1) * size
    const { Op } = this.app.Sequelize
    if (projectName) {
        const __like = `%${projectName}%` // 模糊查询
        where.project_name(数据库中的字段) = {
            [Op.like]: __like
        }
    }
    // findAndCountAll返回字段中有总数,和分页查询的数据;findAll返回所有查询数据
    return await projectModel(表别名).findAndCountAll({
        offset,
        limint: +size,
        where,
        raw: true
    })
}

计算和的所有数据

return await AModel.findAll({
    // 1.SUM 求和, 2.col中是求和的列,3.返回的字段名
    attributes: [
        [fn.('SUM', col('delivery_total')), 'deliveryTotal']
    ],
    where,
    raw: true
})

接口返回指定数据

const attr = ['merchant_id', 'merchant_name', 'account_name', 'merchant_type', 'address', 'phone', [fn.('SUM', col('delivery_total')), 'deliveryTotal']]
// 1.SUM 求和, 2.col中是求和的列,3.返回的字段名
return await AModel.findAll({
    attributes: attr,
    where,
    raw: true
})

删除选定的属性

attributes: {exclude: ['id', 'delete_flag']

新增

service.js

/** 新增文档 */
  async create(params) {
    const now = Date.now()
    const p = await this.DI.create({
      ...
      created_at: now,
      updated_at: now,
      del_flag: 'Y'
    })
    return {
      id: p.id  // 接口返回新增数据的id
    }
  }

注意:新增的时候会默认生成两个字段 created_at、updated_at ,数据库插入数据会导致报错找不到该字段,我的处理方式是在数据库里直接创建相同的字段。

修改

service.js

async update(params) {
    const id = params.id
    const u = await projectModel.findById(id)
    u.update(params)
    return u
}

或者

async update(params) {
    return await projectModel.update(params)
}

删除

service.js

async delete({id}) {
    const d = await projectModel.destroy({
        where: {
            id: id
        }
    })
    return d
}

调用后台接口

有时候需要从别的服务上调用接口,获取数据。方式如下:

async search() {
    const ctx = this.ctx
    let params = ''
    const result = await ctx.curl(`http://....?${params}`, {
        dataType: 'text',
        method: 'GET',
        timeout: 3000
    })
    return result
}

安全威胁 钓鱼攻击 的防范

报错提示:

invalid csrf token. See https://eggjs.org/zh-cn/core/security.html#安全威胁csrf的防范

防范方式

在 config.default.js 中配置

// config/config.default.js
 config.security = {
    csrf: {
      enable: false,
      ignoreJSON: true
    },
    domainWhiteList: ["http://localhost:8080"] //允许访问接口的白名单
  };

若用户没有配置 domainWhiteList 或者 domainWhiteList数组内为空,则默认会对所有跳转请求放行

暂时记录到这里,后面又遇到问题在更新。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值