初学nodejs+express,打造cms系统(2)
先安装需要的组件,主要是express脚手架,deasync,mysql,cookie-parser
package.json
{
"name": "demo1",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/start.js",
"dev": "node-dev ./bin/start.js"
},
"dependencies": {
"co": "^4.6.0",
"cookie-parser": "~1.4.4",
"deasync": "^0.1.21",
"debug": "~2.6.9",
"ejs": "~2.6.1",
"excel-export": "^0.5.1",
"express": "~4.16.1",
"express-session": "^1.17.1",
"http-errors": "~1.6.3",
"morgan": "~1.9.1",
"multiparty": "^4.2.2",
"mysql": "^2.18.1",
"node-dev": "^6.6.0",
"node-xlsx": "^0.16.1",
"session-file-store": "^1.5.0",
"sync-request": "^6.1.0"
}
}脚手架有个app.js,这必须规划好,有个管理路径(或许称呼为路由器,我个人还是喜欢叫admin);每一个管理模块(我个人称之为model);每个模块由n个行为组成( 我个人称为action)
没专门学习nodejs,直接看了个指引教程上手撸代码。还是用的古老的php思路,专业名次叫不准。当时不影响我继续实践。
再聊app.js,基本上都有雏形了,然后需要管理路由,先把后台路由到admin
app.use('/'+config.admin_dir, require('./routes/admin')); //管理地址
路由里,再转换到不同的model
if($model=='code')
{
var api_path=`../admin/code/code`;
console.log(api_path);
var api_action=require(api_path);
api_action.init(base,$model,$ac);//装载
api_action.action();
}
详细代码如下
【app.js】
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var config = require('./config/config');
var session = require('express-session');
var FileStore = require('session-file-store')(session);
var app = express();
var identityKey = 'sessionkey';
app.use(session({
name: identityKey,
secret: 'gggguuuuyyyy', // 用来对session id相关的cookie进行签名
store: new FileStore(), // 本地存储session(文本文件,也可以选择其他store,比如redis的)
saveUninitialized: false, // 是否自动保存未初始化的会话,建议false
resave: false, // 是否每次都重新保存会话,建议false
cookie: {
maxAge: 365 * 24 * 3600 * 1000 // 有效期,单位是毫秒
}
}));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
//静态资源目录
//app.use('/assets', express.static('assets'));
//app.use('/json', express.static('json'));
//app.use('/page', express.static('page'));
app.get('/'+config.admin_dir+'*', function( req, res, next) {
try{
var check_path=req.params['0'];
if(!check_path || typeof(check_path)=='undefined')
{
var check_path='';
}
}catch(e){
var check_path='';
}
if(check_path!='/')
{
next(createError(404));
}else{
next();
}
}); //管理地址 规则过滤
app.use('/', require('./routes/index'));
app.use('/test', require('./routes/test'));
app.use('/'+config.admin_dir, require('./routes/admin')); //管理地址
app.use('/api', require('./routes/api')); //管理地址
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;【routes/admin.js】
var express = require('express');
var router = express.Router();
var base = require('../function/base');
base.use(['config','fun','db_mysql']);
var db=base.db_mysql;
db.init(base.config.mysql);
base.db=db;
/* GET home page. */
router.use('/', function(req, res, next) {
base.$config=base.db.select_one("select * from config where tag='config'");
base.config.randtime=Date.parse(new Date());
base.use('req_res',{req:req,res:res});
var req_res=base.req_res;
var $ac=base.fun.str(req.query["action"]);
var $model=base.fun.str(req.query["model"]);
base.$model=$model;
//admin基础数据处理
var admin_username=base.req_res.admin_username();
if(admin_username!='')
{
var admininfo_sql=`select * from admin where admin_username='${admin_username}'`;
var admininfo=base.db.select_one(admininfo_sql);
var admingroup_id=admininfo['admingroup'];
var admingroup_sql=`select * from admingroup where id='${admingroup_id}'`;
var admingroup=base.db.select_one(admingroup_sql);
base.admin={
username:admin_username
,info:admininfo
,admingroup_id:admingroup_id
,admingroup:admingroup
,is_systemadmin:admininfo['system']
};
//console.log('***********base.admin*************');
//console.log(base.admin);
}
base.$tpl={
page_title:base.$config.sitename
,this_dw:''
};
//特殊模块 主要是处理少量不要登录的特殊用途模块
if($model=='code')
{
var api_path=`../admin/code/code`;
console.log(api_path);
var api_action=require(api_path);
api_action.init(base,$model,$ac);//装载
api_action.action();
}else{
//常规 admin 模块
//未登录 或者 登录模块 拦截
if( !req_res.admin_checklogin() && $ac!='logincp'){
$model="login";
res.render(`admin/login/admin_login`, { base: base });
return;
}else{
if($model=='')
{
//首页
res.render(`admin/index`, { base: base });
return;
}else{
if($ac=='')
{
//默认为功能首页
$ac='index';
}
//get view层(view层里绑定具体哪一个view)
var api_path=`../admin/admin/${$model}`;
console.log(api_path);
var api_action=require(api_path);
api_action.init(base,$model,$ac);//装载
try{
var this_type=typeof(api_action.action[$ac]);
}catch(e){
var this_type='';
}
if(this_type=='undefined')
{
//部分无关紧要的页面效果
res.render(`admin/${$model}/admin_${$ac}`, { base: base,$tpl:base.$tpl,$model:$model,$ac:$ac });
}else{
api_action.action[$ac]();
}
//
return;
}
}
//常规 admin 模块 end
}
});
module.exports = router;个人喜欢用大括号,看了对齐心里爽,所以很多能不用大括号的地方我也用了。编辑器可以折叠大括号,方便维护代码。抛开这些大括号,我代码里主要是路由跳转类的工作。注释中大量用到了“装载”,其实我的核心部分都是由操作类控制。
【操作类base.js】一个基础类,可以说所有代码base走遍天下。后面每个模块都是通过base串联的。插口式代码写入方式,非大家熟悉的顺序式。我这个base有点跟前端的window变量一样,当一个超级全局变量在用。由于js双向绑定特性,base这个超级全局变量上插满了东西。就像一台电脑,插一个u盘(user模块);再插一个u盘(order模块);再插一个u盘(admin模块)。
当然nodejs我还是个菜鸟,只是利用一些前端的javescript进行开发,没有系统学习。所以这个时候很多时候结合其他语言,其他系统自创的模式。目的也只有一个,以自己的思路先学着,遇到问题想办法解决,在摸索中学习。
今天先介绍到这,后面的代码下次继续介绍。
