跳至主要內容

常用配置

微信公众号:储凡About 13 min

常用配置

常用代码

const {ctx}=this;

// xss攻击
ctx.helper.escape(XXXX)

// 参数校验
ctx.validate({xxxx},ctx.query||ctx.request.body)

// http请求
// options解析: https://eggjs.org/zh-cn/core/httpclient.html#options-%E5%8F%82%E6%95%B0%E8%AF%A6%E8%A7%A3
ctx.curl(url,options);

// 判断是否通过 XMLHttpRequest 发起的请求
// 参考:https://eggjs.org/zh-cn/core/unittest.html#ctx
ctx.isXHR===true|false

// 当前时间戳
const currentTime=new Date().getTime();

// 当前环境变量
app.config.env

常用配置

// 日志自定义切割 参考: https://eggjs.org/zh-cn/core/logger.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E6%97%A5%E5%BF%97
config.customLogger={
  // 日志名称,通过ctx.getLogger('XXX')来调用
  xxx:{
    // 
    file:'XXXX'
  }
}

// 端口监听
config.cluster={
  listen:{
    host:'xxxxxx',  // 主机地址
    port: 7001,   // 端口
  }
}

// csrf安全规范,默认开启
config.security={
  csrf:false
}

// 配置图片上传模式, 参考:https://eggjs.org/api/Config.html#multipart
config.multipart={
  // 文件传输
  mode:'file',
  fileSize:'200mb',
  fields:'20'
}

// 配置表单参数允许大小,参考:https://eggjs.org/api/Config.html#bodyParser
config.bodyParser={
  jsonLimit:'5mb',
  formLimit:'6mb'
}

sequelize

api参考:https://www.sequelize.com.cn/open in new window

const sequelize = require('sequelize')

// 字段属性
{
  field  字段名 
  type   字段类型 INTEGER|STRING
  primaryKey 是否外键 true|false
  defaultValue 数据为空时的默认值
  autoIncrement 是否自增 true|false
  allowNull 是否允许为空 true|false
  comment 字段注释 
}
// 表属性
{
  tableName  自定义表名
  freezeTableName 默认false修改表名为复数,true不修改表名,与数据库表名同步
  timestamps  对sequelize自带时间戳开关进行设置,默认为true
  createdAt 创建时间字段自定义
  updatedAt 更新时间字段自定义

  deletedAt 删除时间字段自定义
  paranoid  在被告之要删除记录时并不会真正的物理上删除,而是添加一个存有删除请求时间戳deletedAt的特殊字段。

  indexes [   //索引
    {
      name:''  //索引名称
      method:'BTREE' //缩影类型
      fields:[]  //索引对应的列名
    }
  ]  
  // 索引可以参考: https://www.sequelize.com.cn/other-topics/indexes
}

// 查询
findAll()
// 分页查询
findAndCountAll()
// 更新
update()
// 物理删除
destroy()
// 创建
create()


// 模型CURD操作对应的属性
{
  raw 是否json处理  true|false
  Association { 表之间关联关系
    foreignKey  外键名称
    targetKey   目标表主键
  }  
  attributes 属性名
  include {  连表操作
    model  连接的模型
    attributes {  属性
      exclude  不包含的属性
      include  包含的属性
    }
  }
  limit  分页单页数据 page_size
  offset 分页起始  (current_page-1)*page_size
  where { 条件语句
    ...查询条件
  } 
  order [ 排序语句
    ...排序条件 ['xxx','desc|asc']
  ] 
  group 分组语句
}


// 事务
const transaction= await ctx.model.sequelize.transaction();
// 事务提交
transaction.commit();
// 事务回滚【手动控制】
transaction.rollback();


// OP操作  参考:
const Op = require('sequelize').Op

