初学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进行开发,没有系统学习。所以这个时候很多时候结合其他语言,其他系统自创的模式。目的也只有一个,以自己的思路先学着,遇到问题想办法解决,在摸索中学习。
今天先介绍到这,后面的代码下次继续介绍。