commit
06ec52b00b
48 changed files with 6201 additions and 0 deletions
@ -0,0 +1,2 @@ |
|||||
|
node_modules |
||||
|
.idea |
@ -0,0 +1,3 @@ |
|||||
|
{ |
||||
|
"sqltools.connections": [] |
||||
|
} |
@ -0,0 +1,60 @@ |
|||||
|
// require('module-alias/register')
|
||||
|
require('./global/index.js'); |
||||
|
|
||||
|
const Koa = require('koa'); |
||||
|
const jwt = require('koa-jwt'); |
||||
|
const views = require('koa-views'); |
||||
|
const serve = require('koa-static'); |
||||
|
const app = new Koa(); |
||||
|
const cors = require('@koa/cors'); |
||||
|
const koaBody = require('koa-body'); |
||||
|
const router = require('./routes/index.js'); |
||||
|
const config = require('./config.js'); |
||||
|
const path = require('path') |
||||
|
|
||||
|
app.use(serve(path.join(__dirname + '/public'))); |
||||
|
app.use(views(path.join(__dirname + '/public'), { |
||||
|
extension: 'pug' |
||||
|
})); |
||||
|
app.use(cors()); |
||||
|
|
||||
|
// Custom 401 handling if you don't want to expose koa-jwt errors to users
|
||||
|
app.use(async (ctx, next) => { |
||||
|
return next().catch((err) => { |
||||
|
if (401 == err.status) { |
||||
|
ctx.status = 401; |
||||
|
ctx.body = { |
||||
|
message: 'Protected resource, use Authorization header to get access\n', |
||||
|
data: null, |
||||
|
code: 401 |
||||
|
}; |
||||
|
} else { |
||||
|
throw err; |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
// https://www.v2ex.com/t/320710有关token不需要状态,可以多人登录同一个账号
|
||||
|
app.use(jwt({ |
||||
|
secret: config.share_key |
||||
|
}).unless({ |
||||
|
path: [/^\/api\/login/, /^\/api\/register/, /^((?!\/api).)*$/,/^\/api\/menus\/getAll/] |
||||
|
})); |
||||
|
|
||||
|
|
||||
|
// logger
|
||||
|
app.use(async (ctx, next) => { |
||||
|
const start = new Date() |
||||
|
await next() |
||||
|
const ms = new Date() - start |
||||
|
log(`${ctx.method} ${ctx.url} - ${ms}ms`) |
||||
|
}); |
||||
|
// 请求解析
|
||||
|
app.use(koaBody()); |
||||
|
// 路由注册
|
||||
|
app.use(router.routes()).use(router.allowedMethods()); |
||||
|
// error-handling
|
||||
|
app.on('error', (err, ctx) => { |
||||
|
console.error('server error', err, ctx) |
||||
|
}); |
||||
|
|
||||
|
module.exports = app |
@ -0,0 +1,90 @@ |
|||||
|
#!/usr/bin/env node |
||||
|
|
||||
|
/** |
||||
|
* Module dependencies. |
||||
|
*/ |
||||
|
|
||||
|
var app = require('../app'); |
||||
|
var debug = require('debug')('demo:server'); |
||||
|
var http = require('http'); |
||||
|
|
||||
|
/** |
||||
|
* Get port from environment and store in Express. |
||||
|
*/ |
||||
|
|
||||
|
var port = normalizePort(process.env.PORT || '3000'); |
||||
|
// app.set('port', port); |
||||
|
|
||||
|
/** |
||||
|
* Create HTTP server. |
||||
|
*/ |
||||
|
|
||||
|
var server = http.createServer(app.callback()); |
||||
|
|
||||
|
/** |
||||
|
* Listen on provided port, on all network interfaces. |
||||
|
*/ |
||||
|
|
||||
|
server.listen(port); |
||||
|
server.on('error', onError); |
||||
|
server.on('listening', onListening); |
||||
|
|
||||
|
/** |
||||
|
* Normalize a port into a number, string, or false. |
||||
|
*/ |
||||
|
|
||||
|
function normalizePort(val) { |
||||
|
var port = parseInt(val, 10); |
||||
|
|
||||
|
if (isNaN(port)) { |
||||
|
// named pipe |
||||
|
return val; |
||||
|
} |
||||
|
|
||||
|
if (port >= 0) { |
||||
|
// port number |
||||
|
return port; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Event listener for HTTP server "error" event. |
||||
|
*/ |
||||
|
|
||||
|
function onError(error) { |
||||
|
if (error.syscall !== 'listen') { |
||||
|
throw error; |
||||
|
} |
||||
|
|
||||
|
var bind = typeof port === 'string' ? |
||||
|
'Pipe ' + port : |
||||
|
'Port ' + port; |
||||
|
|
||||
|
// handle specific listen errors with friendly messages |
||||
|
switch (error.code) { |
||||
|
case 'EACCES': |
||||
|
console.error(bind + ' requires elevated privileges'); |
||||
|
process.exit(1); |
||||
|
break; |
||||
|
case 'EADDRINUSE': |
||||
|
console.error(bind + ' is already in use'); |
||||
|
process.exit(1); |
||||
|
break; |
||||
|
default: |
||||
|
throw error; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Event listener for HTTP server "listening" event. |
||||
|
*/ |
||||
|
|
||||
|
function onListening() { |
||||
|
var addr = server.address(); |
||||
|
var bind = typeof addr === 'string' ? |
||||
|
'pipe ' + addr : |
||||
|
'port ' + addr.port; |
||||
|
debug('Listening on ' + bind); |
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
/** |
||||
|
* 逻辑文案管理 |
||||
|
*/ |
||||
|
|
||||
|
const sysCode = { |
||||
|
|
||||
|
SUCCESS: "success", |
||||
|
Fail: "fail", |
||||
|
} |
||||
|
|
||||
|
|
||||
|
module.exports = sysCode |
@ -0,0 +1,32 @@ |
|||||
|
/** |
||||
|
* 逻辑文案管理 |
||||
|
*/ |
||||
|
|
||||
|
const userCode = { |
||||
|
|
||||
|
ERROR_USER_NAME: '用户名格式为6-16位的小写字母,包括-、_', |
||||
|
|
||||
|
ERROR_EMAIL: '请输入正确的邮箱地址', |
||||
|
|
||||
|
ERROR_PASSWORD: '密码长度应该为6-16', |
||||
|
|
||||
|
ERROR_PASSWORD_CONFORM: '两次密码不一致', |
||||
|
|
||||
|
ERROR_SYS: '系统错误', |
||||
|
|
||||
|
FAIL_EMAIL_IS_EXIST: '邮箱已被注册', |
||||
|
|
||||
|
FAIL_USER_NAME_IS_EXIST: '用户名已被注册', |
||||
|
|
||||
|
FAIL_USER_NAME_OR_PASSWORD_ERROR: '用户名或登录密码错误', |
||||
|
|
||||
|
FAIL_USER_NO_LOGIN: '用户未登录', |
||||
|
FAIL_USER_NO_EXIST: '用户不存在', |
||||
|
ERROR_USER_EMPTY: '用户名不能为空', |
||||
|
ERROR_MORE_USER: '查询到多个用户', |
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
module.exports = userCode |
@ -0,0 +1,11 @@ |
|||||
|
module.exports = { |
||||
|
db: { |
||||
|
host: '47.244.111.211', |
||||
|
port: '3306', |
||||
|
user: 'noderest', |
||||
|
password: '8WBtsejYGiEESJMh', |
||||
|
database: 'noderest', |
||||
|
connectTimeout:3000 |
||||
|
}, |
||||
|
share_key: 'dsadasdasd' |
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
const fs = require('fs'); |
||||
|
const path = require('path'); |
||||
|
const Bean = require('../utils/index.js'); |
||||
|
|
||||
|
// 控制器收集规则
|
||||
|
const routes = fs.readdirSync(path.resolve(__dirname)); |
||||
|
const controler = {}; |
||||
|
routes.forEach(route => { |
||||
|
if (fs.statSync(path.resolve(__dirname, route)).isDirectory()) { |
||||
|
const deep = Bean.readFileDeep(path.resolve(__dirname, route)).file; |
||||
|
|
||||
|
controler[route] = {}; |
||||
|
deep.forEach(file => { |
||||
|
Object.keys(require(file)).forEach(key => { |
||||
|
if (Object.keys(controler[route]).includes(key)) { |
||||
|
let str = "注意有相同的控制器:{" + route + ':' + key + '}'; |
||||
|
throw str |
||||
|
} |
||||
|
}) |
||||
|
controler[route] = { |
||||
|
...controler[route], |
||||
|
...require(file) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
if (fs.statSync(path.resolve(__dirname, route)).isFile()) { |
||||
|
if (route !== 'index.js') { |
||||
|
controler[route.slice(0, -3)] = require(path.resolve(__dirname, route)); |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
module.exports = controler |
@ -0,0 +1,258 @@ |
|||||
|
const menuServices = require('../../services/menus.js') |
||||
|
|
||||
|
|
||||
|
function findeBelong(data, index) { |
||||
|
let array = []; |
||||
|
for (let i = data.length - 1; i >= 0; i--) { |
||||
|
if (data[i].belongto == index) { |
||||
|
const obj = { |
||||
|
id: data[i].id, |
||||
|
name: data[i].name, |
||||
|
desc: data[i].about, |
||||
|
children: [] |
||||
|
} |
||||
|
array.push(obj); |
||||
|
data.splice(i, 1); |
||||
|
} |
||||
|
} |
||||
|
return array; |
||||
|
} |
||||
|
|
||||
|
function sortTree(arr, all) { |
||||
|
let tree = (arr, all) => { |
||||
|
for (let i = 0; i < arr.length; i++) { |
||||
|
let item = findeBelong(all, arr[i].id); |
||||
|
for (let j = 0; j < item.length; j++) { |
||||
|
const obj = { |
||||
|
id: item[j].id, |
||||
|
name: item[j].name, |
||||
|
desc: item[j].desc, |
||||
|
children: [] |
||||
|
} |
||||
|
arr[i].children.push(obj); |
||||
|
} |
||||
|
tree(arr[i].children, all) |
||||
|
} |
||||
|
} |
||||
|
tree(arr, all) |
||||
|
} |
||||
|
|
||||
|
module.exports = { |
||||
|
/** |
||||
|
* 获取所有的菜单 |
||||
|
* @param ctx |
||||
|
* @param next |
||||
|
* @returns {Promise<void>} |
||||
|
*/ |
||||
|
async getAll(ctx, next) { |
||||
|
let result = { |
||||
|
success: false, |
||||
|
message: '', |
||||
|
data: null |
||||
|
} |
||||
|
let getResult = await menuServices.getAllMenus(); |
||||
|
if (getResult && Array.isArray(getResult)) { |
||||
|
let menus = JSON.parse(JSON.stringify(getResult)); |
||||
|
let fa = findeBelong(menus, '0'); |
||||
|
sortTree(fa, menus); |
||||
|
if (menus.length > 0) { |
||||
|
result.success = false; |
||||
|
result.message = '菜单不完整'; |
||||
|
ctx.body = result |
||||
|
return |
||||
|
} else { |
||||
|
result.success = true; |
||||
|
result.message = 'success'; |
||||
|
result.data = fa; |
||||
|
} |
||||
|
|
||||
|
} else{ |
||||
|
result.success = false; |
||||
|
result.message = 'fail'; |
||||
|
ctx.body = result |
||||
|
return ; |
||||
|
} |
||||
|
//menus有长度表示还有菜单没消耗完
|
||||
|
ctx.body = result |
||||
|
}, |
||||
|
/** |
||||
|
* 创建菜单 |
||||
|
* @param ctx |
||||
|
* @param next |
||||
|
* @returns {Promise<void>} |
||||
|
*/ |
||||
|
async createOne(ctx, next) { |
||||
|
let result = { |
||||
|
success: false, |
||||
|
message: '', |
||||
|
data: null |
||||
|
} |
||||
|
let formData = ctx.request.body; |
||||
|
|
||||
|
//验证参数的必需
|
||||
|
let menuResult = await menuServices.validatorNeed(formData, [ |
||||
|
{key: 'name', error: '标题不能为空', validate: (data) => data == undefined}, |
||||
|
{key: 'belongto', error: '没有所属ID', validate: (data) => data == undefined} |
||||
|
]); |
||||
|
if (!menuResult.success) { |
||||
|
result.success = false; |
||||
|
result.message = menuResult.message; |
||||
|
ctx.body = result; |
||||
|
return; |
||||
|
} else { |
||||
|
// 验证所属ID是数据库中的
|
||||
|
if (Number(formData.belongto) > 0) { |
||||
|
let allMenus = await menuServices.getAllMenus(); |
||||
|
let allID = allMenus.map(v => v.id); |
||||
|
if (allID.indexOf(formData.belongto) == -1) { |
||||
|
result.success = false; |
||||
|
result.message = '没有该菜单'; |
||||
|
ctx.body = result; |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
let createResult = await menuServices.createMenu(formData); |
||||
|
if (createResult && createResult.insertId * 1 > 0) { |
||||
|
result.success = true; |
||||
|
result.message = '创建成功'; |
||||
|
} else { |
||||
|
result.success = true; |
||||
|
result.message = '系统错误'; |
||||
|
ctx.body = result; |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
ctx.body = result; |
||||
|
}, |
||||
|
/** |
||||
|
* |
||||
|
* 修改菜单 |
||||
|
*/ |
||||
|
async updateOne(ctx, next) { |
||||
|
let result = { |
||||
|
success: false, |
||||
|
message: '', |
||||
|
data: null |
||||
|
} |
||||
|
let formData = ctx.request.body; |
||||
|
//验证参数的必需
|
||||
|
let menuResult = await menuServices.validatorNeed(formData, [ |
||||
|
{key: 'id', error: 'id不能为空', validate: (data) => data == undefined}, |
||||
|
{ |
||||
|
key: 'id', error: '没有这个菜单', validate: async (data) => { |
||||
|
let allMenus = await menuServices.getAllMenus(); |
||||
|
let allID = allMenus.map(v => v.id); |
||||
|
if (allID.indexOf(formData.id) == -1) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
{key: 'belongto', error: '没有父类', validate: (data) => data == undefined || data < 0}, |
||||
|
{ |
||||
|
key: 'belongto', error: '没有父ID', validate: async (data) => { |
||||
|
if (data == 0) { |
||||
|
return false; |
||||
|
} |
||||
|
let allMenus = await menuServices.getAllMenus(); |
||||
|
let allID = allMenus.map(v => v.id); |
||||
|
if (allID.indexOf(formData.belongto) == -1) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
{key: 'id', error: 'ID不能与父ID相同', validate: (data) => formData.id == formData.belongto} |
||||
|
]); |
||||
|
if (!menuResult.success) { |
||||
|
result.success = false; |
||||
|
result.message = menuResult.message; |
||||
|
ctx.body = result; |
||||
|
return; |
||||
|
} else { |
||||
|
let updateResult = await menuServices.updateMenu(formData); |
||||
|
if (updateResult) { |
||||
|
result.success = true; |
||||
|
result.message = 'success'; |
||||
|
} else { |
||||
|
result.success = false; |
||||
|
result.message = 'fail'; |
||||
|
} |
||||
|
} |
||||
|
ctx.body = result; |
||||
|
}, |
||||
|
/** |
||||
|
* 删除菜单 |
||||
|
*/ |
||||
|
async deleteOne(ctx, next) { |
||||
|
let result = { |
||||
|
success: false, |
||||
|
message: '', |
||||
|
data: null |
||||
|
} |
||||
|
let formData = ctx.request.body; |
||||
|
//验证参数的必需
|
||||
|
let menuResult = await menuServices.validatorNeed(formData, [ |
||||
|
{key: 'id', error: 'id不能为空', validate: (data) => data == undefined}, |
||||
|
{ |
||||
|
key: 'id', error: '没有这个菜单', validate: async (data) => { |
||||
|
let allMenus = await menuServices.getAllMenus(); |
||||
|
let allID = allMenus.map(v => v.id); |
||||
|
if (allID.indexOf(formData.id) == -1) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
key: 'id', error: '这个菜单存在子菜单,替换ID出错', validate: async (data) => { |
||||
|
let judgeResult = await menuServices.judgeID(data); |
||||
|
if (formData.fix==0){ |
||||
|
return false; |
||||
|
} |
||||
|
if(judgeResult&&!formData.fix){ |
||||
|
return true |
||||
|
}else if(judgeResult&&formData.fix){ |
||||
|
//替换ID不能跟要删除的ID相同
|
||||
|
if (formData.fix==formData.id){ |
||||
|
return '替换ID不能跟要删除的ID相同'; |
||||
|
} |
||||
|
// 替换ID不能跟需要修改的ID相同
|
||||
|
let uID = judgeResult.map(v => v.id); |
||||
|
if (uID.indexOf(formData.fix) != -1) { |
||||
|
return '替换ID不能跟需要修改的ID相同'; |
||||
|
} |
||||
|
// 替换ID必须存在与菜单中
|
||||
|
let allMenus = await menuServices.getAllMenus(); |
||||
|
let allID = allMenus.map(v => v.id); |
||||
|
if (allID.indexOf(formData.fix) == -1) { |
||||
|
return '替换ID必须存在与菜单中'; |
||||
|
}else { |
||||
|
return false; |
||||
|
} |
||||
|
}else { |
||||
|
return false |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
]); |
||||
|
if (!menuResult.success) { |
||||
|
result.success = false; |
||||
|
result.message = menuResult.message; |
||||
|
ctx.body = result; |
||||
|
return; |
||||
|
} else { |
||||
|
let judgeResult = await menuServices.judgeID(formData.id); |
||||
|
let deleteResult = await menuServices.deleteMenu(formData,judgeResult,formData.fix); |
||||
|
if (deleteResult){ |
||||
|
//删除成功
|
||||
|
result.success = true; |
||||
|
result.message = 'success'; |
||||
|
} else { |
||||
|
result.success = false; |
||||
|
result.message = 'fail'; |
||||
|
} |
||||
|
} |
||||
|
ctx.body = result; |
||||
|
} |
||||
|
} |
@ -0,0 +1,71 @@ |
|||||
|
// // var data = [
|
||||
|
// // {id: 1, address: "安徽", parent_id: 0},
|
||||
|
// // {id: 2, address: "江苏", parent_id: 0},
|
||||
|
// // {id: 3, address: "合肥", parent_id: 1},
|
||||
|
// // {id: 4, address: "庐阳区", parent_id: 3},
|
||||
|
// // {id: 5, address: "大杨镇", parent_id: 4},
|
||||
|
// // {id: 6, address: "南京", parent_id: 2},
|
||||
|
// // {id: 7, address: "玄武区", parent_id: 6},
|
||||
|
// // {id: 8, address: "梅园新村街道", parent_id: 7},
|
||||
|
// // {id: 9, address: "上海", parent_id: 0},
|
||||
|
// // {id: 10, address: "黄浦区", parent_id: 9},
|
||||
|
// // {id: 11, address: "外滩", parent_id: 10},
|
||||
|
// // {id: 12, address: "安庆", parent_id: 1}
|
||||
|
// // ];
|
||||
|
// var data = [ { id: 1, name: 'html', belongto: 0, about: '22' },
|
||||
|
// { id: 2, name: 'css', belongto: 0, about: '2256' },
|
||||
|
// { id: 3, name: 'js', belongto: 1, about: '5422' },
|
||||
|
// { id: 4, name: 'js', belongto: 2, about: '5422' },
|
||||
|
// { id: 5, name: 'js', belongto: 3, about: '5422' },
|
||||
|
// { id: 6, name: 'js', belongto: 1, about: '5422' },
|
||||
|
// { id: 7, name: 'js', belongto: 1, about: '5422' },
|
||||
|
// { id: 8, name: 'js', belongto: 5, about: '5422' },
|
||||
|
// { id: 9, name: 'js', belongto: 8, about: '5422' },
|
||||
|
// { id: 10, name: 'js', belongto: 8, about: '5422' },
|
||||
|
// { id: 11, name: 'js', belongto: 10, about: '5422' },
|
||||
|
// { id: 12, name: 'js', belongto: 11, about: '5422' } ]
|
||||
|
//
|
||||
|
// function findeBelong(data, index) {
|
||||
|
// let array = [];
|
||||
|
// for (let i = data.length-1; i >= 0 ; i--) {
|
||||
|
// if(data[i].belongto == index){
|
||||
|
// const obj = {
|
||||
|
// id: data[i].id,
|
||||
|
// name: data[i].name,
|
||||
|
// desc: data[i].about,
|
||||
|
// children: []
|
||||
|
// }
|
||||
|
// array.push(obj);
|
||||
|
// data.splice(i,1);
|
||||
|
// }
|
||||
|
// }
|
||||
|
// return array;
|
||||
|
// }
|
||||
|
//
|
||||
|
// function sortTree(arr,all){
|
||||
|
// let tree = (arr,all)=>{
|
||||
|
// for (let i = 0; i < arr.length; i++) {
|
||||
|
// let item = findeBelong(all,arr[i].id);
|
||||
|
// for (let j = 0; j < item.length; j++) {
|
||||
|
// const obj = {
|
||||
|
// id: item[j].id,
|
||||
|
// name: item[j].name,
|
||||
|
// desc: item[j].desc,
|
||||
|
// children: []
|
||||
|
// }
|
||||
|
// arr[i].children.push(obj);
|
||||
|
// }
|
||||
|
// tree(arr[i].children,all)
|
||||
|
// }
|
||||
|
// }
|
||||
|
// tree(arr,all)
|
||||
|
// }
|
||||
|
// let fa = findeBelong(data,0);
|
||||
|
// sortTree(fa,data);
|
||||
|
// console.log(fa);
|
||||
|
// console.log(data);
|
||||
|
// /*
|
||||
|
// * 1. 先找出ID==0的菜单
|
||||
|
// * 2. 选中第一个ID的菜单,去菜单表中寻找是否有其子菜单,找到之后构建插入然后删除这个,然后递归查这一个的子菜单
|
||||
|
// *
|
||||
|
// * */
|
@ -0,0 +1,181 @@ |
|||||
|
const userCode = require('../../codes/user.js') |
||||
|
const userInfoService = require('../../services/user-info') |
||||
|
|
||||
|
module.exports = { |
||||
|
/** |
||||
|
* 修改个人信息,由于用户名和邮箱比较重要,暂不提供修改 |
||||
|
* @param {*} ctx |
||||
|
* @param {*} next |
||||
|
*/ |
||||
|
async modifyUserinfo(ctx, next) { |
||||
|
let user = ctx.state.user; |
||||
|
let formData = ctx.request.body; |
||||
|
let result = { |
||||
|
message: 'fail', |
||||
|
data: null, |
||||
|
success: false |
||||
|
}; |
||||
|
// 根据ID查询
|
||||
|
let userResult = await userInfoService.getExistOneByIdOrUserName(user); |
||||
|
if (userResult) { |
||||
|
// 用户信息验证,不校验密码
|
||||
|
let validateResult = await userInfoService.validatorNeed(formData, false) |
||||
|
if (!validateResult.success) { |
||||
|
result.success = false; |
||||
|
result.message = validateResult.message; |
||||
|
ctx.body = result |
||||
|
return |
||||
|
} |
||||
|
let r = await userInfoService.update(formData, user.id); |
||||
|
if (r) { |
||||
|
result.success = true; |
||||
|
result.message = 'success'; |
||||
|
} else { |
||||
|
result.success = false; |
||||
|
result.message = 'fail'; |
||||
|
} |
||||
|
} else { |
||||
|
result.success = false; |
||||
|
result.message = userCode.FAIL_USER_NO_EXIST |
||||
|
} |
||||
|
ctx.body = result |
||||
|
}, |
||||
|
async getUserinfo(ctx, next) { |
||||
|
let formData = ctx.state.user; |
||||
|
let result = { |
||||
|
message: '', |
||||
|
data: null, |
||||
|
code: 400 |
||||
|
}; |
||||
|
let userResult = await userInfoService.getExistOneByIdOrUserName(formData); |
||||
|
if (userResult) { |
||||
|
result.code = 200; |
||||
|
delete userResult.password |
||||
|
result.data = userResult; |
||||
|
} else { |
||||
|
result.message = userCode.FAIL_USER_NO_EXIST |
||||
|
} |
||||
|
ctx.body = result; |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 登录操作,返回 |
||||
|
* @param {*} ctx |
||||
|
* @param {*} next |
||||
|
*/ |
||||
|
async login(ctx, next) { |
||||
|
let formData = ctx.request.body; |
||||
|
let result = { |
||||
|
message: 'fail', |
||||
|
data: null, |
||||
|
success: false |
||||
|
} |
||||
|
let validateResult = await userInfoService.validatorNeed(formData) |
||||
|
if (!validateResult.success) { |
||||
|
result.success = false; |
||||
|
result.message = validateResult.message; |
||||
|
ctx.body = result |
||||
|
return |
||||
|
} |
||||
|
// 是否存在一个相同用户
|
||||
|
let existOne = await userInfoService.getExistOne(formData); |
||||
|
if (Array.isArray(existOne)) { |
||||
|
if (existOne.length > 1) { |
||||
|
result.success = false; |
||||
|
result.message = userCode.ERROR_MORE_USER; |
||||
|
ctx.body = result; |
||||
|
return; |
||||
|
} |
||||
|
existOne = existOne[0]; |
||||
|
// 密码验证,获取token
|
||||
|
let token = await userInfoService.validatorPwd(formData, existOne) |
||||
|
if (!token) { |
||||
|
result.success = false; |
||||
|
result = userCode.FAIL_USER_NAME_OR_PASSWORD_ERROR; |
||||
|
ctx.body = result; |
||||
|
return; |
||||
|
} else { |
||||
|
result.success = true; |
||||
|
result.message = 'success'; |
||||
|
result.data = token; |
||||
|
} |
||||
|
} else { |
||||
|
result.success = false; |
||||
|
result.message = userCode.FAIL_USER_NO_EXIST; |
||||
|
ctx.body = result; |
||||
|
return; |
||||
|
} |
||||
|
ctx.body = result; |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 注册操作 |
||||
|
* @param {*} ctx 上下文 |
||||
|
* { |
||||
|
* imgurl, |
||||
|
* email, |
||||
|
* password, 必须 |
||||
|
* confirmPassword,必须 |
||||
|
* username, 必须 |
||||
|
* nickname, |
||||
|
* createTime, |
||||
|
* modifiedTime, |
||||
|
* level |
||||
|
* } |
||||
|
*/ |
||||
|
async register(ctx, next) { |
||||
|
let formData = ctx.request.body; |
||||
|
let result = { |
||||
|
success: false, |
||||
|
message: 'fail', |
||||
|
data: null |
||||
|
} |
||||
|
// 用户注册信息验证
|
||||
|
let validateResult = await userInfoService.validatorSignUp(formData) |
||||
|
if (!validateResult.success) { |
||||
|
result.success = false; |
||||
|
result.message = validateResult.message; |
||||
|
ctx.body = result; |
||||
|
return |
||||
|
} |
||||
|
// 是否存在一个相同用户
|
||||
|
let existOne = await userInfoService.getExistOne(formData); |
||||
|
if (Array.isArray(existOne)) { |
||||
|
if (existOne.length > 1) { |
||||
|
result.success = false; |
||||
|
result.message = userCode.ERROR_MORE_USER; |
||||
|
ctx.body = result; |
||||
|
return; |
||||
|
} |
||||
|
existOne = existOne[0]; |
||||
|
// 判断是否存在相同用户名或者邮箱
|
||||
|
if (existOne.username === formData.username) { |
||||
|
result.message = userCode.FAIL_USER_NAME_IS_EXIST |
||||
|
ctx.body = result |
||||
|
return |
||||
|
} |
||||
|
if (existOne.email === formData.email) { |
||||
|
result.message = userCode.FAIL_EMAIL_IS_EXIST |
||||
|
ctx.body = result |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
// 创建用户
|
||||
|
let userResult = await userInfoService.create({ |
||||
|
imgurl: formData.imgurl, |
||||
|
email: formData.email, |
||||
|
password: formData.password, |
||||
|
username: formData.username, |
||||
|
nickname: formData.nickname, |
||||
|
createTime: new Date().getTime(), |
||||
|
level: 1, |
||||
|
}) |
||||
|
if (userResult && userResult.insertId * 1 > 0) { |
||||
|
result.success = true; |
||||
|
result.message = 'success' |
||||
|
} else { |
||||
|
result.message = userCode.ERROR_SYS |
||||
|
} |
||||
|
ctx.body = result; |
||||
|
} |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
const menus = require('../menus/index.js') |
||||
|
|
||||
|
module.exports = { |
||||
|
async home(ctx, next) { |
||||
|
await menus.getAll(ctx, next); |
||||
|
await ctx.render('home', { |
||||
|
data: JSON.stringify(ctx.body.data) |
||||
|
}) |
||||
|
} |
||||
|
}; |
@ -0,0 +1,8 @@ |
|||||
|
/** |
||||
|
* |
||||
|
* 只注册全局变量 |
||||
|
* |
||||
|
*/ |
||||
|
const getOneRes = require('./res.util.js'); |
||||
|
global.log = require('debug')('demo:server'); |
||||
|
global.oneRes = getOneRes.message; |
@ -0,0 +1,45 @@ |
|||||
|
const SuccessTemplate = { |
||||
|
code: 200, |
||||
|
data: null, |
||||
|
message: 'success' |
||||
|
} |
||||
|
|
||||
|
const failTemplate = { |
||||
|
code: 400, |
||||
|
data: null, |
||||
|
message: 'fail' |
||||
|
} |
||||
|
const template = { |
||||
|
code: 200, |
||||
|
data: null, |
||||
|
message: 'ok' |
||||
|
} |
||||
|
module.exports = { |
||||
|
success(code, message, data) { |
||||
|
let res = { |
||||
|
...SuccessTemplate |
||||
|
}; |
||||
|
code && (res.code = code); |
||||
|
message && (res.message = message); |
||||
|
data && (res.data = data); |
||||
|
return res; |
||||
|
}, |
||||
|
fail(code, message, data) { |
||||
|
let res = { |
||||
|
...failTemplate |
||||
|
}; |
||||
|
code && (res.code = code); |
||||
|
message && (res.message = message); |
||||
|
data && (res.data = data); |
||||
|
return res; |
||||
|
}, |
||||
|
message(code, message, data) { |
||||
|
let res = { |
||||
|
...template |
||||
|
}; |
||||
|
code && (res.code = code); |
||||
|
message && (res.message = message); |
||||
|
data && (res.data = data); |
||||
|
return res; |
||||
|
} |
||||
|
} |
@ -0,0 +1,43 @@ |
|||||
|
const fs = require('fs'); |
||||
|
const getSqlContentMap = require('./util/get-sql-content-map'); |
||||
|
const { |
||||
|
query |
||||
|
} = require('./util/db'); |
||||
|
|
||||
|
|
||||
|
// 打印脚本执行日志
|
||||
|
const eventLog = function (err, sqlFile, index) { |
||||
|
if (err) { |
||||
|
console.log(`[ERROR] sql脚本文件: ${sqlFile} 第${index + 1}条脚本 执行失败 o(╯□╰)o !`) |
||||
|
} else { |
||||
|
console.log(`[SUCCESS] sql脚本文件: ${sqlFile} 第${index + 1}条脚本 执行成功 O(∩_∩)O !`) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 获取所有sql脚本内容
|
||||
|
let sqlContentMap = getSqlContentMap() |
||||
|
|
||||
|
// 执行建表sql脚本
|
||||
|
const createAllTables = async () => { |
||||
|
for (let key in sqlContentMap) { |
||||
|
let sqlShell = sqlContentMap[key] |
||||
|
let sqlShellList = sqlShell.split(';') |
||||
|
|
||||
|
for (let [i, shell] of sqlShellList.entries()) { |
||||
|
if (shell.trim()) { |
||||
|
let result = await query(shell) |
||||
|
if (result.serverStatus * 1 === 2) { |
||||
|
eventLog(null, key, i) |
||||
|
} else { |
||||
|
eventLog(true, key, i) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
console.log('sql脚本执行结束!') |
||||
|
console.log('请按 ctrl + c 键退出!') |
||||
|
|
||||
|
} |
||||
|
|
||||
|
createAllTables() |
@ -0,0 +1,11 @@ |
|||||
|
|
||||
|
-- CREATE TABLE IF NOT EXISTS `open` ( |
||||
|
-- `id` int(11) NOT NULL AUTO_INCREMENT, |
||||
|
-- `card` varchar(255) NOT NULL, |
||||
|
-- `host` varchar(255) NOT NULL, |
||||
|
-- PRIMARY KEY (`id`) |
||||
|
-- ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
||||
|
|
||||
|
-- INSERT INTO `open` set card='[0,0,0,1,1]', host='1'; |
||||
|
|
||||
|
-- INSERT INTO `open` set card='[0,0,0,1,2]', host='2'; |
@ -0,0 +1,13 @@ |
|||||
|
|
||||
|
CREATE TABLE IF NOT EXISTS `category` ( |
||||
|
`id` bigint(20) NOT NULL AUTO_INCREMENT, |
||||
|
`name` varchar(255) DEFAULT NULL, |
||||
|
`belongto` varchar(255) DEFAULT NULL, |
||||
|
`about` varchar(255) DEFAULT NULL, |
||||
|
PRIMARY KEY (`id`) USING BTREE |
||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
||||
|
|
||||
|
|
||||
|
INSERT INTO `category` set id='1', name='html', belongto='0', about='22'; |
||||
|
INSERT INTO `category` set id='2', name='css', belongto='0', about='2256'; |
||||
|
INSERT INTO `category` set id='3', name='js', belongto='1', about='5422'; |
@ -0,0 +1,14 @@ |
|||||
|
-- level: 0:管理员 |
||||
|
-- level: 1:普通用户 |
||||
|
CREATE TABLE IF NOT EXISTS `user_info` ( |
||||
|
`id` int(11) NOT NULL AUTO_INCREMENT, |
||||
|
`imgurl` varchar(255) DEFAULT NULL, |
||||
|
`email` varchar(255) DEFAULT NULL, |
||||
|
`password` varchar(255) DEFAULT NULL, |
||||
|
`username` varchar(255) DEFAULT NULL, |
||||
|
`nickname` varchar(255) DEFAULT NULL, |
||||
|
`createTime` varchar(20) DEFAULT NULL, |
||||
|
`modifiedTime` varchar(20) DEFAULT NULL, |
||||
|
`level` int(11) DEFAULT '1', |
||||
|
PRIMARY KEY (`id`) |
||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
@ -0,0 +1,30 @@ |
|||||
|
const mysql = require('mysql') |
||||
|
var config = require('../../config.js') |
||||
|
const pool = mysql.createPool({ |
||||
|
...config.db |
||||
|
}) |
||||
|
|
||||
|
let query = function (sql, values) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
pool.getConnection(function (err, connection) { |
||||
|
if (err) { |
||||
|
reject(err) |
||||
|
} else { |
||||
|
connection.query(sql, values, (err, rows) => { |
||||
|
|
||||
|
if (err) { |
||||
|
reject(err) |
||||
|
} else { |
||||
|
resolve(rows) |
||||
|
} |
||||
|
connection.release() |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
}) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
module.exports = { |
||||
|
query |
||||
|
} |
@ -0,0 +1,30 @@ |
|||||
|
const fs = require('fs') |
||||
|
const getSqlMap = require('./get-sql-map') |
||||
|
|
||||
|
let sqlContentMap = {} |
||||
|
|
||||
|
/** |
||||
|
* 读取sql文件内容 |
||||
|
* @param {string} fileName 文件名称 |
||||
|
* @param {string} path 文件所在的路径 |
||||
|
* @return {string} 脚本文件内容 |
||||
|
*/ |
||||
|
function getSqlContent( fileName, path ) { |
||||
|
let content = fs.readFileSync( path, 'binary' ) |
||||
|
sqlContentMap[ fileName ] = content |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 封装所有sql文件脚本内容 |
||||
|
* @return {object} |
||||
|
*/ |
||||
|
function getSqlContentMap () { |
||||
|
let sqlMap = getSqlMap() |
||||
|
for( let key in sqlMap ) { |
||||
|
getSqlContent( key, sqlMap[key] ) |
||||
|
} |
||||
|
|
||||
|
return sqlContentMap |
||||
|
} |
||||
|
|
||||
|
module.exports = getSqlContentMap |
@ -0,0 +1,20 @@ |
|||||
|
const fs = require('fs') |
||||
|
const walkFile = require('./walk-file') |
||||
|
|
||||
|
/** |
||||
|
* 获取sql目录下的文件目录数据 |
||||
|
* @return {object} |
||||
|
*/ |
||||
|
function getSqlMap() { |
||||
|
let basePath = __dirname |
||||
|
basePath = basePath.replace(/\\/g, '\/') |
||||
|
|
||||
|
let pathArr = basePath.split('\/') |
||||
|
pathArr = pathArr.splice(0, pathArr.length - 1) |
||||
|
basePath = pathArr.join('/') + '/sql/' |
||||
|
|
||||
|
let fileList = walkFile(basePath, 'sql') |
||||
|
return fileList |
||||
|
} |
||||
|
|
||||
|
module.exports = getSqlMap |
@ -0,0 +1,28 @@ |
|||||
|
const fs = require('fs') |
||||
|
|
||||
|
/** |
||||
|
* 遍历目录下的文件目录 |
||||
|
* @param {string} pathResolve 需进行遍历的目录路径 |
||||
|
* @param {string} mime 遍历文件的后缀名 |
||||
|
* @return {object} 返回遍历后的目录结果 |
||||
|
*/ |
||||
|
const walkFile = function( pathResolve , mime ){ |
||||
|
|
||||
|
let files = fs.readdirSync( pathResolve ) |
||||
|
|
||||
|
let fileList = {} |
||||
|
|
||||
|
for( let [ i, item] of files.entries() ) { |
||||
|
let itemArr = item.split('\.') |
||||
|
|
||||
|
let itemMime = ( itemArr.length > 1 ) ? itemArr[ itemArr.length - 1 ] : 'undefined' |
||||
|
let keyName = item + '' |
||||
|
if( mime === itemMime ) { |
||||
|
fileList[ item ] = pathResolve + item |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return fileList |
||||
|
} |
||||
|
|
||||
|
module.exports = walkFile |
@ -0,0 +1,98 @@ |
|||||
|
const dbUtils = require('../utils/db-util') |
||||
|
|
||||
|
const menus = { |
||||
|
async ceateMenu(model) { |
||||
|
let result = await dbUtils.insertData('category', model); |
||||
|
return result; |
||||
|
}, |
||||
|
// async deleteMenu(id) {
|
||||
|
// let result = await dbUtils.deleteDataById('category', id);
|
||||
|
// if (result.serverStatus == 2) {
|
||||
|
// result = true
|
||||
|
// } else {
|
||||
|
// result = false
|
||||
|
// }
|
||||
|
// },
|
||||
|
deleteMenu(id,subList,fix) { |
||||
|
let sql = []; |
||||
|
sql.push('DELETE FROM category WHERE id = '+id); |
||||
|
if(subList){ |
||||
|
for (let i = 0; i < subList.length; i++) { |
||||
|
sql.push("UPDATE category SET belongto='"+fix+"' WHERE id = "+subList[i].id); |
||||
|
} |
||||
|
} |
||||
|
console.log(sql) |
||||
|
return new Promise((resolve,reject)=>{ |
||||
|
dbUtils.execTrans(sql,(err)=>{ |
||||
|
if (err){ |
||||
|
resolve(false); |
||||
|
} else { |
||||
|
resolve(true) |
||||
|
} |
||||
|
}) |
||||
|
}) |
||||
|
}, |
||||
|
/** |
||||
|
* 更新菜单信息 |
||||
|
* @param {object} model 数据模型 |
||||
|
* @return {object} mysql执行结果 |
||||
|
*/ |
||||
|
async update(model, id) { |
||||
|
let result = await dbUtils.updateData('category', model, id) |
||||
|
if (result.serverStatus == 2) { |
||||
|
result = true |
||||
|
} else { |
||||
|
result = false |
||||
|
} |
||||
|
return result |
||||
|
}, |
||||
|
/** |
||||
|
* 获取所有菜单 |
||||
|
*/ |
||||
|
async getAllMenus() { |
||||
|
let _sql = `SELECT * from category;`; |
||||
|
let result = await dbUtils.query(_sql); |
||||
|
if (Array.isArray(result)) { |
||||
|
result = result |
||||
|
} else { |
||||
|
result = null; |
||||
|
} |
||||
|
return result |
||||
|
}, |
||||
|
|
||||
|
async getMenusByID(id) { |
||||
|
let _sql = ` |
||||
|
SELECT * from category |
||||
|
where id="${id}";`;
|
||||
|
let result = await dbUtils.query(_sql); |
||||
|
if (Array.isArray(result) && result.length > 0) { |
||||
|
result = result |
||||
|
} else { |
||||
|
result = null; |
||||
|
} |
||||
|
return result |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 获取子菜单 |
||||
|
* 0: 主菜单 |
||||
|
* 1: 属于ID:1的子菜单 |
||||
|
* 2: 属于ID:2的子菜单 |
||||
|
*/ |
||||
|
|
||||
|
async getMenusByBelongTo(belongto) { |
||||
|
let _sql = ` |
||||
|
SELECT * from category |
||||
|
where belongto="${belongto}";`;
|
||||
|
let result = await dbUtils.query(_sql); |
||||
|
if (Array.isArray(result) && result.length > 0) { |
||||
|
result = result |
||||
|
} else { |
||||
|
result = null; |
||||
|
} |
||||
|
return result |
||||
|
}, |
||||
|
|
||||
|
} |
||||
|
|
||||
|
module.exports = menus |
@ -0,0 +1,110 @@ |
|||||
|
const dbUtils = require('./../utils/db-util') |
||||
|
|
||||
|
const user = { |
||||
|
|
||||
|
/** |
||||
|
* 数据库创建用户 |
||||
|
* @param {object} model 用户数据模型 |
||||
|
* @return {object} mysql执行结果 |
||||
|
*/ |
||||
|
async create(model) { |
||||
|
let result = await dbUtils.insertData('user_info', model) |
||||
|
return result |
||||
|
}, |
||||
|
/** |
||||
|
* 更新用户信息 |
||||
|
* @param {object} model 用户数据模型 |
||||
|
* @return {object} mysql执行结果 |
||||
|
*/ |
||||
|
async update(model, id) { |
||||
|
let result = await dbUtils.updateData('user_info', model, id) |
||||
|
if (result.serverStatus == 2) { |
||||
|
result = true |
||||
|
} else { |
||||
|
result = false |
||||
|
} |
||||
|
return result |
||||
|
}, |
||||
|
/** |
||||
|
* 查找一个存在用户的数据 |
||||
|
* @param {obejct} options 查找条件参数 |
||||
|
* @return {object|null} 查找结果 |
||||
|
*/ |
||||
|
async getExistOne(options) { |
||||
|
let _sql = ` |
||||
|
SELECT * from user_info |
||||
|
where email="${options.email}" or username="${options.username}";` |
||||
|
let result = await dbUtils.query(_sql) |
||||
|
if (Array.isArray(result) && result.length > 0) { |
||||
|
result = result |
||||
|
} else { |
||||
|
result = null; |
||||
|
} |
||||
|
return result |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 根据ID或者用户名查找一个存在用户的数据 |
||||
|
* @param {obejct} options 查找条件参数 |
||||
|
* @return {object|null} 查找结果 |
||||
|
*/ |
||||
|
async getExistOneByIdOrUserName(options) { |
||||
|
let _sql = ''; |
||||
|
if (options.username) { |
||||
|
_sql = ` |
||||
|
SELECT * from user_info |
||||
|
where username="${options.username}";` |
||||
|
} |
||||
|
if (options.id) { |
||||
|
_sql = ` |
||||
|
SELECT * from user_info |
||||
|
where id="${options.id}";` |
||||
|
} |
||||
|
let result = await dbUtils.query(_sql) |
||||
|
if (Array.isArray(result) && result.length > 0) { |
||||
|
result = result |
||||
|
} else { |
||||
|
result = null; |
||||
|
} |
||||
|
return result |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 根据用户名和密码查找用户 |
||||
|
* @param {object} options 用户名密码对象 |
||||
|
* @return {object|null} 查找结果 |
||||
|
*/ |
||||
|
async getOneByUserName(options) { |
||||
|
let _sql = ` |
||||
|
SELECT * from user_info |
||||
|
where username="${options.username}";` |
||||
|
let result = await dbUtils.query(_sql) |
||||
|
if (Array.isArray(result) && result.length > 0) { |
||||
|
result = result |
||||
|
} else { |
||||
|
result = null; |
||||
|
} |
||||
|
return result |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* 根据用户名查找用户信息 |
||||
|
* @param {string} userName 用户账号名称 |
||||
|
* @return {object|null} 查找结果 |
||||
|
*/ |
||||
|
async getUserInfoByUserName(userName) { |
||||
|
let _sql = ` |
||||
|
SELECT * from user_info |
||||
|
where username="${userName}";`;
|
||||
|
let result = await dbUtils.query(_sql); |
||||
|
if (Array.isArray(result) && result.length > 0) { |
||||
|
result = result |
||||
|
} else { |
||||
|
result = null; |
||||
|
} |
||||
|
return result |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
|
||||
|
module.exports = user |
File diff suppressed because it is too large
@ -0,0 +1,38 @@ |
|||||
|
{ |
||||
|
"name": "noderest", |
||||
|
"version": "1.0.0", |
||||
|
"description": "", |
||||
|
"main": "./src/main.js", |
||||
|
"private": true, |
||||
|
"scripts": { |
||||
|
"dev": "set DEBUG=demo:server,demo:ssc,demo:sql & cross-env PORT=3303 nodemon ./bin/www", |
||||
|
"db": "node ./init/index.js", |
||||
|
"test": "mocha" |
||||
|
}, |
||||
|
"keywords": [], |
||||
|
"author": "Dash Crash", |
||||
|
"license": "ISC", |
||||
|
"dependencies": { |
||||
|
"@koa/cors": "^2.2.3", |
||||
|
"async": "^3.1.0", |
||||
|
"bcryptjs": "^2.4.3", |
||||
|
"debug": "^4.1.1", |
||||
|
"jsonwebtoken": "^8.5.1", |
||||
|
"koa": "^2.11.0", |
||||
|
"koa-body": "^4.1.1", |
||||
|
"koa-jwt": "^3.6.0", |
||||
|
"koa-router": "^7.4.0", |
||||
|
"koa-static": "^5.0.0", |
||||
|
"lodash": "^4.17.15", |
||||
|
"mocha": "^6.2.2", |
||||
|
"module-alias": "^2.2.2", |
||||
|
"mysql": "^2.17.1", |
||||
|
"nodemon": "^1.19.4", |
||||
|
"pug": "^2.0.4", |
||||
|
"validator": "^12.0.0" |
||||
|
}, |
||||
|
"devDependencies": { |
||||
|
"cross-env": "^6.0.3", |
||||
|
"koa-views": "^6.2.1" |
||||
|
} |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
extends template/layout.pug |
||||
|
|
||||
|
|
||||
|
block content |
||||
|
include ui/login.pug |
||||
|
|
||||
|
append script |
||||
|
//script init({nb: decode("#{data}")}) |
||||
|
script(src='/static/js/home.js'); |
@ -0,0 +1,3 @@ |
|||||
|
body { |
||||
|
background-color: #F5F5D5; |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
|
||||
|
/**************************************/ |
||||
|
.login-panel .mask{ |
||||
|
position: fixed; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
background-color: rgba(0, 0, 0, 0.2); |
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
const homeVue = init({nb: decode("#{data}")}) |
@ -0,0 +1,17 @@ |
|||||
|
const init = (data = {}) => { |
||||
|
return new Vue.extend({ |
||||
|
data() { |
||||
|
return data |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const decode = (text) => { |
||||
|
var temp = document.createElement("div"); |
||||
|
//2.然后将要转换的字符串设置为这个元素的innerHTML(ie,火狐,google都支持)
|
||||
|
temp.innerHTML = text; |
||||
|
//3.最后返回这个元素的innerText(ie支持)或者textContent(火狐,google支持),即得到经过HTML解码的字符串了。
|
||||
|
var output = temp.innerText || temp.textContent; |
||||
|
temp = null; |
||||
|
return output |
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
footer |
@ -0,0 +1 @@ |
|||||
|
header |
@ -0,0 +1,19 @@ |
|||||
|
//- https://pug.bootcss.com/language/inheritance.html |
||||
|
|
||||
|
html |
||||
|
head |
||||
|
title 我的站点 |
||||
|
block css |
||||
|
link(href='/static/css/index.css' rel='stylesheet') |
||||
|
link(href='/static/css/style.css' rel='stylesheet') |
||||
|
body |
||||
|
#app |
||||
|
block header |
||||
|
include header.pug |
||||
|
block content |
||||
|
block foot |
||||
|
include footer.pug |
||||
|
block script |
||||
|
script(src='https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js') |
||||
|
script(src='https://cdn.jsdelivr.net/npm/vue/dist/vue.js') |
||||
|
script(src='/static/js/index.js') |
@ -0,0 +1,3 @@ |
|||||
|
.login-panel |
||||
|
.mask |
||||
|
div {{nb}} |
@ -0,0 +1,13 @@ |
|||||
|
## 约定 |
||||
|
``` |
||||
|
//各个模块之间的消息传递 |
||||
|
//200表示正确的返回 |
||||
|
//其他表示处理中存在错误 |
||||
|
{ |
||||
|
code: 200, |
||||
|
data: null, |
||||
|
message: 'ok' |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
todo:将数据库操作全部改为占位符形式防止sql注入 |
@ -0,0 +1,14 @@ |
|||||
|
var Router = require('koa-router'); |
||||
|
const controler = require('../../controler/index.js') |
||||
|
|
||||
|
var router = new Router(); |
||||
|
|
||||
|
router.post('/menus/getall', controler.menus.getAll); |
||||
|
router.post('/menus/create', controler.menus.createOne); |
||||
|
router.post('/menus/update', controler.menus.updateOne); |
||||
|
router.post('/menus/delete', controler.menus.deleteOne); |
||||
|
|
||||
|
module.exports = { |
||||
|
name: __dirname.split('\\')[__dirname.split('\\').length - 1], |
||||
|
router |
||||
|
}; |
@ -0,0 +1,14 @@ |
|||||
|
var Router = require('koa-router'); |
||||
|
const controler = require('../../controler/index.js') |
||||
|
|
||||
|
var router = new Router(); |
||||
|
router.post('/login', controler.user.login); |
||||
|
router.post('/register', controler.user.register); |
||||
|
|
||||
|
router.get('/userinfo', controler.user.getUserinfo); |
||||
|
router.post('/modifyuserinfo', controler.user.modifyUserinfo); |
||||
|
|
||||
|
module.exports = { |
||||
|
name: __dirname.split('\\')[__dirname.split('\\').length - 1], |
||||
|
router |
||||
|
}; |
@ -0,0 +1,34 @@ |
|||||
|
const path = require('path'); |
||||
|
const Bean = require('../utils/index.js'); |
||||
|
|
||||
|
const router = require('koa-router')(); |
||||
|
|
||||
|
// 路由收集规则
|
||||
|
const api_routes = Bean.readFileDeep(path.resolve(__dirname, 'api')).file; |
||||
|
const api_root = '/api'; |
||||
|
api_routes.forEach(route => { |
||||
|
if (route != path.resolve(__filename)) { |
||||
|
const obj = require(route); |
||||
|
const child_router = obj.router; |
||||
|
// 可以根据路由筛选动态设置路由前缀
|
||||
|
// const name = obj.name;
|
||||
|
// router.prefix('/api');
|
||||
|
// app.use(router.routes()).use(router.allowedMethods());
|
||||
|
router.use(api_root, child_router.routes(), child_router.allowedMethods()) |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
const views_routes = Bean.readFileDeep(path.resolve(__dirname, 'views')).file; |
||||
|
const views_root = '/'; |
||||
|
views_routes.forEach(route => { |
||||
|
if (route != path.resolve(__filename)) { |
||||
|
const obj = require(route); |
||||
|
const child_router = obj.router; |
||||
|
// 可以根据路由筛选动态设置路由前缀
|
||||
|
// const name = obj.name;
|
||||
|
// router.prefix('/api');
|
||||
|
// app.use(router.routes()).use(router.allowedMethods());
|
||||
|
router.use(views_root, child_router.routes(), child_router.allowedMethods()) |
||||
|
} |
||||
|
}); |
||||
|
module.exports = router |
@ -0,0 +1,12 @@ |
|||||
|
var Router = require('koa-router'); |
||||
|
const controler = require('../../controler/index.js') |
||||
|
|
||||
|
var router = new Router(); |
||||
|
|
||||
|
router.get('/', controler.views.home); |
||||
|
|
||||
|
|
||||
|
module.exports = { |
||||
|
name: __dirname.split('\\')[__dirname.split('\\').length - 1], |
||||
|
router |
||||
|
}; |
@ -0,0 +1,84 @@ |
|||||
|
const menus = require('./../models/menus'); |
||||
|
|
||||
|
//菜单的增删改查
|
||||
|
const menuServices = { |
||||
|
// 获取所有菜单
|
||||
|
async getAllMenus() { |
||||
|
let result = await menus.getAllMenus(); |
||||
|
return result |
||||
|
}, |
||||
|
|
||||
|
async createMenu(model) { |
||||
|
let result = await menus.ceateMenu(model); |
||||
|
return result |
||||
|
}, |
||||
|
|
||||
|
async judgeID(id) { |
||||
|
let result = await menus.getMenusByID(id); |
||||
|
if (result){ |
||||
|
result = result[0]; |
||||
|
let belong = await menus.getMenusByBelongTo(result.id); |
||||
|
if (belong){ |
||||
|
if (belong.length>0){ |
||||
|
return belong; |
||||
|
} else { |
||||
|
return null; |
||||
|
} |
||||
|
}else { |
||||
|
return null; |
||||
|
} |
||||
|
}else { |
||||
|
return null; |
||||
|
} |
||||
|
}, |
||||
|
async deleteMenu(model,list,fix) { |
||||
|
let id = model.id; |
||||
|
let result = await menus.deleteMenu(id,list,fix); |
||||
|
return result |
||||
|
}, |
||||
|
async updateMenu(model) { |
||||
|
let data = { |
||||
|
...model, |
||||
|
// modifiedTime: new Date().getTime()
|
||||
|
} |
||||
|
let id = data.id; |
||||
|
delete data.id; |
||||
|
let result = await menus.update(data,id); |
||||
|
return result |
||||
|
}, |
||||
|
/** |
||||
|
* 验证所需要的参数 |
||||
|
* @param model |
||||
|
* @returns {Promise<void>} |
||||
|
*/ |
||||
|
async validatorNeed(model,keys=[]) { |
||||
|
let result = { |
||||
|
success: true, |
||||
|
message: '', |
||||
|
data: null |
||||
|
} |
||||
|
for (let key of keys){ |
||||
|
let notHaveValue = model[key.key]==undefined |
||||
|
if (notHaveValue){ |
||||
|
result.success=false; |
||||
|
result.message=key.error; |
||||
|
break; |
||||
|
} |
||||
|
let notJudge = key.validate&&await key.validate(model[key.key]); |
||||
|
if (typeof notJudge == 'string'){ |
||||
|
result.success=false; |
||||
|
result.message=notJudge; |
||||
|
break; |
||||
|
}else if (typeof notJudge == 'boolean'&¬Judge){ |
||||
|
result.success=false; |
||||
|
result.message=key.error; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
module.exports = menuServices; |
@ -0,0 +1,176 @@ |
|||||
|
const bcrypt = require('bcryptjs'); |
||||
|
const jwt = require('jsonwebtoken'); |
||||
|
const { |
||||
|
promisify |
||||
|
} = require('util'); |
||||
|
/** |
||||
|
* 用户业务操作 |
||||
|
*/ |
||||
|
const config = require('./../config.js'); |
||||
|
const validator = require('validator') |
||||
|
const userModel = require('./../models/user-info') |
||||
|
const userCode = require('./../codes/user') |
||||
|
|
||||
|
const user = { |
||||
|
|
||||
|
/** |
||||
|
* 创建用户 |
||||
|
* @param {object} user 用户信息 |
||||
|
* @return {object} 创建结果 |
||||
|
*/ |
||||
|
async create(user) { |
||||
|
let salt = await promisify(bcrypt.genSalt)(10); |
||||
|
let pwd = await promisify(bcrypt.hash)(user.password, salt); |
||||
|
user.password = pwd; |
||||
|
let result = await userModel.create(user) |
||||
|
return result |
||||
|
}, |
||||
|
/** |
||||
|
* 更新用户 |
||||
|
* @param {object} user 用户信息 |
||||
|
* @return {object} 创建结果 |
||||
|
*/ |
||||
|
async update(user, id) { |
||||
|
let data = { |
||||
|
...user, |
||||
|
modifiedTime: new Date().getTime() |
||||
|
} |
||||
|
// /不能修改用户名
|
||||
|
delete data.username; |
||||
|
// 不能修改邮箱
|
||||
|
delete data.email; |
||||
|
let resultData = await userModel.update(data, id) |
||||
|
return resultData |
||||
|
}, |
||||
|
/** |
||||
|
* 查找存在用户信息 |
||||
|
* @param {object} formData 查找的表单数据 |
||||
|
* @return {object|null} 查找结果 |
||||
|
*/ |
||||
|
async getExistOne(formData) { |
||||
|
let resultData = await userModel.getExistOne({ |
||||
|
'email': formData.email, |
||||
|
'username': formData.username |
||||
|
}) |
||||
|
return resultData |
||||
|
}, |
||||
|
/** |
||||
|
* 根据ID查找存在用户信息 |
||||
|
* @param {object} formData 查找的表单数据 |
||||
|
* @return {object|null} 查找结果 |
||||
|
*/ |
||||
|
async getExistOneByIdOrUserName(formData) { |
||||
|
let resultData = await userModel.getExistOneByIdOrUserName({ |
||||
|
'id': formData.id |
||||
|
}) |
||||
|
if (resultData) { |
||||
|
return resultData[0]; |
||||
|
} |
||||
|
return resultData |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 登录Token获取 |
||||
|
* @param {object} formData 登录表单信息 |
||||
|
* @return {object} 登录业务操作结果 |
||||
|
*/ |
||||
|
async validatorPwd(formData, rowData) { |
||||
|
let token = ''; |
||||
|
let isSame = await promisify(bcrypt.compare)(formData.password, rowData.password); |
||||
|
if (isSame) { |
||||
|
// 1小时的登录时间
|
||||
|
token = jwt.sign({ |
||||
|
id: rowData.id, |
||||
|
username: rowData.username, |
||||
|
}, config.share_key, { |
||||
|
expiresIn: '1h' |
||||
|
}); |
||||
|
token = 'Bearer ' + token; |
||||
|
} |
||||
|
return token |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 根据用户名查找用户业务操作 |
||||
|
* @param {string} userName 用户名 |
||||
|
* @return {object|null} 查找结果 |
||||
|
*/ |
||||
|
async getUserInfoByUserName(userName) { |
||||
|
|
||||
|
let resultData = await userModel.getUserInfoByUserName(userName) || {} |
||||
|
// let userInfo = {
|
||||
|
// // id: resultData.id,
|
||||
|
// email: resultData.email,
|
||||
|
// username: resultData.username,
|
||||
|
// detailInfo: resultData.detail_info,
|
||||
|
// createTime: resultData.create_time
|
||||
|
// }
|
||||
|
return resultData |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 检验用户注册数据 |
||||
|
* @param {object} userInfo 用户注册数据 |
||||
|
* @return {object} 校验结果 |
||||
|
*/ |
||||
|
validatorSignUp(userInfo) { |
||||
|
let result = { |
||||
|
success: false, |
||||
|
message: '', |
||||
|
data: null |
||||
|
} |
||||
|
if (/^[a-z0-9\_\-]{6,16}$/.test(userInfo.username || '') === false) { |
||||
|
result.message = userCode.ERROR_USER_NAME |
||||
|
return result |
||||
|
} |
||||
|
if (userInfo.email && !validator.isEmail(userInfo.email)) { |
||||
|
; |
||||
|
result.message = userCode.ERROR_EMAIL |
||||
|
return result |
||||
|
} |
||||
|
if (!/[\w+]{6,16}/.test(userInfo.password || '')) { |
||||
|
result.message = userCode.ERROR_PASSWORD |
||||
|
return result |
||||
|
} |
||||
|
if (userInfo.password !== userInfo.confirmPassword) { |
||||
|
result.message = userCode.ERROR_PASSWORD_CONFORM |
||||
|
return result |
||||
|
} |
||||
|
|
||||
|
result.success = true |
||||
|
return result |
||||
|
}, |
||||
|
/** |
||||
|
* 检验用户必须的数据 |
||||
|
* @param {object} userInfo 用户数据 |
||||
|
* @return {object} 校验结果 |
||||
|
*/ |
||||
|
validatorNeed(userInfo, needPwd = true) { |
||||
|
let result = { |
||||
|
success: false, |
||||
|
message: '', |
||||
|
} |
||||
|
if (!userInfo.username && !userInfo.email) { |
||||
|
result.success = false; |
||||
|
result.message = '用户名或者邮箱不能为空' |
||||
|
return result |
||||
|
} |
||||
|
if (userInfo.email && !validator.isEmail(userInfo.email)) { |
||||
|
result.success = false; |
||||
|
result.message = userCode.ERROR_EMAIL |
||||
|
return result |
||||
|
} |
||||
|
if (needPwd && !userInfo.password) { |
||||
|
result.success = false; |
||||
|
result.message = '密码不能为空' |
||||
|
return result |
||||
|
} |
||||
|
result.success = true |
||||
|
return result |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
module.exports = user |
@ -0,0 +1,14 @@ |
|||||
|
const assert = require('assert'); |
||||
|
const userdb = require('./../src/models/user-info.js'); |
||||
|
describe('#hello.js', () => { |
||||
|
it('0', async (done) => { |
||||
|
try { |
||||
|
let data = userdb.create({ |
||||
|
username: "sdada" |
||||
|
}); |
||||
|
done(); |
||||
|
} catch (error) { |
||||
|
done(error); |
||||
|
} |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,66 @@ |
|||||
|
const monthEnum = [ |
||||
|
'01', '02', '03', '04', '05', '06', |
||||
|
'07', '08', '09', '10', '11', '12', |
||||
|
] |
||||
|
|
||||
|
const dayEnum = [ |
||||
|
'01', '02', '03', '04', '05', '06', '07', '08', '09', '10', |
||||
|
'11', '12', '13', '14', '15', '16', '17', '18', '19', '20', |
||||
|
'21', '22', '23', '04', '25', '26', '27', '28', '29', '30', '31', |
||||
|
] |
||||
|
|
||||
|
const timeEnum = [ |
||||
|
'00', |
||||
|
'01', '02', '03', '04', '05', '06', '07', '08', '09', '10', |
||||
|
'11', '12', '13', '14', '15', '16', '17', '18', '19', '20', |
||||
|
'21', '22', '23', '04', '25', '26', '27', '28', '29', '30', |
||||
|
'31', '32', '33', '34', '35', '36', '37', '38', '39', '40', |
||||
|
'41', '42', '43', '44', '45', '46', '47', '48', '49', '50', |
||||
|
'51', '52', '53', '54', '55', '56', '57', '58', '59', |
||||
|
] |
||||
|
|
||||
|
const datatime = { |
||||
|
|
||||
|
parseStampToFormat(timestamp, type) { |
||||
|
let _date |
||||
|
if (timestamp) { |
||||
|
_date = new Date(timestamp) |
||||
|
} else { |
||||
|
_date = new Date() |
||||
|
} |
||||
|
|
||||
|
let parsedDate |
||||
|
let parseTime |
||||
|
let parseDatetime |
||||
|
|
||||
|
let yearNum = _date.getFullYear() |
||||
|
let monthNum = monthEnum[_date.getMonth()] |
||||
|
let dayNum = dayEnum[_date.getDate() - 1] |
||||
|
let hourNum = timeEnum[_date.getHours()] |
||||
|
let minNum = timeEnum[_date.getMinutes()] |
||||
|
let secNum = timeEnum[_date.getSeconds()] |
||||
|
|
||||
|
type = type || 'YYYY/MM/DD/hh/mm/ss' |
||||
|
|
||||
|
parseDatetime = type |
||||
|
.replace('YYYY', yearNum) |
||||
|
.replace('MM', monthNum) |
||||
|
.replace('DD', dayNum) |
||||
|
.replace('hh', hourNum) |
||||
|
.replace('mm', minNum) |
||||
|
.replace('ss', secNum) |
||||
|
|
||||
|
return parseDatetime |
||||
|
}, |
||||
|
|
||||
|
getNowDatetime() { |
||||
|
let timestamp = new Date().getTime() |
||||
|
let nowDatetime = this.parseStampToFormat(timestamp) |
||||
|
return nowDatetime |
||||
|
}, |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
module.exports = datatime |
@ -0,0 +1,162 @@ |
|||||
|
var config = require('./../config.js') |
||||
|
const mysql = require("mysql") |
||||
|
const async = require("async"); |
||||
|
|
||||
|
const pool = mysql.createPool({ |
||||
|
...config.db |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
// var pool = mysql.createPool({
|
||||
|
// host: "144.48.4.186",
|
||||
|
// user: "noderest",
|
||||
|
// password: "8WBtsejYGiEESJMh",
|
||||
|
// database: "noderest",
|
||||
|
// connectionLimit: 33,
|
||||
|
// port: "3306",
|
||||
|
// waitForConnections: false
|
||||
|
// });
|
||||
|
//mysql事务处理
|
||||
|
let execTrans =function(sqlparamsEntities, callback) { |
||||
|
//建立连接
|
||||
|
pool.getConnection(function (err, connection) { |
||||
|
if (err) { |
||||
|
//抛出连接错误
|
||||
|
return callback(err, null); |
||||
|
} |
||||
|
connection.beginTransaction(function (err) { |
||||
|
if (err) { |
||||
|
return callback(err, null); |
||||
|
} |
||||
|
console.log("开始执行transaction,共执行" + sqlparamsEntities.length + "条数据"); |
||||
|
var funcAry = []; |
||||
|
sqlparamsEntities.forEach(function (sql_param) { |
||||
|
var temp = function (cb) { |
||||
|
// var sql = sql_param.sql;
|
||||
|
// var param = sql_param.params;
|
||||
|
connection.query(sql_param, function (tErr, rows, fields) { |
||||
|
if (tErr) { |
||||
|
connection.rollback(function () { |
||||
|
console.log("事务失败," + sql_param + ",ERROR:" + tErr); |
||||
|
throw tErr; |
||||
|
}); |
||||
|
} else { |
||||
|
return cb(null, 'ok'); |
||||
|
} |
||||
|
}) |
||||
|
}; |
||||
|
funcAry.push(temp); |
||||
|
}); |
||||
|
|
||||
|
async.series(funcAry, function (err, result) { |
||||
|
console.log("transaction error: " + err); |
||||
|
if (err) { |
||||
|
connection.rollback(function (err) { |
||||
|
console.log("transaction error: " + err); |
||||
|
connection.release(); |
||||
|
return callback(err, null); |
||||
|
}); |
||||
|
} else { |
||||
|
connection.commit(function (err, info) { |
||||
|
console.log("transaction info: " + JSON.stringify(info)); |
||||
|
if (err) { |
||||
|
console.log("执行事务失败," + err); |
||||
|
connection.rollback(function (err) { |
||||
|
console.log("transaction error: " + err); |
||||
|
connection.release(); |
||||
|
return callback(err, null); |
||||
|
}); |
||||
|
} else { |
||||
|
connection.release(); |
||||
|
return callback(null, info); |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
let query = function (sql, values) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
pool.getConnection(function (err, connection) { |
||||
|
if (err) { |
||||
|
resolve(err) |
||||
|
} else { |
||||
|
connection.query(sql, values, (err, rows) => { |
||||
|
|
||||
|
if (err) { |
||||
|
reject(err) |
||||
|
} else { |
||||
|
resolve(rows) |
||||
|
} |
||||
|
connection.release() |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
}) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
let createTable = function (sql) { |
||||
|
return query(sql, []) |
||||
|
} |
||||
|
|
||||
|
let findDataLast = function (table) { |
||||
|
let _sql = "SELECT * FROM ?? ORDER BY id DESC LIMIT 1;" |
||||
|
return query(_sql, [table]) |
||||
|
} |
||||
|
|
||||
|
let findDataById = function (table, id) { |
||||
|
let _sql = "SELECT * FROM ?? WHERE id = ? " |
||||
|
return query(_sql, [table, id, start, end]) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
let findDataByPage = function (table, keys, start, end) { |
||||
|
let _sql = "SELECT ?? FROM ?? LIMIT ? , ?" |
||||
|
return query(_sql, [keys, table, start, end]) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
let insertData = function (table, values) { |
||||
|
let _sql = "INSERT INTO ?? SET ?" |
||||
|
return query(_sql, [table, values]) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
let updateData = function (table, values, id) { |
||||
|
let _sql = "UPDATE ?? SET ? WHERE id = ?" |
||||
|
return query(_sql, [table, values, id]) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
let deleteDataById = function (table, id) { |
||||
|
let _sql = "DELETE FROM ?? WHERE id = ?" |
||||
|
return query(_sql, [table, id]) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
let select = function (table, keys) { |
||||
|
let _sql = "SELECT ?? FROM ?? " |
||||
|
return query(_sql, [keys, table]) |
||||
|
} |
||||
|
|
||||
|
let count = function (table) { |
||||
|
let _sql = "SELECT COUNT(*) AS total_count FROM ?? " |
||||
|
return query(_sql, [table]) |
||||
|
} |
||||
|
|
||||
|
module.exports = { |
||||
|
query, |
||||
|
findDataLast, |
||||
|
createTable, |
||||
|
findDataById, |
||||
|
findDataByPage, |
||||
|
deleteDataById, |
||||
|
insertData, |
||||
|
updateData, |
||||
|
select, |
||||
|
count, |
||||
|
execTrans, |
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
const fs = require('fs'); |
||||
|
const path = require('path'); |
||||
|
|
||||
|
|
||||
|
module.exports = { |
||||
|
readFileDeep(dir) { |
||||
|
const routes = { |
||||
|
dir: [], |
||||
|
file: [] |
||||
|
}; |
||||
|
const routeFunc = (dirname) => { |
||||
|
const files = fs.readdirSync(path.resolve(dirname)); |
||||
|
files.forEach(file => { |
||||
|
if (fs.statSync(path.resolve(dirname, file)).isDirectory()) { |
||||
|
routes.dir.push(path.resolve(dirname, file)); |
||||
|
routeFunc(path.resolve(dirname, file)) |
||||
|
} |
||||
|
if (fs.statSync(path.resolve(dirname, file)).isFile()) { |
||||
|
routes.file.push(path.resolve(dirname, file)); |
||||
|
} |
||||
|
}) |
||||
|
return routes |
||||
|
} |
||||
|
return routeFunc(dir); |
||||
|
} |
||||
|
} |
@ -0,0 +1,37 @@ |
|||||
|
const Types = { |
||||
|
|
||||
|
isPrototype(data) { |
||||
|
return Object.prototype.toString.call(data).toLowerCase() |
||||
|
}, |
||||
|
|
||||
|
isArray(data) { |
||||
|
return this.isPrototype(data) === '[object array]' |
||||
|
}, |
||||
|
|
||||
|
isJSON(data) { |
||||
|
return this.isPrototype(data) === '[object object]' |
||||
|
}, |
||||
|
|
||||
|
isFunction(data) { |
||||
|
return this.isPrototype(data) === '[object function]' |
||||
|
}, |
||||
|
|
||||
|
isString(data) { |
||||
|
return this.isPrototype(data) === '[object string]' |
||||
|
}, |
||||
|
|
||||
|
isNumber(data) { |
||||
|
return this.isPrototype(data) === '[object number]' |
||||
|
}, |
||||
|
|
||||
|
isUndefined(data) { |
||||
|
return this.isPrototype(data) === '[object undefined]' |
||||
|
}, |
||||
|
|
||||
|
isNull(data) { |
||||
|
return this.isPrototype(data) === '[object null]' |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
module.exports = Types |
Loading…
Reference in new issue