学弟划水日记·基于Flask的上传作业平台(一)

问题引入

博主最近小学期,每天得收三十多份报告,原采用QQ发送形式,但效率太低,很多时间都花在收发和修改命名格式上,因而博主打算写个提交作业平台,每个同学均可通过它上传自己的当日作业,最后统一上交

PS:由于开发周期只有一天半,所以有些地方可能存有BUG,恳请指正

项目地址

[email protected]:dalao/submit_homework.git

Docker地址

docker run -itd -p 80:8080 registry.cn-beijing.aliyuncs.com/liyuanhao/homework:v3

运行结果

主页面

上传页面

一、需求分析

1.1 上传

同学将每天的作业(Word文档)上传到博主的服务器上

1.2 重命名

按老师要求的格式给每份文件命名

二、系统设计

2.1 概要设计

该系统采取C/S架构

  • 部署环境 : CentOS7

  • 前端 : Bootstrap + Jquery

  • WEB框架 : Flask

2.2 存储设计

博主将上传文件存到了项目中文件夹内,所以此处无需使用絮聚奎

三、实验过程

项目结构

  • index.html为主页面
  • 信1701-3班-报告文件夹存储上传文件
  • modles.py 存储学生学号信息

3.1 前端

3.1.1 信息表格

主页面初始时显示一个提交表格,内容为每位同学的提交状态、学号、姓名、提交时间以及操作按钮.
图示

实现代码:

  • data是后端传来的一个列表,内含每个学生信息的字典
<!--提交信息的表格-->
<table class="table table-hover">
    <thead>
    <tr>
        <th>提交状态</th>
        <th>学号</th>
        <th>姓名</th>
        <th>上传时间</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
    {% for i in data %}
        <tr>
            {% if i['status'] == 'yes' %}
                <td style="color: green">
                    <strong>已提交</strong>
                </td>
            {% else %}
                <td style="color: red">
                    <strong>未提交</strong>
                </td>
            {% endif %}
            <td>{{ i['num'] }}</td>
            <td>{{ i['name'] }}</td>
            <td>{{ i['time'] }}</td>
            <!--已经提交则提交按钮为不可操作状态-->
            {% if i['status'] == 'yes' %}
                <td>
                    <button class="btn btn-primary" disabled="disabled">
                        已上传
                    </button>
                </td>

            {% else %}
                <!--否则当点击上传按钮时将字典i的值传给对应函数-->
                <td>
                    <button class="btn btn-primary btn-lg" data-toggle="modal" onclick="display_form({{ i }})">
                        文件上传
                    </button>
                </td>
            {% endif %}
        </tr>
    {% endfor %}
    </tbody>
</table>

3.1.2 提交框

<!--上传文件弹出框-->
<div class="modal fade" id="stu_modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title" id="myModalLabel">
                    操作系统每日报告上传
                </h4>
            </div>
            <div class="modal-body">
                <!--上传信息表格-->
                <form id="upload" action="/upload" enctype='multipart/form-data' method='POST'>
                    <div class="input-group mb-3">
                        <div class="input-group-prepend">
                            <span class="input-group-text">姓名</span>
                        </div>
                        <label for="name"></label>
                        <input type="text" class="form-control" id="name" name="name">
                    </div>

                    <div class="input-group mb-3">
                        <div class="input-group-prepend">
                            <span class="input-group-text">学号</span>
                        </div>
                        <label for="num"></label>
                        <input type="text" class="form-control" id="num" name="num">
                    </div>

                    <div class="input-group mb-3">
                        <div class="input-group-prepend">
                            <span class="input-group-text">班级</span>
                        </div>
                        <select class="form-control" name="classes" disabled>
                            <option value="1701_1">信1701-1班</option>
                            <option value="1701_2">信1701-2班</option>
                            <!--默认值-->
                            <option value="1701_3" selected>信1701-3班</option>
                        </select>

                    </div>
                    <!--上传文件的控件-->
                    <input id='file' class="btn btn-info" name="file" type="file">
                    <div class="modal-footer">
                        <button type="button" onclick="submit_form()" class="btn btn-primary">提交</button>
                        <button type="button" class="btn btn-danger" data-dismiss="modal">关闭</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>

