问题引入
博主最近小学期,每天得收三十多份报告,原采用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': '张**'},
]