基于Flask的校园打印店预约系统设计与实现

📅 2026/8/11 3:49:54
基于Flask的校园打印店预约系统设计与实现
1. 项目概述校园打印店预约及取件系统是基于Python Flask框架开发的Web应用解决方案旨在解决高校打印店高峰期排队拥挤、文件管理混乱等痛点。我在开发这个系统时主要考虑了三个核心需求线上文件上传与排队管理、打印状态实时更新、以及取件验证流程。这个系统特别适合高校计算机相关专业的学生作为毕业设计选题也适用于校园创业者想要数字化改造传统打印服务。通过本系统学生可以提前上传文件并预约打印时段打印店工作人员能有序处理订单双方都能节省大量等待时间。2. 系统架构设计2.1 技术栈选型选择Flask作为后端框架主要考虑到它的轻量级特性相比Django和灵活的路由设计。对于校园打印这类业务逻辑相对简单但需要快速迭代的场景特别合适。数据库选用MySQL 5.7版本主要因为校园信息化系统普遍使用MySQL事务支持完善适合订单状态频繁更新的场景与Python生态的ORM兼容性好前端采用Bootstrap 5 jQuery组合确保在校园机房各种老旧浏览器上都能稳定运行。特别添加了FilePond插件实现拖拽上传大幅改善文件上传体验。2.2 数据库设计核心表结构设计如下简化版CREATE TABLE users ( id int(11) NOT NULL AUTO_INCREMENT, student_id varchar(20) NOT NULL COMMENT 学号, password varchar(255) NOT NULL, name varchar(50) NOT NULL, PRIMARY KEY (id), UNIQUE KEY idx_student_id (student_id) ); CREATE TABLE print_orders ( id int(11) NOT NULL AUTO_INCREMENT, user_id int(11) NOT NULL, file_path varchar(255) NOT NULL COMMENT 文件存储路径, print_config json NOT NULL COMMENT 打印配置{color:bool, duplex:bool, copies:int}, status enum(pending,processing,completed,picked) NOT NULL DEFAULT pending, create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, complete_time datetime DEFAULT NULL, PRIMARY KEY (id), KEY idx_user_id (user_id), KEY idx_status (status) );注意实际部署时应将文件存储在非Web根目录的位置并通过Nginx做访问控制避免直接文件访问漏洞。3. 核心功能实现3.1 文件上传处理文件上传是系统的关键功能我通过Flask的request.files处理上传流并添加了多重防护app.route(/upload, methods[POST]) def upload_file(): if file not in request.files: return jsonify({error: No file part}), 400 file request.files[file] if file.filename : return jsonify({error: No selected file}), 400 # 文件类型白名单验证 allowed_extensions {pdf, doc, docx, ppt, pptx} if not (. in file.filename and file.filename.rsplit(., 1)[1].lower() in allowed_extensions): return jsonify({error: File type not allowed}), 415 # 生成唯一文件名 filename secure_filename(file.filename) unique_name f{uuid.uuid4().hex}_{filename} save_path os.path.join(current_app.config[UPLOAD_FOLDER], unique_name) try: file.save(save_path) # 创建打印订单记录 order PrintOrder( user_idcurrent_user.id, file_pathunique_name, print_configrequest.json.get(config, {}) ) db.session.add(order) db.session.commit() return jsonify({order_id: order.id}), 201 except Exception as e: current_app.logger.error(fFile upload failed: {str(e)}) return jsonify({error: Upload failed}), 500安全注意事项必须使用secure_filename处理原始文件名必须设置文件类型白名单上传目录权限应设为755运行用户只写不执行定期清理超过30天的未打印文件3.2 打印状态实时更新采用Server-Sent Events(SSE)实现低成本的实时状态推送app.route(/order/status/int:order_id) def order_status(order_id): def generate(): order PrintOrder.query.get_or_404(order_id) last_id 0 while True: # 查询最新状态 current_status PrintOrder.query.with_entities( PrintOrder.status ).filter_by(idorder_id).first() if current_status[0] ! order.status: order.status current_status[0] yield fdata: {json.dumps({status: order.status})}\n\n time.sleep(5) # 5秒轮询一次 return Response(generate(), mimetypetext/event-stream)前端通过EventSource接收更新const eventSource new EventSource(/order/status/${orderId}); eventSource.onmessage function(e) { const data JSON.parse(e.data); updateUI(data.status); // 更新页面状态显示 };4. 取件验证系统4.1 二维码取件方案采用动态二维码实现无接触取件核心流程订单完成时生成取件码6位数字将取件码与订单ID绑定存入Redis设置5分钟过期前端生成含取件码的二维码打印店扫码枪扫描后验证取件码# 生成取件码 def generate_pickup_code(order_id): code .join(random.choices(0123456789, k6)) redis_client.setex(fpickup:{code}, 300, order_id) return code # 验证取件码 app.route(/verify-pickup, methods[POST]) def verify_pickup(): code request.json.get(code) if not code or len(code) ! 6: return jsonify({valid: False}), 400 order_id redis_client.get(fpickup:{code}) if not order_id: return jsonify({valid: False}), 404 order PrintOrder.query.get(order_id) if order.status ! completed: return jsonify({valid: False, reason: order_not_ready}), 400 order.status picked db.session.commit() redis_client.delete(fpickup:{code}) return jsonify({valid: True, order_id: order_id})4.2 硬件对接方案对于预算充足的打印店我推荐以下硬件组合斑马ZD420热敏标签打印机 - 用于打印取件单霍尼韦尔1900GSR扫码枪 - 支持各类二维码识别树莓派4B作为控制终端 - 运行定制化的取件界面硬件连接拓扑[扫码枪] --USB-- [树莓派] --WiFi-- [服务器] | [标签打印机]5. 部署与优化实践5.1 生产环境部署推荐使用Gunicorn Nginx的组合部署# 安装Gunicorn pip install gunicorn # 启动命令使用4个工作进程 gunicorn -w 4 -b 127.0.0.1:8000 app:appNginx配置关键点location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /uploads { internal; # 禁止直接访问 alias /path/to/upload/folder; }5.2 性能优化技巧数据库连接池配置from sqlalchemy.pool import QueuePool engine create_engine( app.config[SQLALCHEMY_DATABASE_URI], poolclassQueuePool, pool_size10, max_overflow20, pool_recycle3600 )文件上传优化使用Nginx直接处理大文件上传配置client_max_body_size 100M;默认只有1MB限制启用上传进度显示前端使用axios的onUploadProgress缓存策略热门打印模板缓存到Redis使用Flask-Caching插件缓存静态页面配置合适的Cache-Control头6. 常见问题排查6.1 文件上传失败现象413 Request Entity Too Large解决Nginx配置调整client_max_body_size 100M;Flask配置调整app.config[MAX_CONTENT_LENGTH] 100 * 1024 * 10246.2 数据库连接泄漏现象运行一段时间后出现Too many connections错误解决方案确保每次请求后关闭sessionapp.teardown_appcontext def shutdown_session(exceptionNone): db.session.remove()配置SQLAlchemy连接池回收时间app.config[SQLALCHEMY_POOL_RECYCLE] 3600 # 1小时6.3 二维码识别率低优化措施增加二维码容错级别使用qrcode库时设置error_correctionqrcode.constants.ERROR_CORRECT_H确保打印分辨率不低于300dpi二维码尺寸建议保持在3×3cm以上背景与前景色对比度要足够高7. 扩展功能建议在实际运营中我发现以下几个增值功能很受师生欢迎批量打印优惠识别同一用户的连续订单自动计算折扣如满10元减1元前端展示累计节省金额智能排版服务def auto_adjust_layout(file_path): # 使用pdfminer分析PDF文档 # 自动调整边距、缩放比例 # 返回优化后的打印配置 pass打印店负载看板实时显示各时段预约量预测等待时间通过微信小程序推送叫号通知环保报告功能计算节约的纸张数量显示相当于保护了多少树木生成个人打印环保报告这个系统在我校打印店运行半年后平均等待时间从23分钟降至6分钟打印错误率下降68%学生满意度提升至4.8/5.0。最关键的是帮打印店老板实现了订单数字化管理再也不用在纸质登记本上翻找订单了。