美文网首页
nodejs mongo博客说说小项目

nodejs mongo博客说说小项目

作者: pretty_rain | 来源:发表于2019-01-02 14:23 被阅读0次

项目下载地址:https://github.com/prettyRain/shuoshuo
项目用到的技术:nodejs+express+mongodb+ejs+cookie+session
项目功能: 注册、登录、上传裁切头像 、发表说说 、查看所有说说、看某人说说
项目环境:node环境 mongo数据库安装

项目目录:


image.png

avatar:存放上传的图片
model:db.js 操作数据库 md5.js 加密


image.png

node_modules: 下载的包
public: bootstrap框架 jcrop裁切图片框架 toptip提示框


image.png

router : 路由


image.png
views:页面展示
image.png
app.js:控制层

settings.js: 配置参数

db.js:

/**
 * Created by prettyRain on 2018/12/10.
 */

 var mongoClient = require('mongodb').MongoClient;
 var settings = require('../settings.js');
 
 var dburl = settings.dburl;
 var dbname = settings.dbname;

/**
 * 连接数据库
 * @param callback
 */
function clientmongodb(callback){
    mongoClient.connect(dburl,function(err,client){
         callback(err,client);
     })
 }

/**
 * 插入一条数据
 * @param collectionName
 * @param paramJSON
 * @param callback
 */
exports.insertOne = function(collectionName,paramJSON,callback){
    clientmongodb(function(err,client){
        if(err){
            callback(err,null);
            return;
        }
        var db = client.db(dbname);
        db.collection(collectionName).insertOne(paramJSON,function(err,result){
            callback(err,result);
            client.close();
        })
    })
}
/**
 * 插入多条数据
 * @param collectionName 集合名称
 * @param paramArray json数组
 * @param callback  回调函数
 */
exports.insertMany = function(collectionName,paramArray,callback){
    clientmongodb(function(err,client){
        var db = client.db(dbname);
        db.collection(collectionName).insertMany(paramArray,function(err,result){
            callback(err,result);
            client.close();
        })
    })
}
/**
 * 修改一条数据
 * @param collectionName 集合名称
 * @param whereJSON  修改条件
 * @param paramJSON  修改内容
 * @param callback   回调函数
 */
exports.updateOne = function(collectionName,whereJSON,paramJSON,callback){
    clientmongodb(function(err,client){
        var db = client.db(dbname);
        db.collection(collectionName).updateOne(whereJSON,paramJSON,function(err,result){
             callback(err,result);
            client.close();
        })
    })
}
/**
 * 修改多条数据
 * @param collectionName 集合名称
 * @param whereJSON  修改条件
 * @param paramJSON  修改内容
 * @param callback   回调函数
 */
exports.updateMany = function(collectionName,whereJSON,paramJSON,callback){
    clientmongodb(function(err,client){
        var db = client.db(dbname);
        db.collection(collectionName).updateMany(whereJSON,paramJSON,function(err,result){
            callback(err,result);
            client.close();
        })
    })
}
/**
 * 删除一条数据
 * @param collectionName 集合名称
 * @param whereJSON 条件
 * @param callback  回调函数
 */
exports.deleteOne = function(collectionName,whereJSON,callback){
    clientmongodb(function(err,client){
        var db = client.db(dbname);
        db.collection(collectionName).deleteOne(whereJSON,function(err,result){
            callback(err,result);
            client.close();
        })
    })
}

/**
 * 删除多条数据
 * @param collectionName 集合名称
 * @param whereJSON 条件
 * @param callback  回调函数
 */
exports.deleteMany = function(collectionName,whereJSON,callback){
    clientmongodb(function(err,client){
        var db = client.db(dbname);
        db.collection(collectionName).deleteMany(whereJSON,function(err,result){
            callback(err,result);
            client.close();
        })
    })
}

/**
 * 查询
 * @param collectionName
 * @param whereStr
 * @param B
 * @param C
 */
exports.find = function(collectionName,whereStr,B,C) {
    if (arguments.length == 3) {
        var callback = B;
        clientmongodb(function (err, client) {
            var db = client.db(dbname);
            db.collection(collectionName).find(whereStr).toArray(function (err, result) {
                callback(err, result);
                client.close();
            })
        })
    } else {
        var callback = C;
        var paramJSON = B;
        clientmongodb(function (err, client) {
            var sort = (!paramJSON.sort) ? {} : paramJSON.sort;
            var end = (!paramJSON.end) ? 0 : paramJSON.end;
            var start = (!paramJSON.start) ? 0 : paramJSON.start;
            var db = client.db(dbname);
            db.collection(collectionName).find(whereStr).sort(sort).skip(start).limit(end).toArray(function (err, result) {
                callback(err, result);
                client.close;
            })
        })
    }
}
/**
 * 删除集合
 * @param collectionName
 * @param callback
 */
