Flask轻量级进销存系统开发实战与优化

Flask轻量级进销存系统开发实战与优化 1. 项目概述Flask小型超市进销存系统开发实录去年帮老家亲戚的小超市做库存管理时我用了三天时间基于Flask搭建了一套轻量级进销存系统。这个经历让我意识到对于日均流水2万以下的小型商超完全没必要用复杂的商业软件。今天就把这套经过实战检验的方案完整分享出来包含商品管理、进货登记、销售记录、库存预警等核心功能特别适合5-20人团队使用。系统采用经典的B/S架构前端用BootstrapECharts实现响应式布局后端用FlaskSQLAlchemy构建RESTful API。实测在树莓派4B上能稳定支持50个并发请求库存数据同步延迟小于200ms。所有功能模块都经过本地化改造比如支持扫码枪快速录入商品、小票打印机自动适配等实际场景需求。2. 技术选型与架构设计2.1 为什么选择Flask框架相比Django的全家桶方案Flask的轻量级特性更适合小型项目快速迭代。实际开发中我发现几个优势路由系统简洁明了添加新API只需30秒Jinja2模板与前端组件天然契合扩展机制让功能模块化比如用Flask-Login处理鉴权调试模式下的热重载对前端开发极其友好典型的路由配置示例app.route(/api/goods, methods[GET]) login_required def get_goods_list(): page request.args.get(page, 1, typeint) per_page min(request.args.get(per_page, 10, typeint), 100) pagination Goods.query.paginate(page, per_page) return jsonify({ items: [good.to_dict() for good in pagination.items], total: pagination.total })2.2 数据库设计要点采用SQLite作为开发环境数据库生产环境可无缝切换MySQL。核心表结构设计考虑了几个实际场景商品表增加barcode字段支持扫码录入库存记录包含batch_no追踪不同进货批次销售明细记录支付方式现金/微信/支付宝class Goods(db.Model): __tablename__ goods id db.Column(db.Integer, primary_keyTrue) name db.Column(db.String(64), indexTrue) barcode db.Column(db.String(32), uniqueTrue) spec db.Column(db.String(32)) # 规格如500ml/瓶 category_id db.Column(db.Integer, db.ForeignKey(category.id)) purchase_price db.Column(db.Numeric(10,2)) selling_price db.Column(db.Numeric(10,2)) stock db.Column(db.Integer, default0) alert_stock db.Column(db.Integer) # 库存预警值3. 核心功能实现细节3.1 商品扫码入库流程优化通过监听USB扫码枪的输入事件开发了极速入库模式document.addEventListener(keypress, (e) { if(e.timeStamp - lastKeyTime 50){ // 扫码枪快速输入特征 barcodeStr String.fromCharCode(e.charCode); lastKeyTime e.timeStamp; if(e.charCode 13){ // 回车符结束 fetchGoodsInfo(barcodeStr); barcodeStr ; } } });实测对比传统手动录入120秒/件扫码录入15秒/件3.2 实时库存计算策略采用触发器缓存方案解决并发问题app.route(/api/sale, methods[POST]) def create_sale(): try: goods_id request.json[goods_id] quantity request.json[quantity] # 使用SELECT FOR UPDATE锁定记录 goods db.session.query(Goods).filter_by(idgoods_id).with_for_update().first() if goods.stock quantity: return jsonify({error: 库存不足}), 400 goods.stock - quantity db.session.commit() # 更新Redis缓存 r redis.StrictRedis() r.hincrby(stock_cache, goods_id, -quantity) return jsonify({success: True}) except Exception as e: db.session.rollback() return jsonify({error: str(e)}), 5004. 典型问题排查实录4.1 扫码枪兼容性问题现象部分型号扫码枪无法触发输入事件 解决方案在/etc/udev/rules.d/添加设备规则前端增加输入模式切换选项备用方案虚拟键盘捕获4.2 库存不同步异常触发条件高并发销售场景 处理步骤检查Redis与MySQL的同步间隔配置验证事务隔离级别是否为REPEATABLE_READ添加库存操作日志表用于对账class StockLog(db.Model): __tablename__ stock_log id db.Column(db.Integer, primary_keyTrue) goods_id db.Column(db.Integer, db.ForeignKey(goods.id)) operation db.Column(db.String(10)) # IN/OUT quantity db.Column(db.Integer) before_stock db.Column(db.Integer) after_stock db.Column(db.Integer) created_at db.Column(db.DateTime, defaultdatetime.utcnow)5. 部署与性能优化5.1 生产环境部署方案推荐使用GunicornNginx组合gunicorn -w 4 -b 127.0.0.1:8000 manage:appNginx关键配置location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /static { alias /path/to/static/files; expires 30d; }5.2 性能压测数据使用Locust模拟不同场景商品查询API800 QPS带缓存销售出库API120 QPS事务操作库存统计报表40 QPS复杂聚合6. 扩展功能开发建议供应商管理模块class Supplier(db.Model): __tablename__ supplier id db.Column(db.Integer, primary_keyTrue) name db.Column(db.String(64)) contact db.Column(db.String(32)) phone db.Column(db.String(20)) address db.Column(db.Text) settlement_days db.Column(db.Integer) # 账期天数移动端适配技巧使用Flex布局实现自适应添加PWA离线支持微信小程序封装方案这套系统在亲戚店里运行8个月后库存准确率从原来的76%提升到99.3%每月盘库时间从6小时缩短到40分钟。最让我意外的是通过销售数据分析优化了货架摆放后某些品类销售额提升了15%。