web作业(二)用node.js在树莓派上开发一个便携式教育工具

树莓派部分

系统烧录

具体步骤参考:https://mc.dfrobot.com.cn/thread-306405-1-1.html
可视化界面如下:
在这里插入图片描述

热点

要求
在这里插入图片描述
由于我的树莓派出了一点小问题,所以这个暂未实现,等我实现好了,再来补充

教育工具部分

在这里插入图片描述
在这里插入图片描述

学生端

1.注册、登录功能实现
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>学生登录</title>
    <link rel="stylesheet" href="stylesheets/style.css">
</head>

<body>
    <div class="container">
        <form action="/stulogin" method="post">
            <div class="title">学生登录</div>
            <div class="row">
                <input type="text" name="username" placeholder="请输入用户名" required>
            </div>
            <div class="row">
                <input type="password" name="password" placeholder="请输入密码" required>
            </div>
            <button type="button" id="loginBtn">登录</button>

            <a href="sturegister.html">还没有账号?去注册一个</a>
        </form>
    </div>
</body>

</html>

后端

var studentLogin = function (username, password, req, callback) {
    var sqlstr = "SELECT username, password FROM student WHERE username=?";
    var params = [username];
    var promise = new Promise(function (resolve, reject) {
        mysql.query(sqlstr, params, function (err, result) {
            if (err) {
                reject(err);
            }
            else {
                resolve(result);
            }
        });
    });
    promise.then((result) => {
        var status = 0;
        if (result[0].password == password) {
            status = 1;
            req.session.username = result[0].username;
            //console.log(req)
        }
        else if (result == undefined || result.length == 0) {
            status = 2;
        }
        else {
            status = 3;
        }
        callback(status);
    })
}

效果如下在这里插入图片描述
注册基本原理一样,除了数据库部分有点不一样

var studentRegister = function (username, password, check, callback) {
    var sqlstr = "SELECT username, password FROM student WHERE username=?"
    var params = [username];
    var promise = new Promise(function (resolve, reject) {
        mysql.query(sqlstr, params, function (err, result) {
            if (err) {
                //alert("error");
                reject(err);
            }
            else {
                resolve(result);
            }
        });
    });
    promise.then((result) => {
        var status = 0;
        if (result[0] == username) {
            //alert("1");
            status = 1;
        }
        else {
            if (password != check) {
                status = 3;
            }
            else {
                //alert(username);
                var sql = "INSERT INTO student(id,username,password) values(null,?,?)";
                var params = [username, password];
                //console.log(params);
                mysql.query(sql, params, function (err, result) {
                    console.log(result);
                });
            }
        }
        callback(status);
    })
}

(其中很多注释掉的就是一遍一遍调试的过程,终于跑通的时候真的有成就感)

其中连接数据库的部分是用老师上课给的代码实现的


const mysql = require('mysql');


var pool = mysql.createPool({
    host: 'localhost',
    user: 'root',
    password: 'root',
    database: 'database'
});

var query = function(sql, sqlparam, callback) {
    pool.getConnection(function(err, conn) {
        if (err) {
            callback(err, null, null);
        } else {
            conn.query(sql, sqlparam, function(qerr, vals, fields) {
                conn.release(); //释放连接 
                callback(qerr, vals, fields); //事件驱动回调 
            });
        }
    });
};
var query_noparam = function(sql, callback) {
    pool.getConnection(function(err, conn) {
        if (err) {
            callback(err, null, null);
        } else {
            conn.query(sql, function(qerr, vals, fields) {
                conn.release(); //释放连接 
                callback(qerr, vals, fields); //事件驱动回调 
            });
        }
    });
};
exports.query = query;
exports.query_noparam = query_noparam;
2.下载

在这里插入图片描述

app.get("/download", function (req, res) {
  fs.readdir("./public/upload", function (err, data) {
    //console.log(data)
    if (err) {
      console.log(err)
      //console.log("error")
    } else {
      //console.log(req)
      res.render("../public/download.html", {
        files: data
      })
    }
  })
})
3.做题目
app.post("/doneproblem", function (req, res) {
  var data = req.body
  var total = 0;
  var right = 0;
  connection.query("select * from problems", function (res_, rows) {
    for (var i = 0; i < rows.length; i++) {
      total++;
      var id_ = rows[i].id;
      var answer_ = rows[i].answer;
      console.log(data[id_])
      if (data[id_] == answer_) {
        right++;
      }
    }
    res.render("../views/situation.html");
  })
})

效果如下:
在这里插入图片描述

做题目我还加了用饼图可视化实现(根据每个同学的情况生成一张图)
在这里插入图片描述
可以完善的是,应该收集所有的学生的答题信息,在老师端生成可视化的图或者表更合理一些。

4.看老师讲题

老师讲题是,老师在图中修改,学生应该是可以看到老师的墨迹
这里用到了socket实现
学生端前端代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>看图</title>
    <link rel="stylesheet" type="text/css"  href="./stylesheets/nav.css">
</head>
<body>
    <ul>
        <li><a class="active" href="#">主页</a></li>
        <li  id="download"><a href="#">下载</a></li>
        <li id="live"><a href="#">进入直播</a></li>
        <li id="problem"><a href="#">完成作业</a></li>
        <li id="getpicture"><a href="#">看图</a></li>

    </ul>
    <div class="paint">
        <canvas id="canvas" width="500" height="400" style="border:1px solid #c3c3c3;"></canvas>
    </div>