exports.drop = function(collectionName,callback){
   clientmongodb(function(err,client){
       var db = client.db(dbname);
       db.collection(collectionName).drop(function(err,result){
           callback(err,result);
           client.close();
       });
   })
}

/**
 * 查询总条数
 * @param collectionName
 * @param whereStr
 * @param callback
 */
exports.count = function(collectionName,whereStr,callback){
    clientmongodb(function(err,client){
        var db = client.db(dbname);
        db.collection(collectionName).find(whereStr).count(function(err,result){
            callback(err,result);
            client.close();
        })
    })
}

md5.js

/**
 * Created by prettyRain on 2018/12/10.
 */

var crypto = require('crypto');

module.exports = function(password){
    var md5 = crypto.createHash('md5');
    return md5.update(password).digest('hex');
}

router.js

/**
 * Created by prettyRain on 2018/12/10.
 */
var db = require('../model/db.js');
var md5 = require('../model/md5');
var formidable = require('formidable');
var util = require('util');
var fs = require('fs');
var gm = require('gm');

/**
 * 首页
 * @param req
 * @param res
 */
exports.showIndex = function(req,res){
    console.log(req.session.login);
  if(req.session.login=='1'){
      db.find("users",{username:req.session.username},function(err,result){
          if(!err){
              res.render('index',{login:"1",username:req.session.username,avatar:result[0].avatar,active:"全部说说"})
          }
      });
      
  }else{
      res.render('index',{login:"-1",active:"全部说说"});
  }
   
}
/**
 * 注册页面
 * @param req
 * @param res
 */
exports.showRegist = function(req,res){
    if(req.session.login=='1'){
        res.render('regist',{login:"1",username:req.session.username,avatar:req.session.avatar,active:"全部说说"})
    }else{
        res.render('regist',{login:"-2",active:"全部说说"});
    }
}

/**
 * 注册
 * @param req
 * @param res
 */
exports.doRegist = function(req,res){
    var form = new formidable.IncomingForm();
    
    form.parse(req, function(err, fields, files) {
        
        console.log(util.inspect({fields: fields, files: files}));
        var username = fields.username;
        var password = md5(fields.password);
        db.find("users",{username:username},{"end":1},function(err,result){
            if(err){
                res.send("-1");
                return;
            }
            if(result.length > 0){
                if(password == result[0].password){
                    res.send("-2")
                    return;
                }
            }
            db.insertOne("users",{username:username,password:password,avatar:"headphoto.jpg"},function(err,result){
                if(err){
                    res.send("-1");
                    return;
                }
                req.session.username = username;
                req.session.login = "1";
                res.send("1");
            });
            
        })
        
    });
}

/**
 * 登录页面
 * @param req
 * @param res
 */
exports.showLogin = function(req,res){
    res.render('login',{login:"-3",active:"全部说说"});
}
/**
 * 登录
 * @param req
 * @param res
 */
exports.doLogin = function(req,res){
    var form = new formidable.IncomingForm();
    
    form.parse(req, function(err, fields, files) {
        var username = fields.username;
        var password = md5(fields.password);
        db.find('users',{username:username},function(err,result){
            if(err){
                res.send("-1");
                return;
            }
            if(result.length > 0){
                if(password == result[0].password){
                    req.session.login = '1';
                    req.session.username = username;
                    req.session.avatar = result[0].avatar;
                    res.send("1");
                }else{
                    //用户名密码不匹配
                    res.send("-3");
                };
            }else{
                //用户名不存在
                res.send("-2")
            }
        })
    })
}
/**
 * 上传图片页面
 * @param req
 * @param res
 */
exports.showAvatar = function(req,res){
    if(req.session.login == "1"){
        res.render('avatar',{login:'1',username:req.session.username,active:"全部说说"});
    }else{
        res.render('avatar',{login:'-1',active:"全部说说"});
    }
}
/**
 * 上传图片
 * @param req
 * @param res
 */
exports.doAvatar = function(req,res){
    if(req.session.login != "1"){
        res.send("-2");
        return;
    }
    var form = new formidable.IncomingForm();
    form.uploadDir = "./avatar";
    form.parse(req, function(err, fields, files) {
       var oldpath = "./"+files.tupian.path;
       var newpath = "./avatar/"+req.session.username+".jpg";
       fs.rename(oldpath,newpath,function(err){
           if(err){
               res.send("-1");
               return;
           }
           //压缩图片
           gm(newpath)
            .resize(500, 500, '!')
            .noProfile()
            .write(newpath, function (err) {
            if (err) {
            console.log(err);
            res.send("-1");
            return;
            }
                res.send({username:req.session.username});
            });
       })
    })
}