3.1.3 JS事件

 //显示模态框
    function display_form(data) {
        //模态框显示事件
        $('#stu_modal').modal('show')
        //自动给姓名与学号控件赋值
        $('#name').val(data['name'])
        $('#num').val(data['num'])
    }

    //提交表格
    function submit_form() {
        var name = $('#name').val()
        var num = $('#num').val()
        //用户名为2-5个汉字
        var name_reg = /^[\u4e00-\u9fa5]{2,5}$/
        //学号为8位数字
        var num_reg = /^\d{8}$/
        if (!name_reg.test(name)) {
            alert("用户名错误!")
            return
        }
        if (!num_reg.test(num)) {
            alert("学号错误!")
            return
        }
        //判断文件是否为空
        var fileInput = $('#file').get(0).files[0];
        if (!fileInput) {
            alert("请选择上传文件!")
            return
        }
        $('#upload').submit();
    }

3.1.4 前端完整代码

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

<head>
    <meta charset="utf-8">
    <title>上传平台</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
    <script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script>
    <script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>

<body>
<div style="text-align: center;">
    <h2>信1701-3班操作系统小学期七月三日报告上传</h2>
    <p>
        <strong style="color:green;">已交{{ num1 }}人</strong>
        /
        <strong style="color:red;">未交{{ 37-num1 }}人</strong>
    </p>
</div>

<!--提交信息的表格-->
<table class="table table-hover">
    <thead>
    <tr>
        <th>提交状态</th>
        <th>学号</th>
        <th>姓名</th>
        <th>上传时间</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
    {% for i in data %}
        <tr>
            {% if i['status'] == 'yes' %}
                <td style="color: green">
                    <strong>已提交</strong>
                </td>
            {% else %}
                <td style="color: red">
                    <strong>未提交</strong>
                </td>
            {% endif %}
            <td>{{ i['num'] }}</td>
            <td>{{ i['name'] }}</td>
            <td>{{ i['time'] }}</td>
            <!--已经提交则提交按钮为不可操作状态-->
            {% if i['status'] == 'yes' %}
                <td>
                    <button class="btn btn-primary" disabled="disabled">
                        已上传
                    </button>
                </td>

            {% else %}
                <!--否则当点击上传按钮时将字典i的值传给对应函数-->
                <td>
                    <button class="btn btn-primary btn-lg" data-toggle="modal" onclick="display_form({{ i }})">
                        文件上传
                    </button>
                </td>
            {% endif %}
        </tr>
    {% endfor %}
    </tbody>
</table>


<!--上传文件弹出框-->
<div class="modal fade" id="stu_modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h4 class="modal-title" id="myModalLabel">
                    操作系统每日报告上传
                </h4>
            </div>
            <div class="modal-body">
                <!--上传信息表格-->
                <form id="upload" action="/upload" enctype='multipart/form-data' method='POST'>
                    <div class="input-group mb-3">
                        <div class="input-group-prepend">
                            <span class="input-group-text">姓名</span>
                        </div>
                        <label for="name"></label>
                        <input type="text" class="form-control" id="name" name="name">
                    </div>

                    <div class="input-group mb-3">
                        <div class="input-group-prepend">
                            <span class="input-group-text">学号</span>
                        </div>
                        <label for="num"></label>
                        <input type="text" class="form-control" id="num" name="num">
                    </div>

                    <div class="input-group mb-3">
                        <div class="input-group-prepend">
                            <span class="input-group-text">班级</span>
                        </div>
                        <select class="form-control" name="classes" disabled>
                            <option value="1701_1">信1701-1班</option>
                            <option value="1701_2">信1701-2班</option>
                            <!--默认值-->
                            <option value="1701_3" selected>信1701-3班</option>
                        </select>

                    </div>
                    <!--上传文件的控件-->
                    <input id='file' class="btn btn-info" name="file" type="file">
                    <div class="modal-footer">
                        <button type="button" onclick="submit_form()" class="btn btn-primary">提交</button>
                        <button type="button" class="btn btn-danger" data-dismiss="modal">关闭</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