[Op.and]: {a: 5}           // AND (a = 5)
[Op.or]: [{a: 5}, {a: 6}]  // (a = 5 OR a = 6)
[Op.gt]: 6,                // > 6
[Op.gte]: 6,               // >= 6
[Op.lt]: 10,               // < 10
[Op.lte]: 10,              // <= 10
[Op.ne]: 20,               // != 20
[Op.eq]: 3,                // = 3
[Op.not]: true,            // IS NOT TRUE
[Op.between]: [6, 10],     // BETWEEN 6 AND 10
[Op.notBetween]: [11, 15], // NOT BETWEEN 11 AND 15
[Op.in]: [1, 2],           // IN [1, 2]
[Op.notIn]: [1, 2],        // NOT IN [1, 2]
[Op.like]: '%142vip',         // LIKE '%142vip'
[Op.notLike]: '%142vip'       // NOT LIKE '%142vip'
[Op.iLike]: '%142vip'         // ILIKE '%142vip' (case insensitive) (PG only)
[Op.notILike]: '%142vip'      // NOT ILIKE '%142vip'  (PG only)
[Op.startsWith]: '142vip'     // LIKE '142vip%'
[Op.endsWith]: '142vip'       // LIKE '%142vip'
[Op.substring]: '142vip'      // LIKE '%142vip%'
[Op.regexp]: '^[h|a|t]'    // REGEXP/~ '^[h|a|t]' (MySQL/PG only)
[Op.notRegexp]: '^[h|a|t]' // NOT REGEXP/!~ '^[h|a|t]' (MySQL/PG only)
[Op.iRegexp]: '^[h|a|t]'    // ~* '^[h|a|t]' (PG only)
[Op.notIRegexp]: '^[h|a|t]' // !~* '^[h|a|t]' (PG only)
[Op.like]: { [Op.any]: ['cat', '142vip']}
                       // LIKE ANY ARRAY['cat', '142vip'] - also works for iLike and notLike
[Op.overlap]: [1, 2]       // && [1, 2] (PG array overlap operator)
[Op.contains]: [1, 2]      // @> [1, 2] (PG array contains operator)
[Op.contained]: [1, 2]     // <@ [1, 2] (PG array contained by operator)
[Op.any]: [2,3]            // ANY ARRAY[2, 3]::INTEGER (PG only)

[Op.col]: 'user.organization_id' // = "user"."organization_id", with dialect specific column identifiers, PG in this example



// 数据同步
ctx.app.model.sync({
  force:false   // 是否强制更新表 true|false
  alter:true    // 是否依据model修改表 true|false
})


服务部署

# 安装node
FROM node:10
# 标签
LABEL version="Beta1.0"
LABEL description="【哔哩哔哩:Rong姐姐好可爱】基于egg框架短链功能、接口代理等接口服务"
# 作者
LABEL Author="哔哩哔哩:Rong姐姐好可爱"
## 邮箱
LABEL Email="237221210@qq.com"
# 创建项目空间
RUN mkdir -p /web-project/node/xxxxx
# 将当前代码文件复制到工作区域
COPY . /web-project/node/xxxxx
# 进入 vendors
WORKDIR /web-project/node/xxxxx
# 下载依赖
RUN npm install --registry https://registry.npm.taobao.org

## 暴露端口
EXPOSE 8848

## 指定环境变量 自定义环境对应config.xxxxx.js
ENV EGG_SERVER_ENV='xxxxx'

# 项目启动 
CMD ["npm","run","start"]

在没有外网连接的基础时,gRPC的部署需要先将模块包导入再应用;

## 忽略脚本安装
RUN npm install grpc --ignore-scripts
## 导入模块
COPY ./grpcModule ./xxxxx

rabbitMQ

api参考:http://www.squaremobius.net/amqp.node/channel_api.html#channel_consumeopen in new window

// 引入模块包
const amqplib = require('amqplib')
// 
const rabbitClient = await amqplib.connect(rabbitConnectUrl);
// 创建通道
const channel = await rabbitClient.createChannel();
// 交换机
await channel.assertExchange(rabbitExchangeName, 'direct', { durable: true });
// 队列
await channel.assertQueue(rabbitQueueName, { durable: true });
await channel.prefetch(4);
// 绑定
await channel.bindQueue(rabbitQueueName, rabbitExchangeName, rabbitRoutingKey);
// 消息获取
await channel.consume(rabbitQueueName, msg => {
  setTimeout(async () => {
    try {
      const msgKey = JSON.parse(msg.content);
      console.log('----正常数据:---------', msgKey);
      const inserted = await ctx.service.mailDetail.insertMaliLogsInDatabase(msgKey);
      // channel.ack(msg);
      // console.log(inserted);
      if (inserted) {
        // 确认
        channel.ack(msg);
      }
    } catch (error) {
      console.log(error);
      // 消息格式异常,直接确认,避免队列堵塞
      console.log('-------消息格式异常-------', msg.content.toString());
      // channel.ack(msg);
      // 拒收,重新放回消息队列
      channel.nack(msg, { requeue: true });
    }
    // // isSuccess==1 写入成功,为true
    // if (!isSuccess) {
    //   // 写入出错,关闭通道
    //   const writeErrorMsg = msg.content.toString();
    //   app.logger.info('writeErrorMsg----->', writeErrorMsg);
    //   // ..... add code here
    //   await channel.close();
    // }
  }, 1000);
}, {
  // 队列中一有消息就消费
  noAck: false,
  exclusive: false,
});

参考资料