/**
 * 裁切图片
 * @param req
 * @param res
 */
exports.setAvatar = function(req,res){
    if(req.session.login != "1"){
        res.send("-2");
        return;
    }
    var form = new formidable.IncomingForm();
    form.parse(req, function(err, fields, files) {
       var x = fields.x;
       var y = fields.y;
       var w = fields.w;
       var h = fields.h;
       console.log(fields);
        //裁切图片
        gm("./avatar/"+req.session.username+".jpg")
         //裁剪参数(w,h,x,y)
         .crop(w,h,x,y)
         .write("./avatar/"+req.session.username+".jpg",function(err){
         if(!err) {
             console.log(1)
             db.updateOne("users",{username:req.session.username},{$set: {avatar:req.session.username+".jpg"} },function(err,result){
                 if(err){
                     console.log(err);
                     res.send("-1");
                     return;
                 }
                 console.log("done");
                 res.send("1");
             })
         }
         })
    })
}
/**
 * 添加说说
 * @param req
 * @param res
 * @param next
 */
exports.addPost = function(req,res,next){
    if(req.session.login=='1') {
    
        var form = new formidable.IncomingForm();
        form.parse(req, function (err, fields, files) {
            var username = fields.username;
            var content = fields.content;
            db.insertOne("posts", {username: username, content: content, creatTime:new Date()}, function (err, reuslt) {
                if (err) {
                    res.send("-2");
                    return;
                }
                res.send("1");
            })
        })
    }else{
        res.send("-1");
    }
}
/**
 * 查询所有说说
 * @param req
 * @param res
 * @param next
 * @constructor
 */
exports.AllPosts = function(req,res,next){
    var currentPage = parseInt(req.query.currentPage);
    var pageSize = parseInt(req.query.pageSize);
    var start = (currentPage-1)*pageSize;
    var end = pageSize;
    db.find('posts',{},{start:start,end:end,sort:{creatTime:-1}},function(err,result){
        if(err){
            res.send("");
            return;
        }
        db.count('posts',{},function(err,result1){
            if(err){
                res.send("");
                return;
            }
            var totalPage = result1%pageSize==0?result1/pageSize:(result1/pageSize + 1);
            (function itempost(i){
                if(!result.length || result.length == i){
                    res.send({list:result,totalPage:parseInt(totalPage),currentPage:currentPage});
                    return;
                }
                db.find('users',{username:result[i].username},function(err,result2){
                    if(err){
                        console.log(err);
                        return;
                    }
                    result[i].avatar = result2[0].avatar;
                    i++;
                    itempost(i);
                });
            })(0)
        })
    })
}
/**
 * 成员列表
 * @param req
 * @param res
 * @param next
 */
exports.userlist = function(req,res,next){
    if(req.session.login=='1'){
        db.find("users",{username:req.session.username},function(err,result){
            if(!err){
                db.find("users",{},function(err,results){
                    if(!err){
                        res.render('userlist',{login:"1",username:req.session.username,avatar:result[0].avatar,active:"成员列表",users:results})
                    }
                })
            }
        });
    }else{
        db.find("users",{},function(err,result){
            if(!err){
                res.render('userlist',{login:"-1",active:"成员列表",users:result});
            }
        })
       
    }
}
/**
 * 某个人的说说
 * @param req
 * @param res
 * @param next
 */
exports.user = function(req,res,next){
    var user = req.params.username;
    if(req.session.login=='1'){
        db.find("users",{username:req.session.username},function(err,result){
            if(!err){
                db.find("users",{username:user},function(err,result1){
                    if(!err){
                        db.find('posts',{username:user},function(err,result2){
                            for(var i in result2){
                                result2[i].avatar = result1[0].avatar;
                            }
                            console.log(result2);
                            res.render('user',{login:"1",username:req.session.username,avatar:result[0].avatar,active:"我的说说",userposts:result2});
                        })
                        
                    }
                })
            }
        });
    }else{
        db.find("users",{username:user},function(err,result1){
            if(!err){
                db.find('posts',{username:user},function(err,result2){
                    for(var i in result2){
                        result2[i].avatar = result1[0].avatar;
                    }
                    console.log(result2);
                    res.render('userlist',{login:"-1",active:"我的说说",userposts:result2});
                })
            
            }
        })
        
    }
}
/*exports.queryUserByUsername = function(req,res,next){
    var username = req.query.username;
    console.log(username);
    db.find('users',{username:username},function(err,result){
        if(err){
            console.log(err);
            res.send("");
            return;
        }
        res.send(result[0]);
    })
}*/