</body>
<script src="javascripts/jquery-3.5.1.js"></script>
<script src="./socket.io.js"></script>
<script src="../node_modules/socket.io-client/dist/socket.io.js"></script>
<script>
    document.getElementById("download").onclick = function(){
        location.href = "/download"
    }
    document.getElementById("problem").onclick = function(){
        location.href = "/doproblem"
    }
    document.getElementById("getpicture").onclick = function(){
        location.href = "/getpicture"
    }

</script>
<script>
    var socket = io("http://localhost:3000");
    socket.on('connect',function(){
        console.log('connected')
    })
    socket.on('info',function(data){
        var img=new Image()
        img.src=data;
        var canvas = document.getElementById("canvas");
        var context = canvas.getContext("2d");
        img.onload = function(){
            context.drawImage(img,0,0,500,400);
        }
    })
    socket.on('disconnect',function(){
        console.log('disconnected')
    })

    window.onload=function(){
        var canvas = document.getElementById("canvas");
        var context = canvas.getContext("2d");
        var temp = false;
        socket.on('info1',function(data){
            temp=true;
            var x=data[0];
            var y=data[1];
            context.moveTo(x,y);
        })
        socket.on('info2',function(data){
            var x=data[0];
            var y=data[1];
            if(temp){
                context.lineTo(x,y);
                context.stroke();
            }
        })
        socket.on("info3",function(data){
            if(data==1){
                temp=false;
            }
        })
    }

    
</script>
</html>

效果如下(现在是一个画布)
在这里插入图片描述

教师端

大致与学生端一样
以下是与学生不太一样的

1.出题界面
app.get("/giveproblem", function (req, res) {
  connection.query("select * from problems", function (err, rows) {
    connection.query("select * from situation", function (error, info) {
      //console.log(info)
      res.render("../views/giveproblem.html", {
        problems: rows,
        situations: info
      })
    })
  })
})

在这里插入图片描述

2.会绘图讲题实现,让学生可以实时看到老师的墨迹

前端代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>绘图</title>
    <link rel="stylesheet" type="text/css" href="./stylesheets/nav.css">
</head>

<body>
    <ul>
        <li><a class="active" href="#">主页</a></li>
        <li id="upload"><a href="#">上传</a></li>
        <li id="live"><a href="#">进入直播</a></li>
        <li id="problem"><a href="#">发布作业</a></li>
        <li id="draw"><a href="#">画图</a></li>
    </ul>


    <div class="paint">
        <canvas id="canvas" width="500" height="400" style="border:1px solid #c3c3c3;"></canvas>
    </div>
    <input accept="image/*" type="file" id="uploadIMG" onchange="btnUploadFile(event)" />
</body>
<script src="javascripts/jquery-3.5.1.js"></script>
<script src="./socket.io.js"></script>
<script src="../node_modules/socket.io-client/dist/socket.io.js"></script>
<script>

    var socket = io("http://localhost:3003");


    socket.on('connect', function () {
        console.log('连接成功')
    })
    socket.on('disconnect', function () {
        console.log('断开连接')
    })

    
    function btnUploadFile(e, type) {
        var files = e.target.files;
        var file = files[0];
        if (!/\/(?:jpeg|jpg|png)/i.test(file.type)) {
            return;
        }

        var reader = new FileReader();
        reader.onload = function () {
            var result = this.result;
            socket.emit("send", result)
        };
        reader.readAsDataURL(file);
    }
    socket.on('info', function (data) {
        var img = new Image()
        //console.log(data)
        img.src = data;
        var canvas = document.getElementById("canvas");
        var context = canvas.getContext("2d");
        //console.log(result)
        img.onload = function () {
            context.drawImage(img, 0, 0, 500, 400);
        }
    })

    window.onload = function () {
        var canvas = document.getElementById("canvas");
        var context = canvas.getContext("2d");
        paint(context);
    }
    function paint(context) {
        var temp = false;
        $("canvas").mousedown(function (e) {
            temp = true;
            var x = e.pageX - 8;
            var y = e.pageY - 8;
            context.moveTo(x, y);
            socket.emit("send1", [x, y])
        })
        $("canvas").mousemove(function (e) {
            var x = e.pageX - 8;
            var y = e.pageY - 8;
            //$("#info").html("( "+x+" , "+y+" )");
            socket.emit("send2", [x, y])
            if (temp) {
                context.lineTo(x, y);
                context.stroke();
            }
        })
        $("canvas").mouseup(function (e) {
            temp = false;
            socket.emit("send3", 1)
        })
    }
</script>
<script>
    document.getElementById("upload").onclick = function () {
        location.href = "/upload.html"
    }
    document.getElementById("problem").onclick = function () {
        location.href = "/giveproblem"
    }
    // document.getElementById("live").onclick = function () {
    //     location.href = "/live"
    // }
    document.getElementById("draw").onclick = function () {
        location.href = "/draw"
    }
</script>

</html>

后端代码

var server = require("http").createServer(app);

var io = require('socket.io')(server);
io.listen(3003);

io.on('mysql', function (socket) {
  socket.on("send", function (data) {
    io.emit("info", data)
  })
  socket.on("send1", function (data) {
    console.log(data);
    io.emit("info1", data)
  })
  socket.on("send2", function (data) {
    io.emit("info2", data)
  })
  socket.on("send3", function (data) {
    io.emit("info3", data)
  })
  socket.on('reply', function () { })
})

总结

这算我完成的第一个项目,可能很多大佬觉得简单,但是实现的过程中我真的学到了很多,有了一些前后端分离的想法,也提升了一点调试代码的能力。最后感谢一下老师,以及帮助我的同学,真的非常感谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值