學弟划水日記·基於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': '張**'},
]

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