作业要求
前言
好家伙,这绝对又是一个艰巨的挑战,好不容易熬过第一个web大作业,现在又来第二个,(瘫)。不过还好,这一次老师给的实在是太多了,基本不需要怎么去调试,不过还是遇到了很多困难。
开始!
1.创建用户信息表
需要建立一个表格来对用户账户,密码,以及新闻数据进行存储
--之前的新闻数据表
CREATE TABLE `fetches` (
`id_fetches` int(11) NOT NULL AUTO_INCREMENT,
`url` varchar(200) DEFAULT NULL,
`source_name` varchar(200) DEFAULT NULL,
`source_encoding` varchar(45) DEFAULT NULL,
`title` varchar(200) DEFAULT NULL,
`keywords` varchar(200) DEFAULT NULL,
`author` varchar(200) DEFAULT NULL,
`publish_date` date DEFAULT NULL,
`crawltime` datetime DEFAULT NULL,
`content` longtext,
`createtime` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id_fetches`),
UNIQUE KEY `id_fetches_UNIQUE` (`id_fetches`),
UNIQUE KEY `url_UNIQUE` (`url`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--创建用户信息数据表
CREATE TABLE `crawl`.`user` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) NOT NULL,
`password` VARCHAR(45) NOT NULL,
`registertime` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `username_UNIQUE` (`username`))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
--记录用户的登陆,查询(具体查询语句)操作
CREATE TABLE `crawl`.`user_action` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) NOT NULL,
`request_time` VARCHAR(45) NOT NULL,
`request_method` VARCHAR(20) NOT NULL,
`request_url` VARCHAR(300) NOT NULL,
`status` int(4),
`remote_addr` VARCHAR(100) NOT NULL,
PRIMARY KEY (`id`))
ENGINE=InnoDB DEFAULT CHARSET=utf8;
2. 登录与注册页面
注册用户可登录,否则不能登录查看信息
登录
<link rel="stylesheet" type="text/css" href="stylesheets/index.css">
<script type="text/javascript" src="javascripts/index.js"></script>
<script>
var app = angular.module('login', []);
app.controller('loginCtrl', function ($scope, $http, $timeout) {
$scope.check_pwd = function () {
var data = JSON.stringify({
username: $scope.username,
password: $scope.password
});
$http.post("/users/login", data)
.then(
function (res) {
if(res.data.msg=='ok') {
window.location.href='/news.html';
}else{
$scope.msg=res.data.msg;
}
},
function (err) {
$scope.msg = err.data;
});
};
注册
$scope.doAdd = function () {
if($scope.add_password!==$scope.confirm_password){
$scope.msg = '两次密码不一致!';
}
else {
var data = JSON.stringify({
username: $scope.add_username,
password: $scope.add_password
});
$http.post("/users/register", data)
.then(function (res) {
if(res.data.msg=='成功注册!请登录') {
$scope.msg=res.data.msg;
$timeout(function () {
window.location.href='index.html';
},2000);
} else {
$scope.msg = res.data.msg;
}
}, function (err) {
$scope.msg = err.data;
});
}
};
});
登录页面路由
router.post('/login', function(req, res) {
var username = req.body.username;
var password = req.body.password;
userDAO.getByUsername(username, function (user) {
if(user.length==0){
res.json({msg:'用户不存在!请检查后输入'});
}else {
if(password===user[0].password){
req.session['username'] = username;
res.cookie('username', username);
res.json({msg: 'ok'});
// res.json({msg:'ok'});
}else{
res.json({msg:'用户名或密码错误!请检查后输入'});
}
}
});
});
3. 查询数据与分页
$scope.search = function () {
var title1 = $scope.title1;
var title2 = $scope.title2;
var selectTitle = $scope.selectTitle;
var content1 = $scope.content1;
var content2 = $scope.content2;
var selectContent = $scope.selectContent;
var sorttime = $scope.sorttime;
if(typeof title1=="undefined" && typeof title2!="undefined" && title2.length>0){
title1 = title2;
}
if(typeof content1=="undefined" && typeof content2!="undefined" && content2.length>0){
content1 = content2;
}
var myurl = `/news/search?t1=${title1}&ts=${selectTitle}&t2=${title2}&c1=${content1}&cs=${selectContent}&c2=${content2}&stime=${sorttime}`;
http.get(myurl).then( function (res) {
if(res.data.message=='data'){
$scope.isisshowresult = true;
$scope.initPageSort(res.data.result)}
else {
window.location.href=res.data.result;
}},function (err) {$scope.msg = err.data;});
};
查询页结果展示
<div ng-show="isisshowresult">
<table class="table table-striped">
<thead>
<tr>
<td>序号</td>
<td>标题</td>
<td>作者</td>
<td>关键词</td>
<td>链接</td>
<td>发布时间</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="(key, item) in items">
<td>{{index+key}}</td>
<td>{{item.title}}</td>
<td>{{item.author}}</td>
<td>{{item.keywords}}</td>
<td>{{item.url}}</td>
<td>{{item.publish_date}}</td>
</tr>
</tbody>
</table>
效果如图
4. 查询结果用Echart表表示
- 柱状图
$scope.histogram = function () {
$scope.isShow = false;
$http.get("/news/histogram")
.then(
function (res) {
if(res.data.message=='url'){
window.location.href=res.data.result;
}else {
let xdata = [], ydata = [], newdata;
var pattern = /\d{4}-(\d{2}-\d{2})/;
res.data.result.forEach(function (element) {
xdata.push(pattern.exec(element["x"])[1]);
ydata.push(element["y"]);
});
newdata = {"xdata": xdata, "ydata": ydata};
var myChart = echarts.init(document.getElementById('main1'));
var option = {
title: {
text: '球队的支持人数'
},
tooltip: {},
legend: {
data: ['人数']
},
xAxis: {
type: 'category',
name: '球队',
show: true,
data: ["Bucks","warriors","Lakers","Clippers","Celtics","Raptors","Heat","Thunder","Lone Rangers","Cavaliers"],
axisLabel: {
rotate: 30,
interval :0
}
},
yAxis: {
type: 'value',
name: '人数',
min: 0,
max: 1000,
interval:100,
axisLabel: {
formatter: '{value}'
}
},
series: [{
name: '人数',
type: 'bar',
itemStyle: {
normal: {
color: function(params) {
var colorList = [
'#C1232B','#B5C334','#FCCE10','#E87C25','#27727B',
'#FE8463','#9BCA63','#FAD860','#F3A43B','#60C0DD',
'#D7504B','#C6E579','#F4E001','#F0805A','#26C0C0'
];
return colorList[params.dataIndex]
},
label: {
show: true,
position: 'top',
formatter: '{c}'
}
}
},
barWidth: 50,
data: [630,750,900,690,720,500,450,580,530,400]
}]
myChart.setOption(option);
}
},
function (err) {
$scope.msg = err.data;
});
};
- 饼状图
$scope.pie = function () {
$scope.isShow = false;
$http.get("/news/pie").then(
function (res) {
if(res.data.message=='url'){
window.location.href=res.data.result;
}else {
let newdata = [];
var pattern = /责任编辑:(.+)/;
res.data.result.forEach(function (element) {
newdata.push({name: pattern.exec(element["x"]), value: element["y"]});
});
var myChart = echarts.init(document.getElementById('main1'));
var app = {};
option = null;
var option = {
title: {
text: '东方明珠游客来源分布图',
y: 'top',
itemGap: 30,
backgroundColor: '#EEE',
textStyle: {
fontSize: 26,
fontWeight: 'bolder',
color: '#000080'
},
subtextStyle: {
fontSize: 18,
color: '#8B2323'
}
},
legend: {
y: 'center',
itemWidth: 24,
itemHeight: 18,
textStyle: {
color: '#666'
},
itemGap: 30,
backgroundColor: '#eee',
data: ['北京','上海','广东','湖南','四川','陕西']
},
series: [
{
name: '来源地',
type: 'pie',
radius: ['30%', '60%'],
center: ['50%', '50%'],
data: [
{value:210, name:'北京'},
{value:404, name:'上海'},
{value:234, name:'广东'},
{value:135, name:'湖南'},
{value:148, name:'四川'},
{value:120, name:'陕西'}
],
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(30, 144, 255,0.5)'
}
},
labelLine: {
normal: {
show: false
}
},
label: {
normal: {
position: 'inner',
formatter: '{c}'
}
}
}
],
tooltip: {
trigger: 'item',
showDelay: 20,
hideDelay: 20,
backgroundColor: 'rgba(255,0,0,0.7)',
textStyle: {
fontSize: '16px',
color: '#000'
},
formatter: '{a} <br/>{b} : {c}个 ({d}%)'
},
color: ['#7EC0EE', '#FF9F7F', '#FFD700', '#C9C9C9', '#E066FF', '#C0FF3E']
};
app.currentIndex = -1;
setInterval(function () {
var dataLen = option.series[0].data.length;
myChart.dispatchAction({
type: 'downplay',
seriesIndex: 0,
dataIndex: app.currentIndex
});
app.currentIndex = (app.currentIndex + 1) % dataLen;
myChart.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: app.currentIndex
});
myChart.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: app.currentIndex
});
}, 1000);
if (option && typeof option === "object") {
myChart.setOption(option, true);
};
}
});
};
- 折线图
$scope.line = function () {
$scope.isShow = false;
$http.get("/news/line").then(
function (res) {
if(res.data.message=='url'){
window.location.href=res.data.result;
}else {
var myChart = echarts.init(document.getElementById("main1"));
option = {
title: {
text: '"综艺"该词在新闻中的出现次数随时间变化图'
},
xAxis: {
type: 'category',
data: Object.keys(res.data.result)
},
yAxis: {
type: 'value'
},
series: [{
data: Object.values(res.data.result),
type: 'line',
itemStyle: {normal: {label: {show: true}}}
}],
};
if (option && typeof option === "object") {
myChart.setOption(option, true);
}
}
});
};
例子
- 词云
$scope.wordcloud = function () {
$scope.isShow = false;
$http.get("/news/wordcloud").then(
function (res) {
if(res.data.message=='url'){
window.location.href=res.data.result;
}else {
var mainContainer = document.getElementById('main1');
var chart = echarts.init(mainContainer);
var data = [];
for (var name in res.data.result) {
data.push({
name: name,
value: Math.sqrt(res.data.result[name])
})
}
var maskImage = new Image();
maskImage.src = './images/logo.png';
var option = {
title: {
text: '所有新闻内容 jieba分词 的词云展示'
},
series: [{
type: 'wordCloud',
sizeRange: [12, 60],
rotationRange: [-90, 90],
rotationStep: 45,
gridSize: 2,
shape: 'circle',
maskImage: maskImage,
drawOutOfBound: false,
textStyle: {
normal: {
fontFamily: 'sans-serif',
fontWeight: 'bold',
color: function () {
return 'rgb(' + [
Math.round(Math.random() * 160),
Math.round(Math.random() * 160),
Math.round(Math.random() * 160)
].join(',') + ')';
}
},
emphasis: {
shadowBlur: 10,
shadowColor: '#333'
}
},
data: data
}]
};
maskImage.onload = function () {
// option.series[0].data = data;
chart.clear();
chart.setOption(option);
};
window.onresize = function () {
chart.resize();
};
}
});
因为数据的导入在上一篇博客中有提及,这里就不在赘述。
总结
这一次的作业真的是匆匆忙忙赶出来的,也得到了助教和同学的不少帮助,真的很谢谢大家