問題引入
博主最近小學期,每天得收三十多份報告,原採用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': '張**'},
]