计算机学院机房作为教学实践的重要场所,其使用效率和管理水平直接影响教学质量。传统的人工预约方式存在信息不对称、资源分配不均、统计困难等问题。基于Flask框架开发的机房预约管理系统,旨在实现以下核心目标:
实际开发中发现:机房预约存在明显的"潮汐现象"——课程设计周预约量可达平时的300%,系统必须考虑高并发场景下的稳定性。
采用Flask+Vue.js的分离架构设计:
code复制[浏览器] ←HTTP→ [Vue前端] ←RESTful API→ [Flask后端] ←ORM→ [MySQL]
↑ ↓
[ElementUI] [Redis缓存]
前端技术栈选型理由:
后端技术栈关键配置:
python复制# Flask核心配置示例
app = Flask(__name__)
app.config.update({
'SQLALCHEMY_DATABASE_URI': 'mysql+pymysql://user:pass@host/db',
'SQLALCHEMY_TRACK_MODIFICATIONS': False,
'JWT_SECRET_KEY': os.urandom(32)
})
核心表结构设计原则:
sql复制CREATE TABLE `reservation` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL COMMENT '学工号',
`room_id` smallint(6) NOT NULL,
`start_time` datetime NOT NULL,
`end_time` datetime NOT NULL,
`status` enum('pending','approved','rejected','canceled') DEFAULT 'pending',
`purpose` varchar(255) DEFAULT NULL COMMENT '使用用途',
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_time_range` (`room_id`,`start_time`,`end_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
sql复制SELECT COUNT(*) FROM reservation
WHERE room_id = %s
AND status = 'approved'
AND NOT (end_time <= %s OR start_time >= %s)
采用时间区间重叠检测算法:
python复制def check_conflict(room_id, new_start, new_end):
existing = Reservation.query.filter(
Reservation.room_id == room_id,
Reservation.status == 'approved',
not_(or_(
Reservation.end_time <= new_start,
Reservation.start_time >= new_end
))
).count()
return existing > 0
基于Flask-Principal实现:
python复制@identity_loaded.connect_via(app)
def on_identity_loaded(sender, identity):
if hasattr(current_user, 'role'):
identity.provides.add(RoleNeed(current_user.role))
if isinstance(current_user, Teacher):
identity.provides.add(Need('access', 'teacher_portal'))
学生端预约时序:
/api/rooms/available获取可预约时段/api/reservations POST请求关键代码片段:
javascript复制// Vue组件方法
submitReservation() {
this.$axios.post('/api/reservations', {
room_id: this.selectedRoom,
start_time: this.timeRange[0],
end_time: this.timeRange[1],
purpose: this.purpose
}).then(response => {
this.$message.success('预约申请已提交');
this.fetchMyReservations();
})
}
教师端批量审批实现方案:
python复制@app.route('/export_approvals')
@teacher_required
def export_approvals():
output = io.BytesIO()
workbook = Workbook()
# ...填充数据逻辑...
workbook.save(output)
return send_file(
output,
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
as_attachment=True,
attachment_filename='approvals.xlsx'
)
使用Pandas进行数据分析:
python复制def generate_report(start_date, end_date):
df = pd.read_sql(
f"SELECT * FROM reservation WHERE create_time BETWEEN '{start_date}' AND '{end_date}'",
db.engine
)
report = {
'total': len(df),
'by_room': df.groupby('room_id').size().to_dict(),
'by_status': df.groupby('status').size().to_dict(),
'peak_hours': df['start_time'].dt.hour.value_counts().head(3).index.tolist()
}
return report
推荐使用Docker-Compose部署:
yaml复制version: '3'
services:
web:
build: .
ports:
- "5000:5000"
environment:
- FLASK_ENV=production
depends_on:
- redis
- db
redis:
image: redis:alpine
db:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_DATABASE=reservation
性能优化措施:
nginx复制location /static {
alias /app/static;
expires 30d;
add_header Cache-Control "public";
}
关键安全配置:
python复制app.config.update({
'SECRET_KEY': os.urandom(24),
'WTF_CSRF_SECRET_KEY': os.urandom(24)
})
python复制# 错误示范
query = f"SELECT * FROM users WHERE name = '{request.form['name']}'"
# 正确做法
db.session.execute(
text("SELECT * FROM users WHERE name = :name"),
{"name": request.form['name']}
)
python复制# 配置Flask时区
app.config['JSON_AS_ASCII'] = False
app.config['JSONIFY_MIMETYPE'] = "application/json;charset=utf-8"
app.config['TIMEZONE'] = 'Asia/Shanghai'
python复制from flask_cors import CORS
CORS(app, resources={
r"/api/*": {
"origins": ["https://yourdomain.com"],
"methods": ["GET", "POST", "PUT", "DELETE"],
"allow_headers": ["Authorization", "Content-Type"]
}
})
python复制if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
javascript复制Vue.config.errorHandler = function (err, vm, info) {
console.error(`Error: ${err.toString()}\nInfo: ${info}`);
// 可接入Sentry等监控系统
}
python复制@app.route('/api/wx/login', methods=['POST'])
def wechat_login():
code = request.json.get('code')
# 调用微信接口服务获取openid
# ...
python复制def recommend_slots(user_id):
# 基于用户历史行为分析
history = get_user_history(user_id)
# 使用协同过滤算法推荐时段
# ...
return recommended_slots