avatar.ejs

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../favicon.ico">
    <title>上传头像</title>
    <link rel="stylesheet" href="/toptip/toptip.css">
    <link rel="stylesheet" href="/jcrop/jquery.Jcrop.css">
    <link rel="stylesheet" href="/jcrop/demos.css">
    <!-- Bootstrap core CSS -->
    <link href="/bootstrap/css/bootstrap.css" rel="stylesheet">
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
    <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>

<body>
<!--头部-->
<%include head.ejs%>
<div class="container theme-showcase" role="main">
    <div class="jumbotron">
        <div class="media" style="margin-top:40px;">
            <form enctype="multipart/form-data" id="formId" >
                <div class="form-group">
                    <label for="exampleInputFile">头像</label>
                    <input type="file" id="exampleInputFile" accept="image/gif, image/jpeg" name="tupian">
                </div>
                <p  class="btn btn-default psubmit">提交<p/>
            </form>

        </div>
        <!--裁切图片-->
        <div id="outer" style="display:none;">
            <div class="jcExample">
                <div class="article">
                    <h1>上传头像拖动例子</h1>
                    <p id="xianshi"></p>
                    <table>
                        <tr>
                            <td>
                                <img  id="target" alt="Flowers" style="width:500px;height:500px;"/>
                            </td>
                            <td>
                                <div style="width:100px;height:100px;overflow:hidden;" id="aa">
                                    <img  id="preview" alt="Preview" class="jcrop-preview" />
                                </div>
                            </td>
                        </tr>
                    </table>
                </div>
            </div>
            <div class="subdiv">
                <p class="subp btn btn-danger">提交裁切</p>
            </div>
        </div>

    </div>

</div> <!-- /container -->
<script src="/bootstrap/js/bootstrap.js"></script>
<script src="/bootstrap/js/jquery-1.11.3.js"></script>
<script src="/toptip/toptip.js"></script>
<script src="/jcrop/jquery.min.js"></script>
<script src="/jcrop/jquery.Jcrop.min.js"></script>
</body>
</html>
<script type="text/javascript">
    var tip = tipAlert();

    $('.psubmit').on('click',function(){
        if(!$('#exampleInputFile').val()){
            tip('内容不能为空');
            return ;
        }
      $.ajax({
          type:"post",
          url:"/doAvatar",
          dataType:"json",
          data:new FormData(document.getElementById("formId")),
          contentType:false,
          processData:false,
          success:function(result){
               if(result=="-1"){
                   tip('上传图片错误');
                   return;
               }else if(result == "-2"){
                   window.location.href = "/";
               }
              $('#outer').slideDown(1000);
              $('#target').width("500px").height("500px").attr("src","/"+result.username+".jpg");
              $('#preview').attr("src","/"+result.username+".jpg");

              //加载裁切图片js
              new cutImage().init();
          }
      })
    $(".subp").on('click',function(){
           $.post("/setAvatar",xyhw,function(result){
              if(result == "-2"){
                  tip("报错");
                  return;
              }
              window.location.href = "/";
           })
    })
    })
    var xyhw = {};
    var x,y,h,w;

    function cutImage(){
        var oop = this;
        this.option = {
            x:170,
            y:110,
            w:350,
            h:200,
            t:'target',
            p:'preview',
            o:'aa',
            q:'xianshi'
        }
        this.init = function(){
            oop.target();
        }
        this.target = function(){
            $('#'+oop.option['t']).Jcrop({
                onChange: oop.updatePreview,
                onSelect: oop.updatePreview,
                aspectRatio: 1,
                setSelect: [ oop.option['x'], oop.option['y'], oop.option['w'],oop.option['h'] ],
                bgFade:     true,
                bgOpacity: .5
            });
        }
        this.updatePreview = function(obj){
            if (parseInt(obj.w) > 0)
            {
                var rx = $('#'+oop.option['o']).width()/ obj.w;
                var ry = $('#'+oop.option['o']).height()/ obj.h;
                var holder = document.querySelector('.jcrop-holder').children[0];
                w = getcurrentStyle(holder,"width");
                h = getcurrentStyle(holder,"height");
                x = getcurrentStyle(holder,"left");
                y  = getcurrentStyle(holder,"top");
                document.querySelector("#xianshi").innerHTML = "x:"+x+";"+"y"+y+";"+"w:"+w+"h:"+h;
                xyhw.x = parseInt(x);
                xyhw.y = parseInt(y);
                xyhw.w = parseInt(w);
                xyhw.h = parseInt(h);
                $('#'+oop.option['p']).css({
                    width: Math.round(rx*$('#'+oop.option['t']).width()) + 'px',
                    height: Math.round(ry*$('#'+oop.option['t']).height()) + 'px',
                    marginLeft: '-' + Math.round(rx * obj.x) + 'px',
                    marginTop: '-' + Math.round(ry * obj.y) + 'px'
                });
            }
        }
    }
    function getcurrentStyle(ele,attr){
        if(window.getComputedStyle){
            return window.getComputedStyle(ele,null)[attr];
        }else{
            //IE
            return ele.currentStyle(attr);
        }
    }
