├── .gitignore ├── views ├── error.html └── index.html ├── public └── stylesheets │ └── style.css ├── routes ├── users.js └── index.js ├── config.js ├── utils ├── jsonHelper.js ├── logHelper.js ├── sequelize.js ├── redis.js ├── mailHelper.js └── common.js ├── README.md ├── config-pro.js ├── config-dev.js ├── package.json ├── app.js └── bin └── www /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | node_modules 3 | .idea 4 | -------------------------------------------------------------------------------- /views/error.html: -------------------------------------------------------------------------------- 1 |
<%= error.stack %>4 | -------------------------------------------------------------------------------- /public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px; 3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; 4 | } 5 | 6 | a { 7 | color: #00B7FF; 8 | } 9 | -------------------------------------------------------------------------------- /routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET home page. */ 5 | router.get('/', function(req, res, next) { 6 | res.render('index', { title: 'web-framework' }); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
Welcome to <%= title %>
10 | 11 | 12 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | /** 2 | *Author: TaiGuangYin 3 | *Date: 2018 4 | *Description: 5 | */ 6 | var env = process.env.NODE_ENV || 'production'; 7 | env = env.toLowerCase(); 8 | 9 | if(env == 'production'){ 10 | console.log('当前环境为生产环境'); 11 | module.exports = require('./config-pro'); 12 | }else{ 13 | console.log('当前环境为开发环境'); 14 | module.exports = require('./config-dev'); 15 | } 16 | -------------------------------------------------------------------------------- /utils/jsonHelper.js: -------------------------------------------------------------------------------- 1 | /** 2 | *Author: TaiGuangYin 3 | *Date: 2018 4 | *Description: return json helper 5 | */ 6 | 7 | function returnJson(code,msg,data) { 8 | return {code:code,msg:msg,data:data}; 9 | } 10 | 11 | function returnUnloginJson() { 12 | return {code:505,msg:'please login first'}; 13 | } 14 | 15 | exports.returnJson = returnJson; 16 | exports.returnUnloginJson = returnUnloginJson; 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # express-web-framework 2 | 基于express的web框架,整合sequelize、redis、mail等工具集合 3 | 4 | # 功能 5 | * 1. 开发环境和生成环境分开配置 6 | * 2. 添加了sequelize数据库操作类 7 | * 3. 添加了Redis 操作类 8 | * 4. 添加了邮件操作类 9 | * 5. 添加了日志操作类 10 | * 6. 添加了常见函数集合 例如 时间格式化、获取客户端IP地址、根据IP定位、检测邮件以及手机号等函数 11 | 12 | 13 | # 安装和运行 14 | * 1. git clone https://github.com/gytai/express-web-framework.git 15 | * 2. npm install 16 | * 3. node bin/www 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /config-pro.js: -------------------------------------------------------------------------------- 1 | /** 2 | *Author: TaiGuangYin 3 | *Date: 2018 4 | *Description: 正式环境配置文件 5 | */ 6 | const REDIS = { 7 | host: "127.0.0.1", 8 | port: "6379", 9 | ttl: 60 * 60 * 12 10 | }; 11 | 12 | const MYSQLDB = { 13 | database:"webFramework", 14 | username:"root", 15 | password:"root", 16 | host:"localhost", 17 | //支持的数据库类型'mysql'|'sqlite'|'postgres'|'mssql' 18 | dialect:"mysql" 19 | }; 20 | 21 | exports.REDIS = REDIS; 22 | exports.MYSQLDB = MYSQLDB; 23 | -------------------------------------------------------------------------------- /config-dev.js: -------------------------------------------------------------------------------- 1 | /** 2 | *Author: TaiGuangYin 3 | *Date: 2018 4 | *Description: 测试环境开发配置类 5 | */ 6 | 7 | const REDIS = { 8 | host: "127.0.0.1", 9 | port: "6379", 10 | ttl: 60 * 60 * 12 11 | }; 12 | 13 | const MYSQLDB = { 14 | database:"webFramework", 15 | username:"root", 16 | password:"root", 17 | host:"localhost", 18 | //支持的数据库类型'mysql'|'sqlite'|'postgres'|'mssql' 19 | dialect:"mysql" 20 | }; 21 | 22 | exports.REDIS = REDIS; 23 | exports.MYSQLDB = MYSQLDB; 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web-framework", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "cookie-parser": "~1.4.3", 10 | "debug": "~2.6.9", 11 | "ejs": "~2.5.7", 12 | "express": "~4.16.0", 13 | "http-errors": "~1.6.2", 14 | "morgan": "~1.9.0", 15 | "mysql2": "^1.6.1", 16 | "nodemailer": "^4.6.8", 17 | "sequelize": "^4.38.1", 18 | "tracer": "^0.9.1", 19 | "multer": "^1.4.1", 20 | "express-session": "^1.15.6" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /utils/logHelper.js: -------------------------------------------------------------------------------- 1 | /** 2 | *Author: TaiGuangYin 3 | *Date: 2018 4 | *Description: 日志帮助类 5 | * 6 | *********使用例子*********** 7 | logger.log('hello'); 8 | logger.trace('hello', 'world'); 9 | logger.debug('hello %s', 'world', 123); 10 | logger.info('hello %s %d', 'world', 123, {foo:'bar'}); 11 | logger.warn('hello %s %d %j', 'world', 123, {foo:'bar'}); 12 | logger.error('hello %s %d %j', 'world', 123, {foo:'bar'}, [1, 2, 3, 4], Object); 13 | *********使用例子*********** 14 | * 15 | */ 16 | var console = require('tracer').colorConsole(); 17 | var file = require('tracer').dailyfile({root:'.', maxLogFiles: 10, allLogsFileName: 'foodEva'}); 18 | 19 | exports.console = console; 20 | exports.file = file; 21 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var createError = require('http-errors'); 2 | var express = require('express'); 3 | var path = require('path'); 4 | var cookieParser = require('cookie-parser'); 5 | var logger = require('morgan'); 6 | var session = require('express-session'); 7 | 8 | var indexRouter = require('./routes/index'); 9 | var usersRouter = require('./routes/users'); 10 | 11 | var app = express(); 12 | var ejs = require('ejs'); 13 | 14 | // session setup 15 | app.use(session({ 16 | name:'webFrameworkSession', 17 | resave:true, 18 | saveUninitialized: true, 19 | secret: 'webFrameworkSecret' 20 | })); 21 | 22 | // view engine setup 23 | app.set('views', path.join(__dirname, 'views')); 24 | app.engine('html', ejs.__express); 25 | app.set('view engine', 'html'); 26 | 27 | app.use(logger('dev')); 28 | app.use(express.json()); 29 | app.use(express.urlencoded({ extended: false })); 30 | app.use(cookieParser()); 31 | app.use(express.static(path.join(__dirname, 'public'))); 32 | 33 | app.use('/', indexRouter); 34 | app.use('/users', usersRouter); 35 | 36 | // catch 404 and forward to error handler 37 | app.use(function(req, res, next) { 38 | next(createError(404)); 39 | }); 40 | 41 | // error handler 42 | app.use(function(err, req, res, next) { 43 | // set locals, only providing error in development 44 | res.locals.message = err.message; 45 | res.locals.error = req.app.get('env') === 'development' ? err : {}; 46 | 47 | // render the error page 48 | res.status(err.status || 500); 49 | res.render('error'); 50 | }); 51 | 52 | module.exports = app; 53 | -------------------------------------------------------------------------------- /utils/sequelize.js: -------------------------------------------------------------------------------- 1 | /** 2 | *Author: TaiGuangYin 3 | *Date: 2017 4 | *Description:数据库操作基础类 5 | */ 6 | const Sequelize = require('sequelize'); 7 | const DB = require('../config').MYSQLDB; 8 | const Op = Sequelize.Op; 9 | const operatorsAliases = { 10 | $eq: Op.eq, 11 | $ne: Op.ne, 12 | $gte: Op.gte, 13 | $gt: Op.gt, 14 | $lte: Op.lte, 15 | $lt: Op.lt, 16 | $not: Op.not, 17 | $in: Op.in, 18 | $notIn: Op.notIn, 19 | $is: Op.is, 20 | $like: Op.like, 21 | $notLike: Op.notLike, 22 | $iLike: Op.iLike, 23 | $notILike: Op.notILike, 24 | $regexp: Op.regexp, 25 | $notRegexp: Op.notRegexp, 26 | $iRegexp: Op.iRegexp, 27 | $notIRegexp: Op.notIRegexp, 28 | $between: Op.between, 29 | $notBetween: Op.notBetween, 30 | $overlap: Op.overlap, 31 | $contains: Op.contains, 32 | $contained: Op.contained, 33 | $adjacent: Op.adjacent, 34 | $strictLeft: Op.strictLeft, 35 | $strictRight: Op.strictRight, 36 | $noExtendRight: Op.noExtendRight, 37 | $noExtendLeft: Op.noExtendLeft, 38 | $and: Op.and, 39 | $or: Op.or, 40 | $any: Op.any, 41 | $all: Op.all, 42 | $values: Op.values, 43 | $col: Op.col 44 | } 45 | 46 | const sequelizeInstance = new Sequelize(DB.database, DB.username, DB.password, { 47 | host: DB.host, 48 | dialect: DB.dialect, 49 | //连接池设置 50 | pool: { 51 | max: 100, 52 | min: 0, 53 | acquire: 30000, 54 | idle: 10000 55 | }, 56 | define:{ 57 | paranoid: true, 58 | underscored: true 59 | }, 60 | operatorsAliases, 61 | //logging: false, 62 | timezone: '+08:00' //东八时区 63 | }); 64 | 65 | sequelizeInstance 66 | .authenticate() 67 | .then(() => { 68 | console.log('数据库连接成功.'); 69 | }) 70 | .catch(err => { 71 | console.error('数据库连接失败:', err); 72 | }); 73 | 74 | 75 | 76 | exports.sequelizeInstance = sequelizeInstance; 77 | -------------------------------------------------------------------------------- /bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('../app'); 8 | var debug = require('debug')('web-framework:server'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.PORT || '3000'); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | 24 | /** 25 | * Listen on provided port, on all network interfaces. 26 | */ 27 | 28 | server.listen(port); 29 | server.on('error', onError); 30 | server.on('listening', onListening); 31 | 32 | /** 33 | * Normalize a port into a number, string, or false. 34 | */ 35 | 36 | function normalizePort(val) { 37 | var port = parseInt(val, 10); 38 | 39 | if (isNaN(port)) { 40 | // named pipe 41 | return val; 42 | } 43 | 44 | if (port >= 0) { 45 | // port number 46 | return port; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Event listener for HTTP server "error" event. 54 | */ 55 | 56 | function onError(error) { 57 | if (error.syscall !== 'listen') { 58 | throw error; 59 | } 60 | 61 | var bind = typeof port === 'string' 62 | ? 'Pipe ' + port 63 | : 'Port ' + port; 64 | 65 | // handle specific listen errors with friendly messages 66 | switch (error.code) { 67 | case 'EACCES': 68 | console.error(bind + ' requires elevated privileges'); 69 | process.exit(1); 70 | break; 71 | case 'EADDRINUSE': 72 | console.error(bind + ' is already in use'); 73 | process.exit(1); 74 | break; 75 | default: 76 | throw error; 77 | } 78 | } 79 | 80 | /** 81 | * Event listener for HTTP server "listening" event. 82 | */ 83 | 84 | function onListening() { 85 | var addr = server.address(); 86 | var bind = typeof addr === 'string' 87 | ? 'pipe ' + addr 88 | : 'port ' + addr.port; 89 | debug('Listening on ' + bind); 90 | } 91 | -------------------------------------------------------------------------------- /utils/redis.js: -------------------------------------------------------------------------------- 1 | /** 2 | *Author: TaiGuangYin 3 | *Date: 2017 4 | *Description:Redis操作类封装 5 | */ 6 | var redisSvc = {}; 7 | var redis = require("source/utils/redis"); 8 | var config = require("../config").REDIS; 9 | 10 | if(!client){ 11 | var client = redis.createClient(config.port,config.host); 12 | } 13 | 14 | client.on("error", function (err) { 15 | console.log("Redis Error :" , err); 16 | client = null; 17 | }); 18 | 19 | client.on('connect', function(){ 20 | console.log('Redis连接成功.'); 21 | }); 22 | 23 | /** 24 | * 添加string类型的数据 25 | * @param key 键 26 | * @params value 值 27 | * @params expire (过期时间,单位秒;可为空,为空表示不过期) 28 | */ 29 | redisSvc.set = function(key, value, expire){ 30 | return new Promise(function (resolve, reject) { 31 | if(typeof value == 'undefined') { 32 | return reject(key + '的值为空') 33 | } 34 | client.set(key, value, function(err, result){ 35 | if (err) { 36 | return reject(err); 37 | } 38 | if (!isNaN(expire) && expire > 0) { 39 | client.expire(key, parseInt(expire)); 40 | } 41 | return resolve(result); 42 | }); 43 | }); 44 | 45 | }; 46 | 47 | /** 48 | * 查询string类型的数据 49 | * @param key 键 50 | */ 51 | redisSvc.get = function(key){ 52 | return new Promise(function (resolve, reject) { 53 | client.get(key, function(err,result){ 54 | if (err) { 55 | return reject(err); 56 | } 57 | return resolve(result); 58 | }); 59 | }); 60 | 61 | }; 62 | 63 | /* 64 | *删除String 类型的key 65 | * @param key 键 66 | */ 67 | redisSvc.del = function(key){ 68 | return new Promise(function (resolve, reject) { 69 | client.del(key, function(err,result){ 70 | if (err) { 71 | return reject(err); 72 | } 73 | return resolve(result); 74 | }); 75 | }); 76 | 77 | }; 78 | 79 | 80 | module.exports = redisSvc; 81 | -------------------------------------------------------------------------------- /utils/mailHelper.js: -------------------------------------------------------------------------------- 1 | /** 2 | *Author: TaiGuangYin 3 | *Date: 2018 4 | *Description: mail helper 5 | */ 6 | const nodemailer = require('nodemailer'); 7 | var AppConfig = require('../config'); 8 | 9 | let transporter = nodemailer.createTransport({ 10 | host: AppConfig.EMAIL.host, 11 | //service: 'qq', // 使用了内置传输发送邮件 查看支持列表:https://nodemailer.com/smtp/well-known/ 12 | //port: 465, // SMTP 端口 13 | //secureConnection: true, // 使用了 SSL 14 | auth: { 15 | user: AppConfig.EMAIL.email, 16 | // 这里密码不是qq密码,是你设置的smtp授权码 17 | pass: AppConfig.EMAIL.password, 18 | } 19 | }); 20 | 21 | function sendMail(to,subject,text) { 22 | let mailOptions = { 23 | from: '"We are INcredible"<' + AppConfig.EMAIL.email + '>', // sender address 24 | to: to, // list of receivers 25 | subject: subject, // Subject line 26 | // 发送text或者html格式 27 | text: text, // plain text body 28 | //html: 'Hello world?' // html body 29 | }; 30 | 31 | // send mail with defined transport object 32 | transporter.sendMail(mailOptions, (error, info) => { 33 | if (error) { 34 | return console.log(error); 35 | } 36 | console.log('Message sent: %s', info.messageId); 37 | // Message sent: <04ec7731-cc68-1ef6-303c-61b0f796b78f@qq.com> 38 | }); 39 | } 40 | 41 | function sendMailByHtml(to,subject,html) { 42 | let mailOptions = { 43 | from: '"We are INcredible"<' + AppConfig.EMAIL.email + '>', // sender address 44 | to: to, // list of receivers 45 | subject: subject, // Subject line 46 | // 发送text或者html格式 47 | //text: text, // plain text body 48 | html: html 49 | }; 50 | 51 | // send mail with defined transport object 52 | transporter.sendMail(mailOptions, (error, info) => { 53 | if (error) { 54 | return console.log(error); 55 | } 56 | console.log('Message sent: %s', info.messageId); 57 | // Message sent: <04ec7731-cc68-1ef6-303c-61b0f796b78f@qq.com> 58 | }); 59 | } 60 | 61 | /** 62 | * @return {string} 63 | */ 64 | function SignEndContent(){ 65 | return 'Dear colleague,