项目文件:
app.js文件
配置服务器,搭建服务器,启动服务器。(输入命令node app.js,即可运行网站)
router.js文件
处理所有业务,渲染前端页面,处理前端请求
mysql.js文件
配置数据库,连接数据库
package.json文件
记录本项目的所有依赖项,记录本项目的详细信息
github:https://github.com/YvhuiWang/Front-end-design
功能一:登录注册(两个前端风格一样)
登录界面前端(背景是个gif图片):
注册界面:
前端代码 login.html
<body style="background-image: url(../public/img/login_back.gif);
background-repeat: no-repeat;
background-size:700px 600px;
background-color: black;
background-position: center">
<p class="welcome_login" style="color:white">登录</p>
<div class="main">
<form>
<p><input type="text" name="username" class="username" placeholder="请输入账号,至少3位" maxlength="1000" style="color:white; background-color:transparent"></p>
<p><input type="password" name="password" class="password" placeholder="请输入密码,至少3位" maxlength="10" style="color:white; background-color:transparent"></p>
<button class="btn" style="color:white">登录</button>
</form>
</div>
<p class="register_p" >
<a href="/register" ><span style="color:whitesmoke">没 有 账 号 ,马 上 注 册</span></a>
</p>
<script src="../public/js/host.js"></script>
<script src="../node_modules/jquery/dist/jquery.js"></script>
<script src="../public/js/login.js"></script>
</body>
前端代码 login.js 中的点击事件:
let dataObj = {
username:username_val,
password:password_val
}
// 发送请求
$.ajax({
data:dataObj,
type:"post",
dataType:"json",
url:`/login`,
success:function(res){
if (res.code == 500) {
alert("登录失败")
}else{
window.location.href = `${host}`
}
}
})
后端响应登录事件 route.js:
// 处理登录请求
router.post("/login", (req, res) => {
let meobj = req.body
let sql = `select * from user where username="${meobj.username}" and password="${meobj.password}" `
mysqlquery(sql, (err, data) => {
// 如果没有。登录失败
if (data.length == 0) {
res.send({ code: 500 })
} else {
// 如果存在。登录成功
// 日志函数
logFN(meobj.username, "登录")
// 设置session状态
req.session.online = meobj.username
// 响应前端
res.send({ code: 200 })
}
})
})
后端响应注册事件 route.js:
// 处理注册请求
router.post("/register", (req, res) => {
let meobj = req.body
// 查询数据库。如果没有,可以注册。如果已有,不可注册。
let sql = `select * from user where username="${meobj.username}"`
mysqlquery(sql, (err, data) => {
// 如果已有,不可注册。
if (data.length != 0) {
res.send({ code: 500 })
} else {
// 如果没有,可以注册。
let sql = `insert into user (username,password) values ("${meobj.username}","${meobj.password}") `
// 日志函数
logFN(meobj.username, "注册")
// 插入用户
mysqlquery(sql, (err) => {
// 响应前端
res.send({ code: 200 })
})
}
})
})
功能二:功能主页
简单的前端代码:
<body style="background-image: url(../public/img/show_back.gif);
background-repeat: no-repeat;
background-size:cover;
background-position: center">
<div class="header">
数 据 展 示
</div>
<div class="main">
<a href="/show">数据显示</a>
<a href="/statistics">分析统计</a>
<a href="/log">详情日志</a>
</div>
</body>
功能三:新闻的展示和查询(AND OR布尔查询)
AND查询:
前端代码:
<body style="background-image: url(../public/img/timg.jpg);
background-repeat: no-repeat;
background-size:700px 250px;
background-color: white;
background-position: right top">
<a href="/" id="indexa" style="background-color: white;"><span style="color:#00FFFF">返回主页</span></a>
<h1>爬虫数据</h1>
<!-- 查询区域 -->
<div class="controlbox">
<input type="text" class="cha1" placeholder="请输入标题">
<select class="cha2">
<option value="none">默认查询</option>
<option value="and">AND</option>
<option value="or">OR</option>
</select>
<input type="text" class="cha3" style="display: none;" placeholder="请输入标题">
<select class="cha4">
<!-- 默认排序为升序排序 -->
<option value="asc">默认排序</option>
<option value="asc">升序</option>
<option value="desc">降序</option>
</select>
<p class="chabtn" style="background-color: #00FFFF;">
<span class="glyphicon glyphicon-search"></span>
</p>
</div>
<!-- 显示区域 -->
<div class="showbox">
<table class="showbox_table">
</table>
</div>
<!-- 分页区域 -->
<div class="pagebox">
<span class="prevbtn">上一页</span>
<span class="nowpage">1</span>
<span class="nextbtn">下一页</span>
</div>
<script src="../public/js/host.js"></script>
<script src="../node_modules/jquery/dist/jquery.js"></script>
<script src="../public/js/show.js"></script>
</body>
Js向后端传输request信号:
// 发送请求-分页-无条件
$.ajax({
data: { page: window.nowPage, num: window.showNum },
type: "post",
dataType: "json",
url: `${host}/showalllimit`,
success: function (res) {
// 数据数组
let arr = res.data
// 调用函数,渲染数据
showData(arr)
}
})
翻页:
- 主要就是记录window的nowPage,初始化为1,翻页会改变,根据nowpage这个变量来申请访问不同的数据库的数据
- 判断当前的查询是否是有条件的? 如果无条件,发送showalllimit函数请求;
如果有条件(例如AND查询),发送showwhere函数请求;
// 上一页按钮
$(".prevbtn").on("click", function (e) {
if (window.nowPage <= 1) {
window.nowPage = 1
} else {
window.nowPage -= 1
}
$(".nowpage").html(window.nowPage)
// 无条件分页
if (window.meObj == null) {
// 发送请求-分页-无条件
$.ajax({
data: { page: window.nowPage, num: window.showNum },
type: "post",
dataType: "json",
url: `${host}/showalllimit`,
success: function (res) {
// 数据数组
let arr = res.data
// 调用函数,渲染数据
showData(arr)
}
})
} else {
// 有条件分页
// 使用最新页数
window.meObj.page = window.nowPage
$.ajax({
data: window.meObj,
type: "post",
dataType: "json",
url: `${host}/showwhere`,
success: function (res) {
console.log(res)
let arr = res.data
// 调用函数,渲染内容
showData(arr)
}
})
}
})
后端实现(主要就是如何访问数据库的新闻数据):
注意此处后端必须精确获取翻页后的那几条数据,所以使用limit ${start},${end}
// 处理showalllimit请求
router.post("/showalllimit", (req, res) => {
let meobj = req.body
let page = meobj.page
let num = meobj.num
let start = num * (page - 1)
let end = num
let sql = ` select * from sina limit ${start},${end} `
mysqlquery(sql, (err, data) => {
// 日志函数
logFN(req.session.online, "普通查询")
res.send({ code: 200, data: data })
})
})
后端实现(主要就是如何使用布尔查询AND OR访问数据库的新闻数据):
核心就在于,使用AND OR 逻辑查询词
// 处理showwhere请求
router.post("/showwhere", (req, res) => {
let meobj = req.body
let page = meobj.page
let num = meobj.num
let start = num * (page - 1)
let end = num
let sql = "select * from sina";
if (meobj.cha2_val == "none") {
sql = `select * from sina where title like "%${meobj.cha1_val}%" order by id ${meobj.cha4_val} limit ${start},${end} `
} else {
// sql = `select * from sina where source="${meobj.cha1_val}" ${meobj.cha2_val} title="${meobj.cha3_val}" order by id ${meobj.cha4_val} limit ${start},${end} `
sql = `select * from sina where title like "%${meobj.cha1_val}%" ${meobj.cha2_val} title like "%${meobj.cha3_val}%" order by id ${meobj.cha4_val} limit ${start},${end} `
}
// console.log(sql)
mysqlquery(sql, (err, data) => {
// 日志函数
logFN(req.session.online, "条件查询")
res.send({ code: 200, data: data })
})
})
功能三:日志显示
后端实现:
在route.js中,设置了logFN函数,每次需要和数据库交互的时候(登录、注册、查询等等),都会来使用这个函数,实现日志记录的插入:
// 封装日志函数
function logFN(username, info) {
let sql=` insert into log (username,info,time) values ("${username}","${info}","${new Date().toLocaleString()}") `
mysqlquery(sql, (err) => {
// console.log("插入日志成功")
})
}
日志查询:
// 处理loglimit请求
router.post("/loglimit", (req, res) => {
let meobj = req.body
let page = meobj.page
let num = meobj.num
let start = num * (page - 1)
let end = num
let sql = `select * from log order by id desc limit ${start},${end}`
mysqlquery(sql, (err, data) => {
// 查看日志的操作。不需要记录到日志数据库中。
res.send({ code: 200, data: data })
})
})
功能四:数据分析(Echarts图表)
图表一:体育明星新闻个数
前端部分代码:
sourceData = [{'name': '霍华德', 'value': 14, 'extData': [obj.arr1[0]["count(*)"], '#DFFFDF', 0, '']},
{'name': '尼尔森', 'value': 14, 'extData': [obj.arr2[0]["count(*)"], '#93FF93', 0, '']},
{'name': '詹姆斯', 'value': 20, 'extData': [obj.arr3[0]["count(*)"], '#7AFEC6', 0, '']},
{'name': '科比', 'value': 22, 'extData': [obj.arr4[0]["count(*)"], '#1AFD9C', 0, '']},
{'name': '格林', 'value': 30, 'extData': [obj.arr5[0]["count(*)"], '#4DFFFF', 0, '']},
{'name': '维金斯', 'value': 45, 'extData': [obj.arr6[0]["count(*)"], '#00E3E3', 0, '']},
{'name': '汤神', 'value': 50, 'extData': [obj.arr7[0]["count(*)"], '#2894FF', 0, '']},
{'name': '杜兰特', 'value': 57, 'extData': [obj.arr8[0]["count(*)"], '#0072E3', 0, '']},
{'name': '拉塞尔', 'value': 60, 'extData': [obj.arr9[0]["count(*)"], '#4A4AFF', 0, '']},
{'name': '库里', 'value': 100, 'extData': [obj.arr10[0]["count(*)"], '#0000C6', 0, '']}]
/*中间有一部分风格代码,错位饼状图,代码有点长,可以看博客*/
option = {
title: {
text: '体育明星新闻个数',
left: 'center',
textStyle: {
fontSize: 40
},
top: "2%"
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
toolbox: {
show: true,
feature: {
mark: {
show: true
},
dataView: {
show: true,
readOnly: false
},
magicType: {
show: true,
type: ['pie', 'funnel']
},
restore: {
show: true
},
saveAsImage: {
show: true
}
}
},
graphic: graphicData,
series: [{
name: '新闻个数',
type: 'pie',
radius: [20, 450],
center: ['50%', '60%'],
label: {
show: true
},
roseType: 'area',
data: convertData1(),
rich: {
a: {
color: 'white',
lineHeight: 10
},
b: {
backgroundColor: {
image: 'xxx/xxx.jpg'
},
height: 40
},
x: {
fontSize: 18,
fontFamily: 'Microsoft YaHei',
borderColor: '#449933',
borderRadius: 4
}
}
}]
};
// 使用图表规则
MyEcharts3.setOption(option)
/***************图表区域******************/
后端操作:
// 专题语句
let about_sql1 = ` select count(*) from sina where title like "%霍华德%" `
let about_sql2 = ` select count(*) from sina where title like "%尼尔森%" `
let about_sql3 = ` select count(*) from sina where title like "%詹姆斯%" `
let about_sql4 = ` select count(*) from sina where title like "%科比%" `
let about_sql5 = ` select count(*) from sina where title like "%格林%" `
let about_sql6 = ` select count(*) from sina where title like "%维金斯%" `
let about_sql7 = ` select count(*) from sina where title like "%汤神%" `
let about_sql8 = ` select count(*) from sina where title like "%杜兰特%" `
let about_sql9 = ` select count(*) from sina where title like "%拉塞尔%" `
let about_sql10 =` select count(*) from sina where title like "%库里%" `
// 专题语句
let about_obj = {}
// 封装函数。异步函数。处理Promise实例对象
async function mefn_handle3(res) {
about_obj.arr1 = await mefn(about_sql1)
about_obj.arr2 = await mefn(about_sql2)
about_obj.arr3 = await mefn(about_sql3)
about_obj.arr4 = await mefn(about_sql4)
about_obj.arr5 = await mefn(about_sql5)
about_obj.arr6 = await mefn(about_sql6)
about_obj.arr7 = await mefn(about_sql7)
about_obj.arr8 = await mefn(about_sql8)
about_obj.arr9 = await mefn(about_sql9)
about_obj.arr10 = await mefn(about_sql10)
// 响应前端
res.send({ code: 200, data: about_obj })
}
// 处理statisticsme3图3请求
router.post("/statisticsme3", (req, res) => {
// 调用异步函数
mefn_handle3(res)
})
图表二:各大新闻媒体新闻个数(基于爬虫的数据)
后端:
// 资源语句
let source_sql1 = 'select count(*) from sina where source="新浪网体育" '
let source_sql2 = 'select count(*) from sina where source="网易新闻" '
let source_sql3 = 'select count(*) from sina where source="网易体育" '
// 资源对象
let source_obj = {}
// 封装函数。异步函数。处理Promise实例对象
async function mefn_handle1(res) {
source_obj.arr1 = await mefn(source_sql1)
source_obj.arr2 = await mefn(source_sql2)
source_obj.arr3 = await mefn(source_sql3)
// 响应前端
res.send({ code: 200, data: source_obj })
}
// 处理statisticsme1图1请求
router.post("/statisticsme1", (req, res) => {
mefn_handle1(res)
})