</script>

head.ejs

<!-- Fixed navbar -->
<nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">班级说说</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li <%if(active=='全部说说'){%>class = "active" <%}%> ><a href="/">全部说说</a></li>
                <li <%if(active=='我的说说'){%>class = "active" <%}%> >
                    <%if(login == '1'){%>
                    <a href="/user/<%=username%>">我的说说</a>
                    <%}else{%>
                    <a href="/">我的说说</a>
                    <%}%>
                </li>
                <li <%if(active=='成员列表'){%>class = "active" <%}%> ><a href="/userlist">成员列表</a></li>
            </ul>
            <ul class="nav navbar-nav pull-right">

                <%if(login != null &&  login=='-1'){%>
                <li><a href="/regist">注册</a></li>
                <li><a href="/login">登录</a></li>
                <%}else if(login == '1'){%>
                <li><a href="javascript:void(0);">欢迎,<%=username%></a></li>
                <li><a href="/avatar">设置个人资料</a></li>
                <%}else if(login == '-2'){%>
                <li class="active"><a href="javascript:void(0);">注册</a></li>
                <li><a href="/login">登录</a></li>
                <%}else if(login == '-3'){%>
                <li><a href="/regist">注册</a></li>
                <li class="active"><a href="javascript:void(0);" >登录</a></li>
                <%}%>
            </ul>
        </div><!--/.nav-collapse -->
    </div>
</nav>

index.ejs

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../favicon.ico">
    <title>班级说说</title>
    <!-- Bootstrap core CSS -->
    <link href="/bootstrap/css/bootstrap.css" rel="stylesheet">
    <link rel="stylesheet" href="/toptip/toptip.css">
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
    <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>

<body>
       <!--头部-->
       <%include head.ejs%>
<div style="background:#eee;">
    <div class="container theme-showcase" role="main">
            <div class="row" style="padding-top:100px;padding-bottom:20px;">
                <%if(login=="1"){%>
                    <div class="media">
                        <div class="media-left">
                            <a href="#">
                                <img class="media-object" src="/<%=avatar%>" alt="..." style="width:150px;">
                            </a>
                        </div>
                        <div class="media-body">
                            <h4 class="media-heading username"><%=username%></h4>
                            <textarea   style="display:block;width:500px;height:90px;"></textarea>
                            <botton id="bottonText" class="btn btn-default" >发表说说</botton>
                        </div>
                    </div>
                <%}else{%>
                    <div class="col-md-6">
                            <h3 style="font-weight:700;">班级动态</h3>
                            <p class="lead">欢迎积极发表说说动态</p>
                            <p><a class="btn btn-lg btn-success" href="#" role="button">注册</a></p>
                    </div>
                    <div class="col-md-6">
                        <form enctype="multipart/form-data" id="formId">
                            <div class="form-group">
                                <label for="username">用户名</label>
                                <input type="text" class="form-control" id="username"  placeholder="请输入用户名" name="username">
                            </div>
                            <div class="form-group">
                                <label for="password">密码</label>
                                <input type="password" class="form-control"  placeholder="请输入密码" name="password" id="password">
                            </div>
                            <div class="checkbox">
                                <label>
                                    <input type="checkbox"> 记住密码
                                </label>
                            </div>
                            <p  class="btn btn-default psubmit">提交<p/>
                        </form>
                    </div>
                <%}%>
            </div>
    </div> <!-- /container -->
</div>
<div>
    <div class="container" style="padding-top:20px;" id="contentId">


    </div>
</div>
<div>
    <div class="container" style="height:100px;">
        <footer class="footer" style="position:fixed;bottom:20px;">
            <p>© 2018 Company, Inc.</p>
        </footer>
    </div>
</div>

<script src="/bootstrap/js/bootstrap.js"></script>
<script src="/bootstrap/js/jquery-1.11.3.js"></script>
<script src="/toptip/toptip.js"></script>
</body>
</html>