</body>

<script>
    //显示模态框
    function display_form(data) {
        //模态框显示事件
        $('#stu_modal').modal('show')
        //自动给姓名与学号控件赋值
        $('#name').val(data['name'])
        $('#num').val(data['num'])
    }

    //提交表格
    function submit_form() {
        var name = $('#name').val()
        var num = $('#num').val()
        //用户名为2-5个汉字
        var name_reg = /^[\u4e00-\u9fa5]{2,5}$/
        //学号为8位数字
        var num_reg = /^\d{8}$/
        if (!name_reg.test(name)) {
            alert("用户名错误!")
            return
        }
        if (!num_reg.test(num)) {
            alert("学号错误!")
            return
        }
        //判断文件是否为空
        var fileInput = $('#file').get(0).files[0];
        if (!fileInput) {
            alert("请选择上传文件!")
            return
        }
        $('#upload').submit();
    }
</script>
</html>

3.2 后端

app.py

import os
import time

from flask import Flask, render_template, request, redirect, url_for
import models
app = Flask(__name__)


@app.route('/')
def hello_world():
    data = get_upload_info()
    num1 = len(get_stu_num())
    return render_template('index.html', data=data, num1=num1)


# 存储上传的文件
@app.route('/upload', methods=['POST', 'GET'])
def upload_file():
    if request.method == 'POST':
        f = request.files['file']
        name = request.form.get('name')
        num = request.form.get('num')
        # 获取文件格式
        file_format = f.filename.split('.')[1]
        # 按老师要求命名
        new_name = '%s-%s-课程设计工作日报表.%s' % (num, name, file_format)
        f.filename = new_name
        # 上传文件的所在路径
        upload_path = os.path.join(os.getcwd(), '信1701-3班-报表-7月3日', f.filename)
        # 将路径转换为绝对路径
        upload_path = os.path.abspath(upload_path)
        f.save(upload_path)
        return redirect(url_for('hello_world'))


# 根据学号获取文件路径
def get_file_path(num):
    folder_path = os.path.join(os.getcwd(), '信1701-3班-报表-7月3日')
    for i in os.listdir(folder_path):
        if num in i:
            # 返回对应文件的绝对路径
            return os.path.join(folder_path, i)


# 获取文件修改时间
def get_upload_time(num):
    path = get_file_path(num)
    times = os.path.getmtime(path)
    return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(times))


# 获取已经上传学生的学号
def get_stu_num():
    data = []
    folder_path = os.path.join(os.getcwd(), '信1701-3班-报表-7月3日')
    for i in os.listdir(folder_path):
        path = os.path.join(folder_path, i)
        if os.path.isfile(path):
            num, name, file_format = i.split('-')
            data.append(num)
    return data


def get_upload_info():
    data2 = []
    num_info = get_stu_num()
    for i in models.stu_info:
        info = {
            'status': 'no',
            'num': i['num'],
            'name': i['name'],
            'time': '-----'
        }
        # 若该人已经提交
        if num_info and i['num'] in num_info:
            info['status'] = 'yes'
            info['time'] = get_upload_time(i['num'])
        data2.append(info)
    return data2


if __name__ == '__main__':
    app.run()

models.py 数据仅做示例

stu_info = [
    {'num': '2015****', 'name': '李**'},
    {'num': '2016****', 'name': '张**'},
    {'num': '2017****', 'name': '张**'},
    {'num': '2017****', 'name': '王**'},
    {'num': '2017****', 'name': '张**'},
]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章