一、前台新闻列表
创建路由文件frnews.js 和 控制器文件frNewController.js(写业务代码)
frnews.js
const express = require('express');
const router = express.Router(); // 路由器
const FrNewsController = require('../controllers/frNewController.js');
/* 在这个文件里面定义前台相关的新闻模块的路由信息*/
// 1. 新闻的列表
router.get("/news",FrNewsController.getNewsList);
module.exports = router;
frNewController.js
const categoryModel = require('../models/category.js');
const newsModel = require('../models/news.js');
const moment = require('moment');
const pagination = require('pagination');
class FrNewController {
static getNewsList = async (req, res) => {
/*返回前台的新闻的信息*/
/*1. 新闻的分类信息*/
const categoryInfo = await categoryModel.find();
/*2. 获取 企业新闻 的列表信息*/
let qyCateId = '6121251c47ccef14ec971818'; // cateId 是前台用户点击跳转链接传递的
let cateId = req.query.cateId ? req.query.cateId : qyCateId;
const infos = await newsModel.find({cateId});
/* 3. 生成分页字符串*/
const paginator = pagination.create('search', {
prelink: '/front/news',
current: 1,
rowsPerPage: 10,
totalResult: 120
});
let pageHtml = paginator.render();
res.render('front/news', {title: '新闻列表页', categoryInfo, infos, cateId, moment, pageHtml});
}
}
front/news.html
<ul class="tabs">
<!--由于我们要获取各个分类下的新闻列表,则我们在遍历分类信息的时候,应该增加一个跳转链接-->
{{ each categoryInfo }}
<li class="{{ $value._id.toString() == cateId ? 'active': ''}}"><a
href="/front/news?cateId={{@ $value._id }}" target="_blank">{{ $value.cateName }}</a></li>
{{ /each }}
</ul>
<ul class="list">
{{ each infos }}
<li>
<div class="l"><img src="/uploads/{{ $value.cover }}" alt=""></div>
<div class="r">
<h2>{{ $value.title }}</h2>
<p class="titile">{{ moment( $value.createdAt ).format('YYYY-MM-DD') }}</p>
<p>{{ $value.markup }}</p>
<a href="/front/detail/{{@$value._id}}">查看详情+</a>
</div>
</li>
{{ /each }}
</ul>
npmjs库-pagination
实现分页
npm i pagination
const pagination = require('pagination');
const paginator = pagination.create('search', {
prelink: '/front/news',
current: 1,
rowsPerPage: 10,
totalResult: 120
});
let pageHtml = paginator.render();
res.render('front/news', {title: '新闻列表页', categoryInfo, infos, cateId, moment, pageHtml});
html
{{@ pageHtml }}
http://localhost:3000/front/news
二、前台新闻详情页
路由/frnews.js
// 2. 新闻的详情 /* 4. 获取新闻的评论列表*/
router.get("/detail/:newsId",FrNewsController.detail);
frNewController.js
方法增加
static detail = async (req, res) => {
let newsId = req.params.newsId;
let info = await newsModel.findOne({_id: newsId});
// res.json(info);
res.render('front/detail', {title: '新闻详情', info, moment});
}
用户每查看一次新闻的详情,对应的 viewcount 应该+1
static detail = async (req, res) => {
/* 用户每查看一次新闻的详情,对应的 viewcount 应该+1*/
/* 获取新闻的评论信息 */
let newsId = req.params.newsId;
newsModel.findOne({_id: newsId}, async (error, doc) => {
if (error) {
res.render('error', {title: '错误信息', time: 3, url: 'front/news', errorRs: [error]});
} else {
//console.log(doc);
doc.viewcount += 1;
await doc.save();
res.render('front/detail', {title: '新闻详情', info: doc, moment});
}
});
}
三、新闻详情评论显示
详情页面
<form action="/front/comment" method="post" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="newsId" value="{{@ info._id }}">
<textarea class="form-control" id="content" name="content"></textarea>
<button type="submit" class="btn btn-success btn-lg btn-block">发布</button>
</form>
前台页面是不需要登录的 评论新建数据库 models/comment.js
const mongoose = require('../db/mongodb.js');
const Schema = mongoose.Schema({
username: {
type: String,
default: '',//不是必须的可以为空
minlength: [2, '评论人的最小长度为10个字符'], // 最小长度
maxlength: [30, '评论人的最大长度为30个字符'], // 最大长度
},
content: {
type: String,
required: [true, '新闻内容不能为空'], // 定义验证规则,这个字段不能为空,必填的
minlength: [2, '新闻内容的最小长度为10个字符'],
maxlength: [300, '新闻内容的最大长度为30个字符'],
},
newsId: {
type: mongoose.Types.ObjectId,
required: [true, '新闻id不能为空'],
},
addTime: {
type: Number, // Date.now() 当前的时间戳,单位是毫秒
default: Date.now(), // 我们在存储记录的创建时间的时候,除了常见的时间格式字符串 。 2021年8月23日09:24:26 还可以存储另外的一种格式,这种我们称之为:时间戳,代表的是 1970年的零点(Unix元年)开始到现在的秒数,或者是毫秒数。 https://tool.lu/timestamp/
}
}, {timestamps: true}); // Schema 的第二个参数是对象,如果传递 timestamps 自动的表里面增加 create_at 和 update_at 字段,代表的记录的添加时间和修改时间,会自行的维护。
const Model = mongoose.model('Comment', Schema, 'comments');
Model.fields = {
username: '评论人',
content: '评论内容',
newsId: '新闻id',
};
module.exports = Model;
路由/frnews.js
// 3. 新闻的评论功能
router.post('/comment', FrNewsController.addComment);
frNewController.js
方法增加
const commentModel = require('../models/comment.js');
const randomstring = require("randomstring");
static addComment = async (req, res) => {
/*收集评论信息*/
let newsId = req.body.newsId;
let content = req.body.content;
let username = '用户 ' + randomstring.generate(7);
/* 入库 */
const commentObj = new commentModel({content, newsId, username});
try {
let info = await commentObj.save();
// res.json(info);
} catch (e) {
// res.json(e);
}
res.redirect('back');
}
因为评论列表需要展示所以要在第二个方法里面放入评论信息
修改部分代码
修改为:
doc.viewcount += 1;
await doc.save();
const commentInfo = await commentModel.find({newsId});
res.render('front/detail', {title: '新闻详情', info: doc, moment, commentInfo});
如果想要评论时间显示为中文,可以去moment.js中文网找到对应模块引入
npm install moment
- 在控制文档上面引入 moment.locale(‘zh_Cn’);
<p class="time">{{ moment($value.addTime).format('lll')}}</p>
四、公司地图展示
关于公司的位置的地图,我们一般使用 第三方公司提供的功能完成。例如:百度的地图名片 高德地图的名片 腾讯地图的名片
百度的地图名片
http://api.map.baidu.com/mapCard/setInformation.html
可以自己输入对应的地址
点击提交生成图片和代码:
代码复制放入需要放置的地方:
<iframe width="504" height="771" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://j.map.baidu.com/s/cfSHFb"></iframe>
这样就能看到了