当前位置: 首页 > 后端技术 > Node.js

博客后台管理DAY12

时间:2023-04-03 13:03:15 Node.js

(12)项目功能的实现:文章评论退出功能创建评论集,判断用户是否登录,如果用户登录,允许用户提交评论表单创建文章评论对应的路由服务器端函数,在路由请求处理函数中接收客户将评论信息存储在评论集合中,并将页面重定向回文章详情页获取文章详情页路由中的文章评论信息,并显示在页面BLOG中--源码目录└──config--配置文件└──中间件└──loginGuard.js└──模型--数据库操作└──comment.js├──public--静态资源└──路由--路由└──admin├──login.js登录└──logout.js登出└──主页├──article.js博文└──comment.js博客评论└──home.js博客└──views--templates└──home└──common└──header.artpublicheadertemplate└──article.art文章内容模板└──app.js--创建网站服务comment.js导入mongoose模块,创建collectionrules,添加存储每篇文章的辅助,并关联文章集合存储uid评论的用户名,关联用户集合存储评论时间,content时间content创建评论组合并导出为模块成员//导入评论集合构造函数const{Comment}=require('../../model/comment');module.exports=async(req,res)=>{//接收客户端传过来的请求参数const{content,uid,aid}=req.body;//将评论信息存储在评论集合中awaitComment.create({content:content,uid:uid,aid:援助,time:newDate()});//跳转回文章详情页res.redirect('/home/article?id='+aid);}login.js对用户进行权限管理,管理可以到后台,正常跳转到博客首页userinfo表示用户是否登录//import用户集合构造函数const{User}=require('../../model/user');constbcrypt=require('bcrypt');module.exports=async(req,res)=>{//接收请求参数const{email,password}=req.body;//如果用户没有输入电子邮件地址//if(email.trim().length==0||password.trim().length==0)returnres.status(400).send('

邮箱地址或密码错误

');if(email.trim().length==0||password.trim().length==0)returnres.status(400).render('admin/error',{msg:'电子邮件地址或密码是错的'});//根据邮箱查询用户信息//如果user变量的值是对象类型,则将用户信息存储在对象中//如果找不到user变量,则为空letuser=awaitUser.findOne({电子邮件});//查询用户if(user){//将客户端传递的密码与用户信息中的密码进行比较//比较成功则为true//比较失败则为falseletisValid=awaitbcrypt.比较(密码,用户。密码);//如果密码比较成功if(isValid){//登录成功//将用户名存储在请求对象中req.session.username=user.username;//将用户角色存储在会话对象中req.session.role=user.role;//res.send('登录成功');req.app.locals.userInfo=用户;//判断用户的角色if(user.role=='admin'){//重定向到用户列表页面res.redirect('/admin/user');}else{//重定向到博客首页res.redirect('/home/');}}else{//没有用户res.status(400).render('admin/error',{msg:'Emailaddressorpassworderror'})}}else{//没有找到用户res.status(400).render('admin/error',{msg:'电子邮件地址或密码错误'})}}loginGuard.js还在会话中存储用户角色。如果用户已登录,则会跳转到博客首页,这样就无法直接修改url了。constguard=(req,res,next)=>{//判断用户是否正在访问登录页面//判断用户的登录状态//如果用户已登录,则释放请求//如果用户未登录,请求将被重定向到登录页面if(req.url!='/login'&&!req.session.username){res.redirect('/admin/login');}else{//如果用户已经登录并且是普通用户if(req.session.role=='normal'){//让它跳转到博客首页并阻止程序执行returnres.redirect('/home/')}//用户已登录,请求将被释放next();}}module.exports=guard;article.art如果文章评论中的模板语法处于登录状态,则显示;如果没有,评论表单将被隐藏。在评论表单中添加请求地址action和请求方法method和name属性。valueaid,输出原文,循环动态输出审稿人信息,处理时间格式dateFormate{{extend'./common/layout.art'}}{{block'link'}}{{/block}}{{block'main'}}{{include'./common/header.art'}}{{文章标题}}</h3>{{article.author.username}}{{dateFormat(article.publishDate,'yyyy-mm-dd')}}
{{@article.content}}
{{ifuserInfo}}

评论

{{else}}

先登录,再评论文章