<script>
    var tip = tipAlert();
    //tip("这是一个提示");

        //添加说说
        $('.theme-showcase').on('click','#bottonText',function(){
           if(!$('textarea').val()){
               tip('发表内容不能为空');
               return;
           }
           $.post('/addPost',{content:$('textarea').val(),username:$('.username').html()},function(data){
               if(data == "-2"){
                   tip("error");
               }else if(data == "-1"){
                   window.location.href = "/";
               }else{
                   getPage();
               }
           })
        })

        //注册
        var psubmit = document.querySelector(".theme-showcase");
        psubmit.onclick = function(event){
            var event = event || window.event;
            if(event.target.className.indexOf("psubmit") != -1){
                if(!$('#username').val() || !$('#password').val()){
                    tip("用户名密码不能为空");
                }
                $.ajax({type:"post",url:"/doLogin",data:$("#formId").serialize(),success:function(result){
                    if(result == "-1"){
                        tip("登录失败")
                    }else if(result == "-2"){
                        tip("用户名不存在");
                    }else if(result == "-3"){
                        tip("用户名密码不匹配");
                    }else{
                        tip("登录成功");
                        window.location.href = "/";
                    }
                }})
            }

        }

        //加载说说
        function AllPosts(objId,pageSize){
            this.totalPage = 0;
            this.currentPage = 1;
            this.list = [];
            this.config = {
                obj:$("#"+objId),
                pageSize:pageSize
            }
        }
        AllPosts.prototype = {
            //拼接数据
            clientPage : function(currentPage){
                var this_ = this;
                 if(!!currentPage){
                     this_.currentPage = currentPage;
                 }
                 this.serverPage(function(){
                      var str = "";
                      var count = 0;
                      for(var i = 0; i < this_.list.length; i++){
                          if(count == 0){
                              str += '<div class="row" style="padding-top:20px;">';
                          }

                          str += '<div class="col-md-4">'
                              +'<div class="media">'
                              +'<div class="media-left">'
                              +'<a href="/user/'+this_.list[i].username+'">'
                              +'<img class="media-object img-circle" style="width:100px;" src="'+this_.list[i].avatar+'" alt="...">'
                              +'</a>'
                              +'</div>'
                              +'<div class="media-body">'
                              +'<h4 class="media-heading">'+this_.list[i].username+'</h4>'
                              + this_.list[i].content
                              +'</div>'
                              +'</div>'
                              +'</div>';
                          if(count == 2){
                              str += '</div>';
                          }
                          count ++;
                          if(count == 3){
                              count = 0;
                          }
                      }

                      str += '<nav aria-label="Page navigation">'
                            +'<ul class="pagination">';
                      if(this_.currentPage > 1){
                          str += '<li>'
                                +'<a href="javascript:getPage('+(this_.currentPage-1)+');" aria-label="Previous">'
                                +'<span aria-hidden="true">«</span>'
                                +'</a>'
                                +'</li>';
                      }
                      var startnum = (this_.currentPage-2)>1?this_.currentPage:1;
                      var endnum = (this_.currentPage + 2 <= this_.totalPage)?this_.currentPage + 2:this_.totalPage;
                      for(var i = startnum ; i <= endnum ; i++ ){
                          if(i == this_.currentPage){
                              str += '<li class="active"><a href="javascript:void(0);">'+i+'</a></li>';
                          }else{
                              str += '<li><a href="javascript:getPage('+i+');">'+i+'</a></li>'
                          }
                      }
                     if(this_.currentPage < this_.totalPage){
                         str += '<li>'
                             +'<a href="javascript:getPage('+(this_.currentPage+1)+');" aria-label="Previous">'
                             +'<span aria-hidden="true">»</span>'
                             +'</a>'
                             +'</li>';
                     }
                     str += ' </ul></nav>';
                      this_.config.obj.html(str);
                 })
            },
            //请求数据
            serverPage : function(fn){
                var this_ = this;
                $.get("/AllPosts",{currentPage:this_.currentPage,pageSize:this_.config.pageSize},function(data){
                    this_.totalPage = data.totalPage;
                    this_.list = data.list;
                    this_.currentPage = data.currentPage;
                    //请求数据后进行拼接
                    fn&&fn();
                })
            }
        }
        var AllPosts = new AllPosts('contentId',3);
        var getPage = function(currentPage){
            AllPosts.clientPage(currentPage)
        }
        getPage();
</script>

