您的位置:首页 > Web前端 > Node.js

一个基于node与mysql的打卡小应用

2016-03-03 08:23 302 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_24309579/article/details/50785717

var request = require('request');
var cheerio = require('cheerio');
var http = require('http');
var fs = require('fs');

function sleep(milliSeconds) {
var startTime = new Date().getTime();
while (new Date().getTime() < startTime + milliSeconds);
};

//获取某一个页面的所有图片
function getImg(Url,className,imgName)
{
request(Url,function(err,res,body)
{
//如果出错,则重新运行一遍程序
if(err)
{
console.log("connect err"+err);
getImg(Url);
}

//加载body
console.log(Url);
var $ = cheerio.load(body)
className = '.'+className;

//如果没有填写,则使用默认值。
if(className == '.')
{
className = 'body';
}
if(imgName == '')
{
imgName = 'img'
}

var items = $(''+className+' .'+imgName);
//获取网页的标题
var title = new $("title").text();
//创建存放图片的文件夹
fs.mkdir(title,function(err)
{
if (err) {console.log("创建文件夹失败")}

items.each(function(id,element){
var src = element.attribs.src;
var date = new Date();
//创建文件名
var filename =title+id+'.jpg';
//写入流
var writestream = fs.createWriteStream('./'+title+'/'+filename);

console.log(src);

if(src){
http.get(src,function(res)
{
if(res)
//下载流
res.pipe(writestream);
else
{
console.log('下载图片失败');
}
}).on('error',function(e){
console.log(e);
});
}
console.log(filename);
//为了防止访问过快而造成禁止访问
sleep(500);
});

})

});

}
//
getImg('http://tieba.baidu.com/p/4416880186','d_post_content','BDE_Image');

昨天写一个基于node与mysql的打卡小应用,现在将其整理出来,方便日后使用。


1,前端设计

首先是页面设计,简单的设计了两个页面。


这个是用户登录之后的打卡界面,用户点击分享之后,打卡按钮消失,只留下分享到朋友圈的按钮。



2,逻辑设计

逻辑设计是比较简单的:

如果打开的是打卡界面,那么首先先检查用户是否注册过,是否是登陆状态,如果是,那么就跳到打卡界面,如果不是,那么就跳到登陆界面,当然应用主要是在微信上面使用,那么应该使用微信用户的OPENID,而不是应该自己写注册,但是非常坑爹的是,这个东西获取是受限的,后面再说。


如果打开的是分享界面,那么就直接是显示分享的人已经打卡多少次。


不过现在这个东西只能自用,给我自己学习打卡用了。哈哈哈



3,数据库设计 

数据库设计是根据个人喜好而定的。
比如我就是这样设计的,当然设计的不 完善,不过不要紧。会有机会完善的。
数据库
用户可修改信息表格 userCloInfo

用户id:int userId
用户名:string userName
上一次打卡时间:string lastCloDate
总共打卡次数:int cloNum
自习时间:int stuTimes
称号:int honor



4,代码

首先放模板的代码,我是用ejs写的模板,所以看起来应该不吃力。

今天是第一次移动开发,移动web最重要的一句就是设定viewport,将vieport设定好之后,窗口才不会随意乱缩放。

<meta name="viewport" content="width=device-width,initial-scale=1,user-scale=no" charset="UTF-8">


clock.ejs

