up
This commit is contained in:
@@ -10,11 +10,9 @@
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
"plugins": [
|
"plugins": [
|
||||||
[
|
["@babel/plugin-proposal-decorators",{"legacy": true}],
|
||||||
"babel-plugin-webpack-alias",
|
// ["@babel/plugin-proposal-class-properties",{"loose": true}],
|
||||||
{
|
// ["babel-plugin-webpack-alias", { "config": "./webpack.config.js" } ]
|
||||||
"config": "./webpack.config.js"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
+44
-2
@@ -1,14 +1,56 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
doc : "",
|
doc : "默认页面",
|
||||||
path : "/",
|
path : "/",
|
||||||
method : ["get", "post"],
|
method : ["get", "post"],
|
||||||
middleware: [],
|
middleware: [],
|
||||||
params : {},
|
params : {},
|
||||||
return : {},
|
return : {},
|
||||||
controller: async (ctx, app) => {
|
controller: async (ctx, app) => {
|
||||||
|
// app.err.ParameterException()
|
||||||
|
app.event.emit('test.event2')
|
||||||
|
const where = {
|
||||||
|
// id: 4
|
||||||
|
}
|
||||||
|
const data = {
|
||||||
|
// id: 1,
|
||||||
|
uid: "77",
|
||||||
|
}
|
||||||
|
|
||||||
ctx.body = 'index,xe:' + app.utils.VERSION
|
// const User = await app.table("User").where(where).findAll()
|
||||||
|
// const User = await app.table("User").time(["2022-04-9", "2022-04-10"]).findAll()
|
||||||
|
// const User = await app.table("User").where(where).findOrCreate(data)
|
||||||
|
// const {count, rows} = await app.table("User").where(where).findAndCountAll()
|
||||||
|
// const User = await app.table("User").save(data)
|
||||||
|
// const res = {
|
||||||
|
// "创建单个数据" : await app.table("User").data({uid: "6666"}).save(),
|
||||||
|
// "查询单个数据" : await app.table("User").where({id: 2}).find(),
|
||||||
|
// "查询单个数据,不存在就创建" : await app.table("User").where({id: 999}).data({uid: "6666"}).findOrCreate(),
|
||||||
|
// "查询所有数据" : await app.table("User").where({uid: "6666"}).findAll(),
|
||||||
|
// "查询所有数据(时间区间)" : await app.table("User").time(['2022-04-09', '2022-04-10']).findAll(),
|
||||||
|
// "查询所有数据(当月数据)" : await app.table("User").time('month').findAll(),
|
||||||
|
// "查询所有数据(30分钟内的数据)": await app.table("User").time(30).findAll(),
|
||||||
|
// "查询所有数据(分页)" : await app.table("User").where({uid: "6666"}).page(1).limit(1).findAll(),
|
||||||
|
// "查询所有数据+总行数(分页)" : await app.table("User").where({uid: "6666"}).page(1).limit(1).findAndCountAll(),
|
||||||
|
// }
|
||||||
|
|
||||||
|
/*
|
||||||
|
await app.setTransaction() // 设置事务
|
||||||
|
await app.table("User").data({uid: "6666"}).save()
|
||||||
|
await app.table("User").where({id: 2}).find()
|
||||||
|
await app.table("User").data({uid: "6666"}).save()
|
||||||
|
await app.table("User").where({id: 2}).find()
|
||||||
|
await app.commitTransaction() //提交事务,如果设置了事务不提交,任务不会执行
|
||||||
|
*/
|
||||||
|
|
||||||
|
// await app.table("User").where({id: 1032}).data({age: 1}).setInc() // 字段值+1
|
||||||
|
// await app.table("User").where({id: 1032}).data({age: 2}).setInc() // 字段值+2
|
||||||
|
// const {res, value} = await app.table("User").where({id: 1032}).data({age: 2}).setDec(0) // 字段值-2,不能低于0,如果低于0返回false
|
||||||
|
// const {res, value} = await app.table("User").where({id: 1032}).data({age: 2}).setDec(0,10) // 字段值-2,不能低于0,如果低于0设置为10
|
||||||
|
const {res, value} = await app.table("User").where({id: 1032}).data({age: 2}).setInc(20, 10) // 字段值+2,不能大于20,如果大于20设置为10
|
||||||
|
|
||||||
|
|
||||||
|
ctx.body = {res, value}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,44 @@
|
|||||||
class HttpException extends Error {
|
class HttpException extends Error {
|
||||||
// message为异常信息,errorCode为错误码(开发人员内部约定),code为HTTP状态码
|
// message为异常信息,code 为错误码(开发人员内部约定),status 为HTTP状态码
|
||||||
constructor(message = '服务器异常', errorCode = 10000, code = 400) {
|
constructor(message, code, status) {
|
||||||
super()
|
super()
|
||||||
this.errorCode = errorCode || 10000
|
this.status = status || 500
|
||||||
this.code = code || 400
|
this.code = code || 500
|
||||||
this.message = message || '服务器异常'
|
this.message = message || '服务器异常'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ParameterException extends HttpException {
|
class ParameterException extends HttpException {
|
||||||
constructor(message, errorCode) {
|
constructor(message, code, status) {
|
||||||
super()
|
super()
|
||||||
this.errorCode = errorCode || 10000
|
this.status = status || 402
|
||||||
this.code = 400
|
this.code = code
|
||||||
this.message = message || '参数错误'
|
this.message = message || '参数错误'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NotFound extends HttpException {
|
class NotFound extends HttpException {
|
||||||
constructor(message, errorCode) {
|
constructor(message, code, status) {
|
||||||
super()
|
super()
|
||||||
this.errorCode = errorCode || 10001
|
this.status = status || 404
|
||||||
this.code = 404
|
this.code = 404
|
||||||
this.message = message || '资源未找到'
|
this.message = message || '资源未找到'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AuthFailed extends HttpException {
|
class AuthFailed extends HttpException {
|
||||||
constructor(message, errorCode) {
|
constructor(message, code, status) {
|
||||||
super()
|
super()
|
||||||
this.errorCode = errorCode || 10002
|
this.status = status || 401
|
||||||
this.message = message || '授权失败'
|
this.message = message || '授权失败'
|
||||||
this.code = 401
|
this.code = 401
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Forbidden extends HttpException {
|
class Forbidden extends HttpException {
|
||||||
constructor(message, errorCode) {
|
constructor(message, code, status) {
|
||||||
super()
|
super()
|
||||||
this.errorCode = errorCode || 10003
|
this.status = status || 403
|
||||||
this.message = message || '禁止访问'
|
this.message = message || '禁止访问'
|
||||||
this.code = 403
|
this.code = 403
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
'use strict';
|
||||||
|
// 监听事件
|
||||||
|
module.exports = {
|
||||||
|
"event1": (args) => {
|
||||||
|
console.log(args || 'event1')
|
||||||
|
},
|
||||||
|
"event2": (args) => {
|
||||||
|
console.log(args || 'event2')
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
/*系统启动后要做初始化*/
|
||||||
|
module.exports = (app) => {
|
||||||
|
console.log("启动完成");
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
'use strict';
|
||||||
|
const error = require('koa-json-error')
|
||||||
|
// 错误处理
|
||||||
|
module.exports = error((err) => {
|
||||||
|
return {
|
||||||
|
status : err.status,
|
||||||
|
message : err.message,
|
||||||
|
code : err.code,
|
||||||
|
res : false,
|
||||||
|
// postFormat: (e, obj) => process.env.NODE_ENV === 'production' ? _.omit(obj, 'stack') : obj
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -5,7 +5,6 @@ module.exports = async (ctx, next, app) => {
|
|||||||
// const timetaken = `${ctx.request.method}${ctx.request.url} 响应时间`
|
// const timetaken = `${ctx.request.method}${ctx.request.url} 响应时间`
|
||||||
// console.time(timetaken)
|
// console.time(timetaken)
|
||||||
// app.logger.debug("123")
|
// app.logger.debug("123")
|
||||||
throw new app.err.HttpException
|
|
||||||
await next()
|
await next()
|
||||||
// console.timeEnd(timetaken)
|
// console.timeEnd(timetaken)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
module.exports = {
|
||||||
|
doc : "用户",
|
||||||
|
model: {
|
||||||
|
uid: {type: "STRING", comment: '用户id'},
|
||||||
|
age: {type: "INTEGER", comment: '年龄', defaultValue: 0,},
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
'use strict';
|
||||||
|
// 监听事件
|
||||||
|
module.exports = {
|
||||||
|
time : "*/3 * * * * *",
|
||||||
|
run : true,//系统启动时立即执行一次
|
||||||
|
schedule: (app) => {
|
||||||
|
// console.log('每3秒我执行一次' + app.utils.VERSION)
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -0,0 +1,8 @@
|
|||||||
|
module.exports = {
|
||||||
|
doc : "mysql模型文件的m5记录",
|
||||||
|
model: {
|
||||||
|
fileName: {type: "STRING", comment: '文件名称'},
|
||||||
|
md5 : {type: "TEXT", comment: 'md5记录'},
|
||||||
|
md5json : {type: "JSON", comment: 'md5记录'},
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1 +1,57 @@
|
|||||||
/*数据库配置*/
|
/*数据库配置*/
|
||||||
|
module.exports = {
|
||||||
|
mysql: {
|
||||||
|
database: "bamboo",
|
||||||
|
username: "bamboo",
|
||||||
|
password: "bamboo",
|
||||||
|
options : {
|
||||||
|
dialect: 'mysql',
|
||||||
|
host : "192.168.1.26",
|
||||||
|
port : 3306,
|
||||||
|
// 禁用日志记录或提供自定义日志记录功能;默认值:console.log
|
||||||
|
// logging: false,
|
||||||
|
// model的全局配置
|
||||||
|
define: {
|
||||||
|
// 添加create,update,delete时间戳
|
||||||
|
timestamps: true,
|
||||||
|
// 添加软删除
|
||||||
|
paranoid: false,
|
||||||
|
// 防止修改表名为复数
|
||||||
|
freezeTableName: true,
|
||||||
|
// 防止驼峰式字段被默认转为下划线
|
||||||
|
underscored: false,
|
||||||
|
},
|
||||||
|
// 由于orm用的UTC时间,这里必须加上东八区,否则取出来的时间相差8小时
|
||||||
|
timezone: '+08:00',
|
||||||
|
// 连接数 = ((核心数 * 2) + 有效磁盘数)
|
||||||
|
pool : {// 连接池
|
||||||
|
max : require('os').cpus().length * 2 + 1,
|
||||||
|
min : 0,
|
||||||
|
acquire: 60000,
|
||||||
|
idle : 100000,
|
||||||
|
},
|
||||||
|
dialectOptions: {
|
||||||
|
charset : "utf8mb4",
|
||||||
|
collate : "utf8mb4_general_ci",
|
||||||
|
supportBigNumbers: true,
|
||||||
|
bigNumberStrings : true,
|
||||||
|
dateStrings : true,
|
||||||
|
typeCast(field, next) {// 让读取date类型数据时返回字符串而不是UTC时间
|
||||||
|
if (field.type === 'DATETIME') {
|
||||||
|
// console.log(field);
|
||||||
|
return field.string();
|
||||||
|
}
|
||||||
|
return next();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
redis:{},
|
||||||
|
sqlite:{
|
||||||
|
dialect: 'sqlite',
|
||||||
|
storage: 'app/sqlite/database.sqlite',
|
||||||
|
logging: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
/*redis配置*/
|
|
||||||
module.exports = {
|
|
||||||
port: 3000,
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
const Bamboo = require("./index")
|
||||||
|
|
||||||
|
module.exports = class DB extends Bamboo {
|
||||||
|
|
||||||
|
constructor() {super();}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+755
-11
@@ -4,25 +4,66 @@ import Koa from 'koa';
|
|||||||
//https://x-extends.gitee.io/xe-utils/#/
|
//https://x-extends.gitee.io/xe-utils/#/
|
||||||
import xe from 'xe-utils'
|
import xe from 'xe-utils'
|
||||||
|
|
||||||
|
const fs = require('fs'); // 文件模块
|
||||||
const log4js = require("log4js");
|
const log4js = require("log4js");
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const error = require('./errorException')
|
|
||||||
const requireDirectory = require("require-directory");
|
const requireDirectory = require("require-directory");
|
||||||
const Router = require("koa-router");
|
const Router = require("koa-router");
|
||||||
|
const EventEmitter = require('events');
|
||||||
|
const schedule = require("node-schedule");
|
||||||
|
const Sequelize = require("sequelize");
|
||||||
|
|
||||||
module.exports = class Bamboo extends Koa {
|
module.exports = class Bamboo extends Koa {
|
||||||
constructor(agrs, options) {
|
constructor(agrs, options) {
|
||||||
super(options)
|
super(options)
|
||||||
super.on('error', (err, ctx) => this.serverError(err, ctx));
|
this.asyncStatus = {} //异步启动状态
|
||||||
|
this.fulfill = false //启动完成
|
||||||
|
this.modelAmend = false //模型文件是否有改动
|
||||||
this.config = {}
|
this.config = {}
|
||||||
this.utils = this.registeredContextUtils(xe)
|
this.utils = this.registeredContextUtils(xe)
|
||||||
this.logger = null
|
this.logger = null
|
||||||
|
this.Sequelize = null
|
||||||
|
this.mysql = null
|
||||||
|
this.sqlite = null
|
||||||
|
this.event = new EventEmitter()
|
||||||
this.registeredConfig()
|
this.registeredConfig()
|
||||||
this.setLogger()
|
this.setLogger()
|
||||||
|
this.registeredError()
|
||||||
|
this.initDB()
|
||||||
this.registeredMiddleware()
|
this.registeredMiddleware()
|
||||||
this.registeredRouter()
|
this.registeredRouter()
|
||||||
this.listen(8884)
|
this.listen(8884)
|
||||||
|
this.init()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
const initInterval = setInterval(() => {
|
||||||
|
console.log('启动中...');
|
||||||
|
const asyncStatusList = xe.toArray(this.asyncStatus)
|
||||||
|
console.log(this.asyncStatus);
|
||||||
|
console.log(asyncStatusList);
|
||||||
|
const asyncStatus = asyncStatusList.filter(item => item === 0)
|
||||||
|
if (asyncStatus.length === 0) {
|
||||||
|
this.fulfill = true
|
||||||
|
const init = require(this.path('app/init.js'));
|
||||||
|
init(this.application)
|
||||||
|
this.onFulfill()
|
||||||
|
clearInterval(initInterval)
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async initDB() {
|
||||||
|
await this.registeredSqlite()
|
||||||
|
await this.registeredDB()
|
||||||
|
}
|
||||||
|
|
||||||
|
//启动完成事件
|
||||||
|
onFulfill() {
|
||||||
|
this.registeredEvent()
|
||||||
|
this.registeredSchedule()
|
||||||
}
|
}
|
||||||
|
|
||||||
listen(args) {
|
listen(args) {
|
||||||
@@ -42,26 +83,240 @@ module.exports = class Bamboo extends Koa {
|
|||||||
this.config = hash
|
this.config = hash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//注册 错误
|
||||||
|
registeredError() {
|
||||||
|
console.log('注册 错误');
|
||||||
|
this.errorException = {}
|
||||||
|
const hash = requireDirectory(module, this.path('app/err'), {
|
||||||
|
visit: (obj) => {
|
||||||
|
for (let key of Object.keys(obj)) {
|
||||||
|
this.errorException[key] = (message, code) => {
|
||||||
|
throw new obj[key](message, code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//注册 mysql数据库
|
||||||
|
async registeredDB() {
|
||||||
|
console.log('注册 数据库');
|
||||||
|
this.asyncStatus['registeredDB'] = 0
|
||||||
|
const {
|
||||||
|
database,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
options,
|
||||||
|
} = this.config.database.mysql
|
||||||
|
this.Sequelize = Sequelize
|
||||||
|
|
||||||
|
const sequelize = new Sequelize(database, username, password, {
|
||||||
|
...options,
|
||||||
|
operatorsAliases: this.operatorsAliases
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
await sequelize.authenticate();
|
||||||
|
console.log('数据库连接成功');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('数据库连接失败', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
requireDirectory(module, this.path('app/model'), {
|
||||||
|
visit: (obj, joined, filename) => {
|
||||||
|
const parse = path.parse(filename);
|
||||||
|
const model = {}
|
||||||
|
for (let key of Object.keys(obj.model)) {
|
||||||
|
obj.model[key].type = this.Sequelize[obj.model[key].type]
|
||||||
|
model[key] = obj.model[key]
|
||||||
|
}
|
||||||
|
model['id'] = {
|
||||||
|
type : this.Sequelize.INTEGER,
|
||||||
|
comment : '表自增id',
|
||||||
|
allowNull : false,
|
||||||
|
unique : 'id',
|
||||||
|
primaryKey : true,
|
||||||
|
autoIncrement: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
sequelize.define(parse.name, model)
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.mysql = sequelize
|
||||||
|
console.log('this.modelAmend', this.modelAmend);
|
||||||
|
if (this.modelAmend) {
|
||||||
|
console.log('生成模型结构到数据库');
|
||||||
|
await sequelize.sync({alter: true});
|
||||||
|
}
|
||||||
|
this.asyncStatus['registeredDB'] = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
//注册 sqlite 数据库(记录model文件是否有改动,如果有就同步模型到mysql数据库)
|
||||||
|
async registeredSqlite() {
|
||||||
|
console.log('注册 sqlite 数据库');
|
||||||
|
this.asyncStatus['registeredSqlite'] = 0
|
||||||
|
const sqlite = new Sequelize(this.config.database.sqlite);
|
||||||
|
try {
|
||||||
|
await sqlite.authenticate();
|
||||||
|
console.log('sqlite数据库连接成功');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('sqlite数据库连接失败', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// const MysqlMD5 = sqlite.define('MysqlMD5', {
|
||||||
|
// fileName: Sequelize.STRING,
|
||||||
|
// md5 : Sequelize.TEXT
|
||||||
|
// });
|
||||||
|
requireDirectory(module, this.path('app/sqlite/model'), {
|
||||||
|
visit: (obj, joined, filename) => {
|
||||||
|
const parse = path.parse(filename);
|
||||||
|
const model = {}
|
||||||
|
for (let key of Object.keys(obj.model)) {
|
||||||
|
obj.model[key].type = Sequelize[obj.model[key].type]
|
||||||
|
model[key] = obj.model[key]
|
||||||
|
}
|
||||||
|
sqlite.define(parse.name, model)
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await sqlite.sync({alter: true});
|
||||||
|
const {MysqlMD5} = sqlite.models
|
||||||
|
this.modelAmend = true
|
||||||
|
requireDirectory(module, this.path('app/model'), {
|
||||||
|
visit: async (obj, joined, filename) => {
|
||||||
|
const parse = path.parse(filename);
|
||||||
|
const md5 = this.getFileMd5(this.path('app/model/') + filename)
|
||||||
|
const MysqlMD5Data = await MysqlMD5.findOne({where: {fileName: 'User'}})
|
||||||
|
if (!MysqlMD5Data) {
|
||||||
|
this.modelAmend = true
|
||||||
|
await MysqlMD5.create({fileName: parse.name, md5: md5})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (MysqlMD5Data.md5 !== md5) {
|
||||||
|
console.log('有改动的模型', MysqlMD5Data.fileName);
|
||||||
|
this.modelAmend = true
|
||||||
|
MysqlMD5.update({md5}, {where: {fileName: 'User'}})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.sqlite = sqlite
|
||||||
|
this.asyncStatus['registeredSqlite'] = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
get operatorsAliases() {
|
||||||
|
const Op = Sequelize.Op;
|
||||||
|
//操作符别名
|
||||||
|
const operatorsAliases = {
|
||||||
|
$eq : Op.eq,
|
||||||
|
$ne : Op.ne,
|
||||||
|
$gte : Op.gte,
|
||||||
|
$gt : Op.gt,
|
||||||
|
$lte : Op.lte,
|
||||||
|
$lt : Op.lt,
|
||||||
|
$not : Op.not,
|
||||||
|
$in : Op.in,
|
||||||
|
$notIn : Op.notIn,
|
||||||
|
$is : Op.is,
|
||||||
|
$like : Op.like,
|
||||||
|
$notLike : Op.notLike,
|
||||||
|
$iLike : Op.iLike,
|
||||||
|
$notILike : Op.notILike,
|
||||||
|
$regexp : Op.regexp,
|
||||||
|
$notRegexp : Op.notRegexp,
|
||||||
|
$iRegexp : Op.iRegexp,
|
||||||
|
$notIRegexp : Op.notIRegexp,
|
||||||
|
$between : Op.between,
|
||||||
|
$notBetween : Op.notBetween,
|
||||||
|
$overlap : Op.overlap,
|
||||||
|
$contains : Op.contains,
|
||||||
|
$contained : Op.contained,
|
||||||
|
$adjacent : Op.adjacent,
|
||||||
|
$strictLeft : Op.strictLeft,
|
||||||
|
$strictRight : Op.strictRight,
|
||||||
|
$noExtendRight: Op.noExtendRight,
|
||||||
|
$noExtendLeft : Op.noExtendLeft,
|
||||||
|
$substring : Op.substring,
|
||||||
|
$startsWith : Op.startsWith,
|
||||||
|
$endsWith : Op.endsWith,
|
||||||
|
$and : Op.and,
|
||||||
|
$or : Op.or,
|
||||||
|
$any : Op.any,
|
||||||
|
$all : Op.all,
|
||||||
|
$values : Op.values,
|
||||||
|
$col : Op.col
|
||||||
|
};
|
||||||
|
return operatorsAliases
|
||||||
|
}
|
||||||
|
|
||||||
|
//文件md5值
|
||||||
|
getFileMd5(url) {
|
||||||
|
const buffer = fs.readFileSync(url);
|
||||||
|
const hash = require('crypto').createHash('md5');
|
||||||
|
hash.update(buffer, 'utf8');
|
||||||
|
const md5 = hash.digest('hex');
|
||||||
|
return md5
|
||||||
|
}
|
||||||
|
|
||||||
//注册 router
|
//注册 router
|
||||||
registeredRouter() {
|
registeredRouter() {
|
||||||
console.log('注册 router');
|
console.log('注册 router');
|
||||||
const router = new Router();
|
const router = new Router();
|
||||||
const hash = requireDirectory(module, this.path('app/controller'), {
|
const hash = requireDirectory(module, this.path('app/controller'), {
|
||||||
visit: (c) => {
|
visit: (obj) => {
|
||||||
for (let methodElement of c.method) {
|
for (let methodElement of obj.method) {
|
||||||
router[methodElement](c.path, async (ctx, next) => {
|
router[methodElement](obj.path, async (ctx, next) => {
|
||||||
ctx['logger'] = this.logger
|
ctx['logger'] = this.logger
|
||||||
await c.controller(ctx, this.application)
|
await obj.controller(ctx, this.application)
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return c
|
return obj
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
super.use(router.routes())
|
super.use(router.routes())
|
||||||
super.use(router.allowedMethods())
|
super.use(router.allowedMethods())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//注册 事件
|
||||||
|
registeredEvent() {
|
||||||
|
console.log('注册 事件');
|
||||||
|
const hash = requireDirectory(module, this.path('app/event'), {
|
||||||
|
visit: (obj, joined, filename) => {
|
||||||
|
const parse = path.parse(filename);
|
||||||
|
// super.on(parse.name, obj);
|
||||||
|
for (let key of Object.keys(obj)) {
|
||||||
|
this.event.on(`${parse.name}.${key}`, obj[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(this.event.listeners);
|
||||||
|
}
|
||||||
|
|
||||||
|
//注册 定时任务
|
||||||
|
registeredSchedule() {
|
||||||
|
console.log('注册 定时任务');
|
||||||
|
const hash = requireDirectory(module, this.path('app/schedule'), {
|
||||||
|
visit: (obj, joined, filename) => {
|
||||||
|
//https://www.cnblogs.com/yalong/p/15601391.html
|
||||||
|
if (!process.env.NODE_APP_INSTANCE || process.env.NODE_APP_INSTANCE === '0') { //防止pm2多个线程重复执行
|
||||||
|
const parse = path.parse(filename);
|
||||||
|
if (obj.run) { obj.schedule(this.application) }
|
||||||
|
schedule.scheduleJob(parse.name, obj.time, () => obj.schedule(this.application))
|
||||||
|
}
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
//注册 middleware
|
//注册 middleware
|
||||||
registeredMiddleware() {
|
registeredMiddleware() {
|
||||||
console.log('注册 middleware');
|
console.log('注册 middleware');
|
||||||
@@ -78,7 +333,7 @@ module.exports = class Bamboo extends Koa {
|
|||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log(hash);
|
// console.log(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
//注册 utils
|
//注册 utils
|
||||||
@@ -119,11 +374,500 @@ module.exports = class Bamboo extends Koa {
|
|||||||
return xe
|
return xe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetDbData() {
|
||||||
|
this.tableData = null
|
||||||
|
this.tableWhere = null
|
||||||
|
this.tablePage = null
|
||||||
|
this.tableLimit = null
|
||||||
|
this.tableOrder = null
|
||||||
|
this.tableGroup = null
|
||||||
|
this.tableAttributes = null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定表名
|
||||||
|
* @param {object} data 表名.
|
||||||
|
*/
|
||||||
|
table(data) {
|
||||||
|
this.tableName = data
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置事务
|
||||||
|
*/
|
||||||
|
async setTransaction() {
|
||||||
|
console.log("设置事务");
|
||||||
|
this.t = await this.mysql.transaction()
|
||||||
|
return this.t
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交事务,如果设置了事务不提交,任务不会执行
|
||||||
|
*/
|
||||||
|
async commitTransaction() {
|
||||||
|
try {
|
||||||
|
await this.t.commit()
|
||||||
|
} catch (error) {
|
||||||
|
await this.t.rollback()
|
||||||
|
}
|
||||||
|
this.t = null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 筛选条件
|
||||||
|
* @param {object} data 筛选条件对象.
|
||||||
|
*/
|
||||||
|
where(data) {
|
||||||
|
this.tableWhere = data
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模糊查询
|
||||||
|
* @param {string} value 模糊查询内容.
|
||||||
|
* @param {array} searchData 模糊查询搜索的字段(默认表的全部字段).
|
||||||
|
*/
|
||||||
|
search(value, searchData) {
|
||||||
|
if (!this.tableName) { this.errorException.HttpException("请传表名") }
|
||||||
|
if (!this.tableWhere) { this.tableWhere = {} }
|
||||||
|
if (!this.tableWhere['$or']) {
|
||||||
|
this.tableWhere['$or'] = []
|
||||||
|
}
|
||||||
|
if (!searchData) {
|
||||||
|
searchData = Object.keys(this.mysql.models[this.tableName].rawAttributes)
|
||||||
|
}
|
||||||
|
for (let key of searchData) {
|
||||||
|
const search = {}
|
||||||
|
search[key] = {"$substring": value || ''}
|
||||||
|
this.tableWhere['$or'].push(search)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据分组
|
||||||
|
* @param {string|array} value 传需要分组的字段['createdAt'].
|
||||||
|
*/
|
||||||
|
group(value) {
|
||||||
|
this.tableGroup = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据分组
|
||||||
|
* @param {string|array} value 传需要分组的字段['createdAt'].
|
||||||
|
*/
|
||||||
|
attributes(value) {
|
||||||
|
this.tableAttributes = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页数
|
||||||
|
* @param {int} value 页数从0开始.
|
||||||
|
*/
|
||||||
|
|
||||||
|
page(value) {
|
||||||
|
this.tablePage = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 条数
|
||||||
|
* @param {int} value 条数.
|
||||||
|
*/
|
||||||
|
limit(value) {
|
||||||
|
this.tableLimit = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
get getLimit() {
|
||||||
|
return this.tableLimit || null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据
|
||||||
|
* @param {any} value 数据.
|
||||||
|
*/
|
||||||
|
data(value) {
|
||||||
|
this.tableData = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间排序
|
||||||
|
* @param {array} value 时间排序(默认按更新时间排序).
|
||||||
|
*/
|
||||||
|
order(value) {
|
||||||
|
this.tableOrder = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字段值增加
|
||||||
|
* @param {string} data 要增加的字段和值{xxx:1,xxxx:2}.
|
||||||
|
* @param {number} max 字段增加后的值不能大于最大值
|
||||||
|
* @param {number} setValue 如果增加后的字段大于max,设置字段值为n
|
||||||
|
*/
|
||||||
|
async setInc(max, setValue) {
|
||||||
|
if (!this.tableName) { this.errorException.HttpException("请传表名") }
|
||||||
|
if (!this.tableData) { this.errorException.HttpException("请数据") }
|
||||||
|
if (!this.tableWhere) { this.errorException.HttpException("请筛选值") }
|
||||||
|
|
||||||
|
let res = await this.mysql.models[this.tableName].findOne(
|
||||||
|
{
|
||||||
|
where : this.tableWhere,
|
||||||
|
transaction: this.t
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
for (let key of Object.keys(this.tableData)) {
|
||||||
|
if (res[key] + this.tableData[key] > max) {
|
||||||
|
if (setValue === 0 || setValue) {
|
||||||
|
const data = {}
|
||||||
|
Object.keys(this.tableData).map(item => {data[item] = setValue})
|
||||||
|
await this.mysql.models[this.tableName].update(
|
||||||
|
data,
|
||||||
|
{
|
||||||
|
where : this.tableWhere,
|
||||||
|
transaction: this.t
|
||||||
|
}
|
||||||
|
)
|
||||||
|
res = {
|
||||||
|
...res.dataValues,
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
return {res: true, value: res}
|
||||||
|
}
|
||||||
|
return {res: false, value: res}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.mysql.models[this.tableName].increment(
|
||||||
|
this.tableData,
|
||||||
|
{
|
||||||
|
where : this.tableWhere,
|
||||||
|
transaction: this.t
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
res = await this.mysql.models[this.tableName].findOne(
|
||||||
|
{
|
||||||
|
where : this.tableWhere,
|
||||||
|
transaction: this.t
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return {res: true, value: res.dataValues}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字段值减小
|
||||||
|
* @param {string} data 要减小的字段和值{xxx:1,xxxx:2}.
|
||||||
|
* @param {number} min 字段减小后的值不能小于最小值
|
||||||
|
* @param {number} setValue 如果减小后的字段小于min,设置字段值为n
|
||||||
|
*/
|
||||||
|
async setDec(min, setValue) {
|
||||||
|
if (!this.tableName) { this.errorException.HttpException("请传表名") }
|
||||||
|
if (!this.tableData) { this.errorException.HttpException("请数据") }
|
||||||
|
if (!this.tableWhere) { this.errorException.HttpException("请筛选值") }
|
||||||
|
|
||||||
|
let res = await this.mysql.models[this.tableName].findOne(
|
||||||
|
{
|
||||||
|
where : this.tableWhere,
|
||||||
|
transaction: this.t
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
for (let key of Object.keys(this.tableData)) {
|
||||||
|
if (res[key] - this.tableData[key] < min) {
|
||||||
|
if (setValue === 0 || setValue) {
|
||||||
|
const data = {}
|
||||||
|
Object.keys(this.tableData).map(item => {data[item] = setValue})
|
||||||
|
await this.mysql.models[this.tableName].update(
|
||||||
|
data,
|
||||||
|
{
|
||||||
|
where : this.tableWhere,
|
||||||
|
transaction: this.t
|
||||||
|
}
|
||||||
|
)
|
||||||
|
res = {
|
||||||
|
...res.dataValues,
|
||||||
|
...data
|
||||||
|
}
|
||||||
|
return {res: true, value: res}
|
||||||
|
}
|
||||||
|
return {res: false, value: res}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.mysql.models[this.tableName].decrement(
|
||||||
|
this.tableData,
|
||||||
|
{
|
||||||
|
where : this.tableWhere,
|
||||||
|
transaction: this.t
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
res = await this.mysql.models[this.tableName].findOne(
|
||||||
|
{
|
||||||
|
where : this.tableWhere,
|
||||||
|
transaction: this.t
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return {res: true, value: res.dataValues}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 常用时间筛选
|
||||||
|
* @param {string|array|Number} value 时间内容:按时间段:['2000-1-1','2000-1-2'],按常用时间:day,按最近60分钟:60.
|
||||||
|
* @param {string} field 时间字段(默认createdAt字段)
|
||||||
|
*/
|
||||||
|
time(value, field) {
|
||||||
|
if (!this.tableName) { this.errorException.HttpException("请传表名") }
|
||||||
|
if (!field) { field = "createdAt"}
|
||||||
|
if (!this.tableWhere) { this.tableWhere = {} }
|
||||||
|
if (!this.tableWhere['$and']) {
|
||||||
|
this.tableWhere['$and'] = []
|
||||||
|
}
|
||||||
|
const {fn, col, where, literal} = Sequelize
|
||||||
|
switch (value) {
|
||||||
|
case 'yday': // 昨天
|
||||||
|
this.tableWhere['$and'].push(where(fn('TO_DAYS', col(this.tableName + '.' + field)), '-', fn('TO_DAYS', fn('NOW')), '<=', 1))
|
||||||
|
break;
|
||||||
|
case 'day': //当天
|
||||||
|
this.tableWhere['$and'].push(where(fn('TO_DAYS', col(this.tableName + '.' + field)), '=', fn('TO_DAYS', fn('NOW'))))
|
||||||
|
break;
|
||||||
|
case 'week': //本周
|
||||||
|
this.tableWhere['$and'].push(where(fn('YEARWEEK', fn('date_format', col(this.tableName + '.' + field), '%Y-%m-%d')), '=', fn('YEARWEEK', fn('now'))))
|
||||||
|
break;
|
||||||
|
case 'month': //当月
|
||||||
|
this.tableWhere['$and'].push(where(fn('DATE_FORMAT', col(this.tableName + '.' + field), '%Y%m'), '=', fn('DATE_FORMAT', fn('CURDATE'), '%Y%m')))
|
||||||
|
break;
|
||||||
|
case 'lmonth': //上个月
|
||||||
|
this.tableWhere['$and'].push(where(fn('PERIOD_DIFF', fn('date_format', fn('now'), '%Y%m'), fn('date_format', col(this.tableName + '.' + field), '%Y%m')), '=', 1))
|
||||||
|
break;
|
||||||
|
case 'year': //当年
|
||||||
|
this.tableWhere['$and'].push(where(fn('YEAR', col(this.tableName + '.' + field)), '=', fn('YEAR', fn('NOW'))))
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (xe.isArray(value)) { //时间范围筛选
|
||||||
|
const data = {}
|
||||||
|
data[field] = {"$between": value}
|
||||||
|
this.tableWhere['$and'].push(data)
|
||||||
|
}
|
||||||
|
if (xe.isNumber(value)) {
|
||||||
|
const minute = {}
|
||||||
|
minute[field] = {"$lt": new Date(), "$gt": new Date(new Date() - value * 60 * 1000)}
|
||||||
|
this.tableWhere['$and'].push(minute)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询1条数据
|
||||||
|
* @param {Transaction} options.transaction 运行查询的事务.
|
||||||
|
*/
|
||||||
|
async find(options) {
|
||||||
|
if (!this.tableName) { this.errorException.HttpException("请传表名") }
|
||||||
|
const res = await this.mysql.models[this.tableName].findOne(
|
||||||
|
{
|
||||||
|
where : this.tableWhere,
|
||||||
|
transaction: this.t
|
||||||
|
}
|
||||||
|
)
|
||||||
|
this.resetDbData()
|
||||||
|
return res && res.dataValues || null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新数据
|
||||||
|
* @param {object} data 数据.
|
||||||
|
* @param {boolean} options.paranoid 如果为 true,则只会更新未删除的记录。如果为 false,将更新已删除和未删除的记录。仅适用于模型的 options.paranoid 为真。.
|
||||||
|
* @param {Array} options.fields 要更新的字段(默认为所有字段)
|
||||||
|
* @param {boolean} options.validate 每一行在插入之前是否应该经过验证。如果一行未通过验证,则整个插入将失败
|
||||||
|
* @param {boolean} options.hooks 在批量更新挂钩之后运行?
|
||||||
|
* @param {boolean} options.sideEffects 是否更新任何虚拟二传手的副作用。
|
||||||
|
* @param {boolean} options.individualHooks 在更新挂钩之前运行?如果为真,这将执行一个 SELECT,然后执行单独的 UPDATE。需要一个选择,因为需要将行数据传递给钩子
|
||||||
|
* @param {boolean | Array} options.returning 如果为真,则附加 RETURNING <model columns> 以取回所有定义的值;如果是列名数组,则附加 RETURNING <columns> 以获取特定列(仅限 Postgres)
|
||||||
|
* @param {number} options.limit 要更新多少行(仅适用于 mysql 和 mariadb,对于 MSSQL 实现为 TOP(n);对于 sqlite,仅当存在 rowid 时才支持)
|
||||||
|
* @param {Function} options.logging在运行查询以记录 sql 时执行的函数。
|
||||||
|
* @param {boolean} options.benchmark 将查询执行时间(以毫秒为单位)作为第二个参数传递给日志记录函数(options.logging)。
|
||||||
|
* @param {Transaction} options.transaction 运行查询的事务
|
||||||
|
* @param {boolean} options.silent 如果为 true,则不会更新 updatedAt 时间戳。
|
||||||
|
*/
|
||||||
|
async update(options) {
|
||||||
|
if (!this.tableName) { this.errorException.HttpException("请传表名") }
|
||||||
|
if (!this.tableData) { this.errorException.HttpException("请数据") }
|
||||||
|
const res = await this.mysql.models[this.tableName].update(
|
||||||
|
this.tableData,
|
||||||
|
{
|
||||||
|
where: this.tableWhere,
|
||||||
|
...options
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除数据
|
||||||
|
* @param {object} options 参数.
|
||||||
|
* @param {boolean} options.hooks 在批量销毁挂钩之前运行.
|
||||||
|
* @param {boolean} options.individualHooks 如果设置为 true,destroy 将选择与 where 参数匹配的所有记录,并将在每行上的 destroy 钩子之前执行.
|
||||||
|
* @param {number} options.limit 要删除多少行.
|
||||||
|
* @param {boolean} options.force 删除而不是将 deletedAt 设置为当前时间戳(仅在启用偏执狂时适用).
|
||||||
|
* @param {boolean} options.truncate 如果设置为 true,支持它的方言将使用 TRUNCATE 而不是 DELETE FROM。如果表被截断,则忽略 where 和 limit 选项.
|
||||||
|
* @param {boolean} options.cascade 仅与 TRUNCATE 一起使用。截断所有具有对命名表的外键引用的表,或者截断由于 CASCADE 而添加到组中的任何表.
|
||||||
|
* @param {transaction} options.transaction 运行查询的事务.
|
||||||
|
* @param {Function} options.logging 在运行查询以记录 sql 时执行的函数。
|
||||||
|
* @param {boolean} options.benchmark 将查询执行时间(以毫秒为单位)作为第二个参数传递给日志记录函数(options.logging)。
|
||||||
|
*/
|
||||||
|
async delete(options) {
|
||||||
|
if (!this.tableName) { this.errorException.HttpException("请传表名") }
|
||||||
|
const res = await this.mysql.models[this.tableName].destroy(
|
||||||
|
{
|
||||||
|
where: this.tableWhere,
|
||||||
|
...options
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存数据,如果数据已存在就更新,否则创建数据,可以传对象或数组,如果是需要更新数据,必须包含id
|
||||||
|
*/
|
||||||
|
async save() {
|
||||||
|
if (!this.tableName) { this.errorException.HttpException("请传表名") }
|
||||||
|
if (!this.tableData) { this.errorException.HttpException("请传要保存的数据") }
|
||||||
|
let data = this.tableData
|
||||||
|
let updateOnDuplicate = []
|
||||||
|
let keyData = {}
|
||||||
|
if (xe.isArray(data)) {
|
||||||
|
if (!data.length) { this.errorException.HttpException("请传要保存的数据") }
|
||||||
|
keyData = data[0]
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
keyData = data
|
||||||
|
data = [data]
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let key of Object.keys(keyData)) {
|
||||||
|
if (key !== 'id') { updateOnDuplicate.push(key) }
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await this.mysql.models[this.tableName].bulkCreate(data,
|
||||||
|
{returning: true, updateOnDuplicate: updateOnDuplicate, transaction: this.t}
|
||||||
|
)
|
||||||
|
this.resetDbData()
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有符合条件的数据
|
||||||
|
* @return {array} dataValues 查询结果.
|
||||||
|
*/
|
||||||
|
async findAll() {
|
||||||
|
if (!this.tableName) { this.errorException.HttpException("请传表名") }
|
||||||
|
const res = await this.mysql.models[this.tableName].findAll(
|
||||||
|
{
|
||||||
|
where : this.tableWhere,
|
||||||
|
offset : (this.tablePage && this.tableLimit) ? this.tablePage - 1 * this.tableLimit : null,
|
||||||
|
limit : this.tableLimit,
|
||||||
|
order : this.tableOrder || [['updatedAt', 'DESC']], // 时间排序
|
||||||
|
group : this.tableGroup,
|
||||||
|
attributes : this.tableAttributes,
|
||||||
|
transaction: this.t
|
||||||
|
}
|
||||||
|
)
|
||||||
|
this.resetDbData()
|
||||||
|
return res.map(item => item.dataValues)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果数据不存在就创建数据,否则反查询结果
|
||||||
|
* @return {object} dataValues 查询结果.
|
||||||
|
*/
|
||||||
|
async findOrCreate() {
|
||||||
|
if (!this.tableName) { this.errorException.HttpException("请传表名") }
|
||||||
|
if (!this.tableData) { this.errorException.HttpException("请传data") }
|
||||||
|
const res = await this.mysql.models[this.tableName].findOrCreate(
|
||||||
|
{
|
||||||
|
defaults : this.tableData,
|
||||||
|
where : this.tableWhere,
|
||||||
|
transaction: this.t
|
||||||
|
}
|
||||||
|
)
|
||||||
|
this.resetDbData()
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询数据
|
||||||
|
* @param {array} args.include 关联查询.
|
||||||
|
* @return {int} count 总行数.
|
||||||
|
* @return {array} rows 数据列表.
|
||||||
|
*/
|
||||||
|
async findAndCountAll(args = {}) {
|
||||||
|
if (!this.tableName) { this.errorException.HttpException("请传表名") }
|
||||||
|
const {count, rows} = await this.mysql.models[this.tableName].findAndCountAll(
|
||||||
|
{
|
||||||
|
where : this.tableWhere,
|
||||||
|
offset : (this.tablePage && this.tableLimit) ? this.tablePage - 1 * this.tableLimit : null,
|
||||||
|
limit : this.tableLimit,
|
||||||
|
order : this.tableOrder || [['updatedAt', 'DESC']], // 时间排序
|
||||||
|
group : this.tableGroup,
|
||||||
|
attributes : this.tableAttributes,
|
||||||
|
transaction: this.t
|
||||||
|
}
|
||||||
|
)
|
||||||
|
this.resetDbData()
|
||||||
|
return {count, rows: rows.map(item => item.dataValues)}
|
||||||
|
}
|
||||||
|
|
||||||
get application() {
|
get application() {
|
||||||
return {
|
return {
|
||||||
|
config : this.config,
|
||||||
utils : this.utils,
|
utils : this.utils,
|
||||||
logger: this.logger,
|
log : this.logger,
|
||||||
err : error,
|
err : this.errorException,
|
||||||
|
event : this.event,
|
||||||
|
sequelize : this.Sequelize,
|
||||||
|
mysql : this.mysql,
|
||||||
|
sqlite : this.sqlite,
|
||||||
|
table : this.table,
|
||||||
|
where : this.where,
|
||||||
|
data : this.data,
|
||||||
|
search : this.search,
|
||||||
|
group : this.group,
|
||||||
|
attributes : this.attributes,
|
||||||
|
page : this.page,
|
||||||
|
setDec : this.setDec,
|
||||||
|
setInc : this.setInc,
|
||||||
|
limit : this.limit,
|
||||||
|
time : this.time,
|
||||||
|
setTransaction : this.setTransaction,
|
||||||
|
commitTransaction: this.commitTransaction,
|
||||||
|
save : this.save,
|
||||||
|
find : this.find,
|
||||||
|
findAll : this.findAll,
|
||||||
|
findOrCreate : this.findOrCreate,
|
||||||
|
findAndCountAll : this.findAndCountAll,
|
||||||
|
resetDbData : this.resetDbData,
|
||||||
|
//======= 简写函数
|
||||||
|
// S: this.sqlite.models,
|
||||||
|
// M: this.mysql.models,
|
||||||
|
C: this.config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.5.5",
|
"@babel/core": "^7.5.5",
|
||||||
|
"@babel/plugin-proposal-class-properties": "^7.16.7",
|
||||||
|
"@babel/plugin-proposal-decorators": "^7.17.9",
|
||||||
"@babel/plugin-transform-runtime": "^7.5.5",
|
"@babel/plugin-transform-runtime": "^7.5.5",
|
||||||
"@babel/preset-env": "^7.5.5",
|
"@babel/preset-env": "^7.5.5",
|
||||||
"@babel/register": "^7.5.5",
|
"@babel/register": "^7.5.5",
|
||||||
@@ -44,13 +46,18 @@
|
|||||||
"clean-webpack-plugin": "^4.0.0",
|
"clean-webpack-plugin": "^4.0.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"koa-bodyparser": "^4.3.0",
|
"koa-bodyparser": "^4.3.0",
|
||||||
|
"koa-json-error": "^3.1.2",
|
||||||
"koa-logger": "^2.0.1",
|
"koa-logger": "^2.0.1",
|
||||||
"koa-redis": "^4.0.1",
|
"koa-redis": "^4.0.1",
|
||||||
"log4js": "^6.4.4",
|
"log4js": "^6.4.4",
|
||||||
|
"mysql2": "^2.3.3",
|
||||||
|
"node-schedule": "^2.1.0",
|
||||||
"pm2": "^5.1.2",
|
"pm2": "^5.1.2",
|
||||||
"require-all": "^3.0.0",
|
"require-all": "^3.0.0",
|
||||||
"require-directory": "^2.1.1",
|
"require-directory": "^2.1.1",
|
||||||
|
"sequelize": "^6.18.0",
|
||||||
"shelljs": "^0.8.5",
|
"shelljs": "^0.8.5",
|
||||||
|
"sqlite3": "^5.0.2",
|
||||||
"webpack": "^4.41.5",
|
"webpack": "^4.41.5",
|
||||||
"webpack-cli": "3.3.10",
|
"webpack-cli": "3.3.10",
|
||||||
"webpack-node-externals": "^3.0.0",
|
"webpack-node-externals": "^3.0.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user