常用配置
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/
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_consume
// 引入模块包
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,
});