<!DOCTYPE html>
<html>
<head>
<pre name="code" class="html"><meta name="viewport" content="width=device-width,initial-scale=1,user-scale=no" charset="UTF-8">
<title><%= userCloInfor.title %></title> <link rel="stylesheet" type="text/css" href="./css/weui.css"> <link rel="stylesheet" type="text/css" href="./css/clock.css"> <script type="text/javascript" src="./js/jquery-2.2.0.min.js"></script> <link rel="shortcut icon" href="http://cdn-img.easyicon.net/favicon.ico"></head><body> <div id="mcover" οnclick="document.getElementById('mcover').style.display='';" style="display:none;"> <img src="./img/guide.png" /></div><div class="content"><img src="./img/background.gif"><p class="normalWord"><%= userCloInfor.userName %>已经在南开大学津南图书馆自习了</p><p class="bigWord"><span id="userStuTimes"><%= userCloInfor.stuTimes %></span>天</p><p class="normalWord">打卡共<span id="numbercolor"><%= userCloInfor.cloNum %></span>次</p><p class="normalWord">成功获得了称号</p><p class="bigWord"><span id="userHonor"><%= userCloInfor.honor %></span></p></div><div class="postbtn"><button class="weui_btn weui_btn_plain_primary" id="clock">打卡</button><button class="weui_btn weui_btn_plain_primary" id="share">分享到朋友圈</button></div><script type="text/javascript"> <%- somescript %> $('#share').click(function(){ window.location.href="share" }); var clockflag = 1; if(clockflag == 1) { $('#clock').click(function(){ $.ajax({ //以数组形式将数据发给服务器 type:'POST', url:'/users/<%- userCloInfor.userName %>' }).done(function(results){ //改变数据库之后要做的事情 $('#userStuTimes').html(results.stuTimes); $('#numbercolor').html(results.cloTimes); $('#userHonor').html(results.honor); $('#clock').addClass("weui_btn_disabled"); clockflag = 0; }); }); }</script></body></html>


最下面是一段ajax,使用打卡之后刷新数据,并且你点击一次打卡之后,就不能再一次点击了。但是刷新之后就可以,因为我在后端没有限制两次点击事件。

clock.css

.content{width: 100%;text-align: center;}
.content img{margin-bottom: -20px;}
.bigWord,.normalWord{font-family: "微软雅黑";}
#numbercolor{color: #cc3333;}
.normalWord{font-size: 18px;color: #000033;}
.bigWord{font-size: 30px;font-weight: bold;color: #cc3333;}
.postbtn{width: 60%;padding: 0 20%;margin-top: 10px;}
#share{margin-bottom: 20px;}

#mcover {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
display: none;
z-index: 20000;
}
#mcover img {
position: fixed;
right: 18px;
top: 5px;
width: 260px!important;
height: 180px!important;
z-index: 20001;
}


其他用的插件,大家可以去网上找,其中有weui,jquery。


这里我学到的一个点就是如果点击分享之后出现的小动画是如何做的,原来就是点击按钮之后在所有图层前面放一个遮罩就可以了。


users.js


var express = require('express');
var router = express.Router();

var mysql = require('mysql');

// 链接数据库
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'mxd6980k9',
port : '3306'
});

function handleError(err)
{
if(err){

3ff7
if(err.code === 'PROTOCOL_CONNECTION_LOST')
{
connect();
}
else
{
console.err(err||err.stack);
}
}
}

//数据库连接
function connect()
{
connection.connect(handleError);
connection.on('error',handleError);
}

connect();

/* GET users listing. */
//分享界面
router.get('/share',function(req,res,next){
var username = req.params.user;

var honor = ['学渣','学屌','学霸','学神'];
connection.query('select * from dispg.userCloInfo where userId = 1', function(err,result)
{
if(err)
{
console.log(err);
}
var certainuser = result[0];
certainuser.title =  certainuser.userName + "在南开大学津南图书馆打卡第" + certainuser.cloNum + "次";
certainuser.honor = honor[certainuser.honor];
var somescript = "$('#clock').css('display','none');$('#mcover').css('display','block');";
res.render('clock',{userCloInfor:certainuser,somescript:somescript});
});
});

//访问界面
router.get('/:user', function(req, res, next) {

var username = req.params.user;

var honor = ['学渣','学屌','学霸','学神'];
connection.query('select * from dispg.userCloInfo where userId = 1', function(err,result)
{
if(err)
{
console.log(err);
}
var certainuser = result[0];
certainuser.title =  certainuser.userName + "在南开大学津南图书馆打卡第" + certainuser.cloNum + "次";
certainuser.honor = honor[certainuser.honor];
res.render('clock',{userCloInfor:certainuser,somescript:''});
});
});

//点击打卡之后提交的post界面
router.post('/:user',function(req,res,next){
//如果现在的时间比上一次提交的时间只相差5分钟,那么就原数据返回
var honor = ['学渣','学屌','学霸','学神'];
connection.query('select * from dispg.userCloInfo where userId = 1', function(err,result){
if(err)
{
console.log(err);
}

var certainuser = result[0];
//获取时间
var date = new Date();
var time = date.getTime();

//数据初始化
if(certainuser.lastCloDate == 0)
{
certainuser.lastCloDate = time;
}
else
{
//如果时间大于一天,那么就学习的天数就增加。
if(time - certainuser.lastCloDate >= 86400000)
{
certainuser.stuTimes++;
}
}
//数据初始化
if(certainuser.stuTimes==0)
{
certainuser.stuTimes = 1 ;
}

certainuser.lastCloDate = time;
certainuser.cloNum++;
certainuser.honor = certainuser.stuTimes/20;
console.log(result);
//update语句,今天也算是学到了一点了,每天变量设定之间要有逗号隔开。
var query = 'update dispg.userCloInfo set cloNum = '+ certainuser.cloNum +', honor ='+certainuser.honor +', lastCloDate = '+certainuser.lastCloDate +', stuTimes = '+certainuser.stuTimes+' where userCloInfo.userId = 1';

console.log(query);

connection.query(query,function(err,result){ if(err){ console.log(err);} res.json({stuTimes:certainuser.stuTimes,cloTimes:certainuser.cloNum++,honor: honor[certainuser.honor]
});
});

});

});

module.exports = router;



下面来说一下关于微信的oauth2.0,登陆oauth2.0需要appid,但是我只有一个订阅号的appid,也就是说,这个appid是没有权限获得微信用户的openid的,坑爹的微信,我又不拿来获取用户信息,我只是 获取openid区别用户而已。


总之以后再做登陆吧,还有就是关于session 和 cookie 的事情,还没有看明白,还得去查资料看看。





内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: