web编程期末大作业 项目一

    技术2022-07-10  120

    作业要求

    一、登录注册页面

    检测用户名密码是否一致,是则跳转至新闻页面

    增加注册用户

    登录界面如下: 发现自己实在是不太了解bootstrap的各种样式,界面也不知道该怎么优化,后面的html文档的css就都用的老师给的模板了 -_-||

    二、操作记录保留

    首先先在数库中建立两张表,一个存放已注册的用户账号密码。另一个存放用户操作记录:

    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;

    然后设置mysql配置文件:

    module.exports = { mysql: { host: 'localhost', user: '***', password: '***', database:'***', connectionLimit: *** }};

    账号密码表: 操作记录表:

    三、查询数据与分页

    数据查询代码:

    $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;}); };

    分页功能的实现:

    $scope.initPageSort=function(item){ $scope.pageSize=5;  $scope.selPage = 1; $scope.data = item; $scope.pages = Math.ceil($scope.data.length / $scope.pageSize); $scope.pageList = []; $scope.index = 1; var len = $scope.pages> 5 ? 5:$scope.pages; $scope.pageList = Array.from({length: len}, (x,i) => i+1); $scope.items = $scope.data.slice(0, $scope.pageSize); }; $scope.selectPage = function (page) { if (page < 1 || page > $scope.pages) return; var pageList = []; if(page>2){ for (var i = page-2; i <= $scope.pages && i < page+3; i++) { pageList.push(i); } } else { for (var i = page; i <= $scope.pages && i < page+5; i++) { pageList.push(i); } } $scope.index =(page-1)*$scope.pageSize+1; $scope.pageList = pageList; $scope.selPage = page; $scope.items = $scope.data.slice(($scope.pageSize * (page - 1)), (page * $scope.pageSize)); console.log("选择的页:" + page); };

    添加查看查询结果返回首页、尾页、任意页功能:

    <script> //返回到首页 $scope.First = function () { $scope.selectPage(1); }; //跳转至尾页 $scope.Previous = function () { $scope.selectPage($scope.selPage - 1); }; //跳转至所输入的页 $scope.toThePage=undefined; $scope.ToThePage = function () { $scope.selectPage($scope.toThePage); $scope.toThePage = undefined; } </script> <a ng-click="First()" role="button"><span role="button">首页</span></a> <a ng-click="Previous()" role="button"><span role="button">上一页</span></a> <input type="text" placeholder="页码" style="height:33px; width:40px;" ng-model="$parent.toThePage"> <a ng-click="ToThePage()" role="button"><span role="button" >跳转到</span></a>~

    四、数据可视化

    选用Echarts对爬取到的数据进行一个直观的解明: (1)柱状图

    $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]); data.push(element["y"]); }); newdata = {"xdata": xdata, "ydata": ydata}; var myChart = echarts.init(document.getElementById('main1')); var option = { title: { text: '新闻发布数 随时间变化' }, tooltip: {}, legend: { data: ['新闻发布数'] }, xAxis: { data: newdata["xdata"]}, yAxis: {}, series: [{ name: '新闻数目', type: 'bar', data: newdata["ydata"] }] }; myChart.setOption(option); } }, function (err) { $scope.msg = err.data; }); };

    例子: (2)饼图:

    $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 = /编辑:[\u4E00-\u9FA5]+/; 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: '作者发布新闻数量', x: 'center' }, tooltip: { trigger: 'item', formatter: "{a} <br/>{b} : {c} ({d}%)" }, legend: { orient: 'vertical', left: 'left', }, series: [ { name: '访问来源', type: 'pie', radius: '55%', center: ['50%', '60%'], data: newdata, itemStyle: { emphasis: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5) } } } ] }; 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") { yChart.setOption(option, true); } ; } }); };

    例子: 各个网站对于编辑的格式不一甚至可能一篇文章没有作者,所以汇总在一起以后很难用正则表达式把作者名取出来,故饼图的很多部分作者名为空。 (3)折线图 本来是想在网页输入关键词进行实时更新折线图的,但是我发现折线图仿佛有惰性,刷新页面并不会更新折线图,只能在终端退出以后重新node www文件并重新登录才能更新,所以就放弃了。

    $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)} } }); };

    例子: (4)词云

    $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 () { chart.clear(); chart.setOption(option); }; window.onresize = function () { chart.resize(); }; } }); }~

    例子:

    总结

    相比期中的作业,本次大作业对我来说是蛮有难度的,代码多数也是用了老师的代码,我更多的是依葫芦画瓢在模仿写跳转页等而非有什么新东西,路由方面的设置也不太会写。听说油管等外网有很多优秀的前端开发教程,希望在后续的学习中能学会一些,不再面对各科大作业时心中发怵。

    Processed: 0.023, SQL: 9