{{/if}}{{each评论}}{{$value.uid.username}}{{dateFormat($value.time,'yyyy-mm-dd')}}{{$value.uid.email}}{{$value.content}}{{/each}}div>{{/block}}logout.js清除用户userinfo,否则退出后只删除cookie和session,userinfo还在存在实现退出功能,删除session和cookieclearCookie(并重定向到用户登录页面module.exports=(req,res)=>{//删除sessionreq.session.destroy(function(){//删除cookieres.clearCookie('connect.sid');//重定向到用户登录页面res.redirect('/admin/login');//清除模板中的用户信息req.app.locals.userInfo=null;});}home.jsaddcommentsFunctionrouting//参考expess框架constexpress=require('express');//创建博客展示页面routeconsthome=express.Router();//展示页面博客首页home.get('/',require('./home/index'));//博客前端文章详情展示页home.get('/article',require('./home/article'));//创建评论功能路由home.post('/comment',require('./home/comment'));//导出路由对象作为模块成员评论集合导入函数,将评论信息存入评论集合,异步跳转回文章详情页//导入评论集合构造函数const{Comment}=require('../../model/评论');module.exports=async(req,res)=>{//接收客户端传过来的请求参数const{content,uid,aid}=req.body;//将评论信息存入评论集合awaitComment.create({content:content,uid:uid,aid:aid,time:newDate()});//将页面重定向回文章详情页面res.redirect('/home/article?id='+aid);}article.js引入评论集合构造函数查询当前文章对应的评论信息,用户名需要结合多集查询populate渲染文章和评论//Importarticlecollectionconstructorconst{Article}=require('../../model/article');//导入评论集合构造函数const{Comment}=require('../../model/comment');module.exports=async(req,res)=>{//接收客户端传过来的文章id值constid=req.query.id;//根据id查询文章的详细信息letarticle=awaitArticle.findOne({_id:id}).populate('作者');//查询当前文章对应的评论信息letcomments=awaitComment.find({aid:id}).populate('uid')//res.send('欢迎来到博客文章详情页')res.render('home/article.art',{article,comments});header.art为注销添加href黑马程序员ITHEIMA{{userInfo&&userInfo.username}}
  • 个人资料
  • 注销
  • app.js在用户未登录时不会初始化cookie,saveUninitialized:false为cookie设置自动过期时间//参考expess框架constexpress=require('express');//处理路径constpath=require('path');//导入body-parser模块处理post请求参数constbodyPaser=require('body-parser');//导入express-session模块constsession=require('express-session');//importart-tempate模板引擎consttemplate=require('art-template');//importdateformat第三方模块constdateFormat=require('dateformat');//importmorgan这前三-partymoduleconstmorgan=require('morgan');//导入配置模块constconfig=require('config');//创建web服务器constapp=express();//数据库连接require('./model/connect');//处理post请求参数app.use(bodyPaser.urlencoded({extended:false}));//配置sessionapp.use(session({secret:'secretkey',saveUninitialized:false,cookie:{最大年龄:24*60*60*1000}}));//Tellexpress框架模板所在位置app.set('views',path.join(__dirname,'views'));//告诉express框架模板默认后缀是什么app.set('viewengine','art');//渲染后缀为art的模板时使用的模板引擎是什么app.engine('art',require('express-art-template'));//导入dateFormate变量template模板。defaults.imports.dateFormat=dateFormat;//打开静态资源文件app.use(express.static(path.join(__dirname,'public')));console.log(config.get('title'))//获取系统环境变量返回值是一个对象if(process.env.NODE_ENV=='development'){//当前是开发环境console.log('当前是开发环境')//发送客户端到开发环境服务端请求信息打印到控制台app.use(morgan('dev'))}else{//当前生产环境console.log('当前生产环境')}//导入路由模块consthome=require('./route/home');constadmin=require('./route/admin');//拦截请求判断用户登录状态app.use('/admin',require('./middleware/loginGuard'));//为路由匹配请求路径app.use('/home',home);app.use('/admin',admin);app.use((err,req,res,next)=>{//将字符串对象转换为对象类型//JSON.parse()constresult=JSON.parse(err);//{path:'/admin/user-edit',message:'密码代码比对失败,用户信息不可修改',id:id}letparams=[];for(letattrinresult){if(attr!='path'){params.push(attr+'='+result[attr]);}}res.redirect(`${result.path}?${params.join('&')}`);})//监听端口app.listen(80);console.log('Web服务器启动成功,请访问localhost')