nodejs 做后台的一个完整业务整理

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介:   大家知道js现在不仅仅可以写前端界面而且可以写后端的业务了,这样js就可以写一个全栈的项目。这里介绍一个nodejs + express + mongodb + bootstap 的全栈项目。  1、安装必要的包,npm install express  npm install mongodb npm install ejs (需要使用什么工具,就安装哪个工具)  2、建一个入口文件,index.js,这里主要是做路由的分发。

  大家知道js现在不仅仅可以写前端界面而且可以写后端的业务了,这样js就可以写一个全栈的项目。这里介绍一个nodejs + express + mongodb + bootstap 的全栈项目。

  1、安装必要的包,npm install express  npm install mongodb npm install ejs (需要使用什么工具,就安装哪个工具)

  2、建一个入口文件,index.js,这里主要是做路由的分发。启动:   node index.js

var express = require("express");// require express 的框架
var app = express(); // 实例化一个 express的对象
var router = require("./router/router.js"); // 引用 router 的文件,下面将介绍这个router
var session = require('express-session');// 使用了 express 一个 session 的工具,主要用作注册登录使用
var config = require("./config.js");// 引用一个配置文件


//使用session
app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
}));
//设置跨域访问  在做前后端分离,nodejs提供接口的时候,这个设置跨域请求必不可少
  app.all('*', function(req, res, next) {
     res.header("Access-Control-Allow-Origin", "*"); // 表示任意的源
    // res.header("Access-Control-Allow-Origin", "http://www.wtapi.wang"); // 只有这个网址
    res.header("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By",'unknown')
    res.header("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
    next();
});


  app.set("view engine","ejs");
  app.set('views', path.join(__dirname, 'views'));
app.use(express.static("./assets"));// 静态一个文件夹,实用的好处这里的文件的路径就可以 用  /   表示

app.get("/",router.index); // 后端分发的路由 "/" 表示主页 主页的业务代码逻辑在 router里的 index 的函数里

//我的发布
// app.get("/mypost", routerUser.list);
//search
// app.get("/search",routerSearch.list);

//执行登陆业务
app.post("/doLogin",router.doLogin);
app.post("/doCinemaSubmit",router.doCinemaSubmit);
//个人中心页

// app.get("/usercenter",router.showUserCenter);

app.get("/cinema/:targetId",router.showSelectPage);

app.post('/seatHandle', router.seatHandle)
//退出
app.get("/user_exit",router.logout);

//提交修改密码
app.post("/reviseMyMsg",router.reviseMyMsg);

app.listen(config.port, function () {
    console.log("项目启动成功: " + config.port);
});

3、处理后端业务数据逻辑的router,这里router 名字可以随便取,贴切的话可以 命名为 controller  或者 model  ,两个命名规范的业务划分,我统统集合在这个一个文件里。

//又提交,引入formidable
var formidable = require("formidable"); // 一个前台提交到后端接受数据的一个包,缺点: 没办法接受前端传来的数组数据
//引入封装好的db.js,从config走
var db = require("../model/db.js"); // 这里的解释转到4 

var path = require("path"); var fs = require("fs");var mongo = require('mongodb'); var Ob = mongo.ObjectID; var userData = {};
// post 请求的一种方式
//注册业务 这是一个post 的请求,接受前端传来的数据做业务处理,处理后返回前端 res.send('....') 前端ajax 获得一个返回状态,做前端数据处理 exports.doRegist = function (req,res,next) { var form = new formidable.IncomingForm(); form.parse(req, function(err, fields, files) { var username = fields.username; var userpassword = fields.userpassword; var sharecode = fields.sharecode; // 邀请码 if (!sharecode){ res.send("-11"); return; } if (!Ob.isValid(sharecode)){ res.send("-11"); return; } // sharecode = "59ac32bbab6a439ed60ebb74"; 测试用 db.find(ds.SHARECODE, {"_id":mongo.ObjectID(sharecode)}, function(err, result){ if (err){ res.send("-11"); return; } if (result.length == 0){ res.send("-11"); return; } db.find("users",{"username": username},function (err,result) { if(err) { res.send("-3"); return; } if(result.length !=0) {//数据库查询到有数据占用 res.send("-1");//被占用 return; } //设置MD5加密 userpassword = md5(md5(userpassword)+"adou"); //返回result.length的长度为0,说明数据库中没有此名字 db.insertOne("users",{ "msgnum" : 0, "username" : username, "userpassword" : userpassword, "nickname" : '', "avatar" : "/user/default.jpg" },function(err,result){ if(err){ res.send("-3");//服务器错误 return; } refresh(req,res,username); // 删除此邀请码 db.deleteMany(ds.SHARECODE, {"_id":mongo.ObjectID(sharecode)}, function(err, result){}); }); }); }); }); } // //执行登录 exports.doLogin = function (req,res,next) { var form = new formidable.IncomingForm(); form.parse(req, function(err, fields, files) { //表单数据 var username = fields.username; var userpassword = fields.userpassword; userpassword_handel= md5(md5(userpassword)+"adou"); db.find("users",{"username" : username},function(err,result){ if(err){ res.send("-5");//随便去,服务器错误 return; } if(result.length == 0){ res.send("-1");//用户名不存在 return; } if(userpassword_handel == result[0].userpassword){ req.session.login = "1"; req.session.username= username; req.session.uid = result[0]._id; console.log(req.session.uid, "login", Math.floor(new Date().getTime()/1000)); res.send("1"); return; }else{ res.send("-2");//密码错误 return; } }); }) }


// get 请求的一个方式

//访问首页 
exports.index = function (req,res,next) {
console.log("router: [/]:exports.index");
var login = req.session.login;
var username = req.session.username;
var userinfo = util.getLoginUser(req);
  // 渲染一个页面,将相关的数据渲染到页面上 res.render('url',{data})
  res.render('index',{ // index 是一个页面转到 5 
    userinfo:{'login':login,'username':username}
  })
}
 

4、上面引入的 db.js 是有关操作数据库的操作,对原始的mongdb 的语法,做了一下封装。

//这个模块里面封装了所有对数据库的常用操作
var MongoClient = require('mongodb').MongoClient;
var config = require("../config.js");
//不管数据库什么操作,都是先连接数据库,所以我们可以把连接数据库
//封装成为内部函数
function _connectDB(callback) {
    var url = config.dburl;   //从 config.js 文件中,都数据库地址
    //连接数据库
    MongoClient.connect(url, function (err, db) {
        if (err) {
            callback(err, null);
            return;
        }
        callback(err, db);
    });
}

//插入数据
exports.insertOne = function (collectionName, json, callback) {
    _connectDB(function (err, db) {
        db.collection(collectionName).insertOne(json, function (err, result) {
            callback(err, result);
            db.close(); //关闭数据库
        })
    });
};
// insertmany
exports.insertMany = function(cname, arr){
    _connectDB(function (err, db) {
        db.collection(cname).insertMany(arr, function (err, result) {
            db.close();
        });
    });
}
exports.removeAll = function(cname, cb){
    _connectDB(function (err, db) {
        db.collection(cname).deleteMany({}, function (err, result){
            cb(err, result);
            db.close();
        });
    });
}
//查找数据,找到所有数据。args是个对象{"pageamount":10,"page":10}
exports.find = function (collectionName, json, C, D) {
    var result = [];    //结果数组
    if (arguments.length == 3) {
        //那么参数C就是callback,参数D没有传。
        var callback = C;
        var skipnumber = 0;
        //数目限制
        var limit = 0;
    } else if (arguments.length == 4) {
        var callback = D;
        var args = C;
        //应该省略的条数
        var skipnumber = args.pageamount * args.page || 0;
        //数目限制
        var limit = args.pageamount || 0;
        //排序方式
        var sort = args.sort || {};
    } else {
        throw new Error("find函数的参数个数,必须是3个,或者4个。");
        return;
    }

    //连接数据库,连接之后查找所有
    _connectDB(function (err, db) {
        var cursor = db.collection(collectionName).find(json).skip(skipnumber).limit(limit).sort(sort);
        cursor.each(function (err, doc) {
            if (err) {
                callback(err, null);
                db.close(); //关闭数据库
                return;
            }
            if (doc != null) {
                result.push(doc);   //放入结果数组
            } else {
                //遍历结束,没有更多的文档了
                callback(null, result);
                db.close(); //关闭数据库
            }
        });
    });
}

//删除
exports.deleteMany = function (collectionName, json, callback) {
    _connectDB(function (err, db) {
        //删除
        db.collection(collectionName).deleteMany(
            json,
            function (err, results) {
                callback(err, results);
                db.close(); //关闭数据库
            }
        );
    });
}
// findmany
exports.findmany = function(cname, con, filter, cb){
    _connectDB(function (err, db) {
        db.collection(cname).find(con, filter).toArray(function(err, docs){
            cb(err, docs);
            db.close();
        });
    });
};
// findone
exports.findone = function(cname, con, op, cb){
    _connectDB(function (err, db) {
        db.collection(cname).findOne(con,{fields:op}, function(err, doc){
            cb(err, doc);
            db.close();
        });
    });
};
//修改
exports.updateMany = function (collectionName, json1, json2, callback) {
    _connectDB(function (err, db) {
        db.collection(collectionName).updateMany(
            json1,
            json2,
            function (err, results) {
                callback(err, results);
                db.close();
        });
    })
};

exports.getAllCount = function (collectionName,callback) {
    _connectDB(function (err, db) {
        db.collection(collectionName).count({}).then(function(count) {
            callback(count);
            db.close();
        });
    })
}

exports.count = function(cname,cond,cb){
    _connectDB(function (err, db) {
        db.collection(cname).count(cond).then(function(count) {
            cb(count);
            db.close();
        });
    });
}

exports.one = function(cname, cond, cb){
    _connectDB(function (err, db) {
        db.collection(cname).count(cond).then(function(err, one) {
            cb(err, one);
            db.close();
        });
    });
}

5、具体到前端页面

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>管理系统</title>
    <% include component/css.ejs %>  // ejs 的一个模版,把相同的东西,封装在一个 模板里,然后各个页面  include 这个模板
  </head>
  <body class="index-body">
    <div><%= userinfo.login%></div>  // ejs 模板渲染  渲染的数据 直接用  <%= data%> 表示

  <div><%= userinfo.username%></div> //
</body> </html>

 

 这样的话,一个前端到后端,后端处理前端传来的数据,nodejs 操作数据库,并返回数据给前端的流程就走通了。

 这里不是前后端分离,这里采用的是后端渲染的方式,也就是,后台将页面渲染好,然后返回到前端。

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
6月前
|
小程序 JavaScript Java
农场管理小程序|基于微信小程序的农场管理系统设计与实现(源码+数据库+文档)
农场管理小程序|基于微信小程序的农场管理系统设计与实现(源码+数据库+文档)
54 2
|
7天前
|
前端开发 JavaScript 数据安全/隐私保护
优雅实现管理后台403页面:技术细节与实践案例
在管理后台开发中,403页面是一个不可忽视的组成部分。它不仅关系到用户体验,还涉及到系统的安全性。本文将分享如何在管理后台中优雅地实现403页面,以及几个具体的实践案例。
16 2
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp小程序的数据分析岗位招聘信息与分析附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp小程序的数据分析岗位招聘信息与分析附带文章源码部署视频讲解等
22 0
|
6月前
|
JavaScript Java 关系型数据库
大学生在线考试|基于SprinBoot+vue的在线试题库系统系统(源码+数据库+文档)
大学生在线考试|基于SprinBoot+vue的在线试题库系统系统(源码+数据库+文档)
51 0
|
6月前
|
Go
区域代理分红商城系统开发指南教程/步骤功能/方案逻辑/源码项目
The development of regional proxy dividend distribution mall system involves multiple aspects such as proxy dividend function and electronic mall system development. The following is an overview of the steps for developing a regional agent dividend distribution mall system
|
监控 JavaScript
nodejs服务后台持续运行
nodejs服务后台持续运行
205 0
|
前端开发
前端代码简洁之路,后台系统之详情页设计
前端业务开发中,为了脱离舒适区,也为了解放重复功能开发的劳动力,会将一些功能进行改造,本期改造千篇一律的详情页。
3999 26
前端代码简洁之路,后台系统之详情页设计
|
数据安全/隐私保护 Python
python线上商城网站项目前台和后台源码
python线上商城网站项目前台和后台源码
146 0
|
前端开发
前端学习笔记202303学习笔记第五天-了解vite项目的运行流程1
前端学习笔记202303学习笔记第五天-了解vite项目的运行流程1
71 0
下一篇
无影云桌面