login.ejs

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../favicon.ico">

    <title>Theme Template for Bootstrap</title>

    <!-- Bootstrap core CSS -->
    <link href="/bootstrap/css/bootstrap.css" rel="stylesheet">
    <link rel="stylesheet" href="/toptip/toptip.css">
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
    <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>

<body>
<!--头部-->
<%include head.ejs%>
<div class="container theme-showcase" role="main">
    <div class="jumbotron">
        <div class="media" style="margin-top:40px;">
            <form enctype="multipart/form-data" id="formId">
                <div class="form-group">
                    <label for="username">用户名</label>
                    <input type="text" class="form-control" id="username"  placeholder="请输入用户名" name="username">
                </div>
                <div class="form-group">
                    <label for="password">密码</label>
                    <input type="password" class="form-control"  placeholder="请输入密码" name="password" id="password">
                </div>
                <div class="checkbox">
                    <label>
                        <input type="checkbox"> 记住密码
                    </label>
                </div>
                <p  class="btn btn-default psubmit">提交<p/>
            </form>
        </div>
    </div>

</div> <!-- /container -->
<script src="/bootstrap/js/bootstrap.js"></script>
<script src="/bootstrap/js/jquery-1.11.3.js"></script>
<script src="/toptip/toptip.js"></script>
<script>
    var tip = tipAlert();
    //tip("这是一个提示");
    var psubmit = document.querySelector(".psubmit");
    psubmit.onclick = function(){
        if(!$('#username').val() || !$('#password').val()){
            tip("用户名密码不能为空");
        }
        $.ajax({type:"post",url:"/doLogin",data:$("#formId").serialize(),success:function(result){
            if(result == "-1"){
                tip("登录失败")
            }else if(result == "-2"){
                tip("用户名不存在");
            }else if(result == "-3"){
                tip("用户名密码不匹配");
            }else{
                tip("登录成功");
                window.location.href = "/";
            }
        }})
    }
    /*psubmit.addEventListener("click",function(){
     console.log(1);
     $.ajax({type:"post",url:"/doregist",data:$("#formId").serialize(),success:function(result){
     if(result == "-1"){
     tip("注册失败")
     }else if(result == "-2"){
     tip("用户名已被占用");
     }else{
     tip("注册成功");
     }
     }})
     })*/
</script>
</body>
</html>

regist.ejs

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../favicon.ico">

    <title>Theme Template for Bootstrap</title>

    <!-- Bootstrap core CSS -->
    <link href="/bootstrap/css/bootstrap.css" rel="stylesheet">
    <link rel="stylesheet" href="/toptip/toptip.css">
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
    <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>

<body>
<!--头部-->
<%include head.ejs%>
<div class="container theme-showcase" role="main">
    <div class="jumbotron">
        <div class="media" style="margin-top:40px;">
            <form enctype="multipart/form-data" id="formId">
                <div class="form-group">
                    <label for="username">用户名</label>
                    <input type="text" class="form-control" id="username"  placeholder="请输入用户名" name="username">
                </div>
                <div class="form-group">
                    <label for="password">密码</label>
                    <input type="password" class="form-control"  placeholder="请输入密码" name="password" id="password">
                </div>
                <!--<div class="form-group">
                    <label for="exampleInputFile">头像</label>
                    <input type="file" id="exampleInputFile">
                </div>-->
                <p  class="btn btn-default psubmit">提交<p/>
            </form>
        </div>
    </div>

</div> <!-- /container -->
<script src="/bootstrap/js/bootstrap.js"></script>
<script src="/bootstrap/js/jquery-1.11.3.js"></script>
<script src="/toptip/toptip.js"></script>
<script>
    var tip = tipAlert();
    //tip("这是一个提示");
    var psubmit = document.querySelector(".psubmit");
    psubmit.onclick = function(){
        if(!$('#username').val() || !$('#password').val()){
            tip("用户名密码不能为空");
        }
        $.ajax({type:"post",url:"/doRegist",data:$("#formId").serialize(),success:function(result){
            if(result == "-1"){
                tip("注册失败")
            }else if(result == "-2"){
                tip("用户名已被占用");
            }else{
                tip("注册成功");
                window.location.href = "/";
            }
        }})
    }
    /*psubmit.addEventListener("click",function(){
        console.log(1);
        $.ajax({type:"post",url:"/doregist",data:$("#formId").serialize(),success:function(result){
              if(result == "-1"){
                  tip("注册失败")
              }else if(result == "-2"){
                  tip("用户名已被占用");
              }else{
                  tip("注册成功");
              }
        }})
    })*/
</script>
</body>
</html>

user.ejs

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../favicon.ico">
    <title>班级说说</title>
    <!-- Bootstrap core CSS -->
    <link href="/bootstrap/css/bootstrap.css" rel="stylesheet">
    <link rel="stylesheet" href="/toptip/toptip.css">
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
    <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>

<body>
<!--头部-->
<%include head.ejs%>
<div >
    <div class="container theme-showcase" role="main">
        <div class="row" style="padding-top:100px;padding-bottom:20px;">
            <%for(var i = 0 ; i < userposts.length ; i++){%>
            <div class="col-md-4">
                <div class="media" style="border-bottom:1px dashed #ccc;padding-bottom:5px;">
                    <div class="media-left">
                        <a href="#">
                            <img class="media-object" src="/<%=userposts[i].avatar%>" alt="..." style="width:90px;border-radius:45px/45px;">
                        </a>
                    </div>
                    <div class="media-body">
                        <h4 class="media-heading username"><%=userposts[i].username%></h4>
                        <%=userposts[i].content%>
                    </div>
                </div>
            </div>
            <%}%>
        </div>
    </div> <!-- /container -->
</div>

<div>
    <div class="container" style="height:100px;">
        <footer class="footer" style="position:fixed;bottom:20px;">
            <p>© 2018 Company, Inc.</p>
        </footer>
    </div>
</div>

<script src="/bootstrap/js/bootstrap.js"></script>
<script src="/bootstrap/js/jquery-1.11.3.js"></script>
<script src="/toptip/toptip.js"></script>
</body>
</html>

<script>
</script>

userlist.ejs

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../favicon.ico">
    <title>班级说说</title>
    <!-- Bootstrap core CSS -->
    <link href="/bootstrap/css/bootstrap.css" rel="stylesheet">
    <link rel="stylesheet" href="/toptip/toptip.css">
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
    <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>

<body>
<!--头部-->
<%include head.ejs%>
<div >
    <div class="container theme-showcase" role="main">
        <div class="row" style="padding-top:100px;padding-bottom:20px;">
            <%for(var i = 0 ; i < users.length ; i++){%>
            <div class="media" style="border-bottom:1px dashed #ccc;padding-bottom:5px;">
                <div class="media-left">
                    <a href="#">
                        <img class="media-object" src="/<%=users[i].avatar%>" alt="..." style="width:90px;border-radius:45px/45px;">
                    </a>
                </div>
                <div class="media-body">
                    <h4 class="media-heading username"><%=users[i].username%></h4>
                </div>
            </div>
            <%}%>
        </div>
    </div> <!-- /container -->
</div>

<div>
    <div class="container" style="height:100px;">
        <footer class="footer" style="position:fixed;bottom:20px;">
            <p>© 2018 Company, Inc.</p>
        </footer>
    </div>
</div>

<script src="/bootstrap/js/bootstrap.js"></script>
<script src="/bootstrap/js/jquery-1.11.3.js"></script>
<script src="/toptip/toptip.js"></script>
</body>
</html>

app.js

/**
 * Created by prettyRain on 2018/12/10.
 */

var express = require('express');
var app = express();
var session = require('express-session');
var cookie = require('cookie-parser');
var router = require('./router/router.js');

//加载静态文件
app.use(express.static('./public'));
app.use(express.static('./avatar'));
//ejs模板
app.set("view engine",'ejs');

app.use(session({
    secret: '12345',
    name: 'testapp',   //这里的name值得是cookie的name,默认cookie的name是:connect.sid
    cookie: {maxAge: 800000 },  //设置maxAge是80000ms,即80s后session和相应的cookie失效过期
    resave: false,
    saveUninitialized: true
}));

//路由
app.get('/',router.showIndex);
//注册
app.get('/regist',router.showRegist);
app.post('/doRegist',router.doRegist);
//登录
app.get('/login',router.showLogin);
app.post('/doLogin',router.doLogin);

app.get('/avatar',router.showAvatar);
app.post('/doAvatar',router.doAvatar);
app.post('/setAvatar',router.setAvatar);

//添加说说
app.post("/addPost",router.addPost);
app.get("/AllPosts",router.AllPosts);
//成员列表
app.get("/userlist",router.userlist);
app.get("/user/:username",router.user);
app.listen(3000);

settings.js

/**
 * Created by prettyRain on 2018/12/10.
 */

module.exports = {
    "dburl" : "mongodb://localhost:27017",
    "dbname" : "shuoshuo"
}

首页样式:



注册登录样式:


image.png
修改个人资料页面:
image.png

我的说说页面:


image.png
成员列表:
image.png

相关文章

网友评论

      本文标题:nodejs mongo博客说说小项目

      本文链接:https://www.haomeiwen.com/subject/darzlqtx.html