最近在技术社区看到不少关于餐饮系统开发的讨论,正好我去年用Python+Flask+Vue这套技术栈完整实现过一个餐厅点餐管理系统。这个项目从后台管理到移动端点餐全流程打通,期间踩过不少坑也积累了些实战经验。不同于常见的Django方案,选择Flask作为后端框架主要考虑到餐饮行业特有的灵活需求——比如需要频繁对接第三方配送平台、支付接口,以及应对高峰期的并发压力。
整套系统采用前后端分离架构:
关键决策:之所以没选Django而用Flask,是因为餐厅业务常有定制化需求(如特殊折扣规则),Flask的轻量级特性更便于快速调整。实测在订单高峰时段,这套架构能稳定处理300+并发请求。
餐饮系统的用户角色复杂程度常被低估。我们设计了5种用户类型:
python复制# 用户模型示例(Flask-SQLAlchemy)
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
password_hash = db.Column(db.String(128))
role = db.Column(db.Enum('customer','waiter','chef','manager','admin'))
last_login = db.Column(db.DateTime)
def verify_password(self, password):
return check_password_hash(self.password_hash, password)
订单状态机是系统的核心逻辑,我们采用状态模式实现:
mermaid复制stateDiagram
[*] --> 待支付
待支付 --> 已取消: 超时未支付
待支付 --> 已支付: 完成支付
已支付 --> 制作中: 后厨接单
制作中 --> 已上菜: 菜品完成
已上菜 --> 已完成: 确认收货
已上菜 --> 投诉中: 顾客反馈
(注:实际开发中用Python的transitions库实现状态机)
餐饮行业对库存敏感度极高,我们实现了三级预警机制:
python复制# 定时任务检查库存(Celery Beat)
@app.task
def check_inventory():
ingredients = Ingredient.query.filter(
Ingredient.quantity < Ingredient.safety_stock
).all()
for item in ingredients:
ratio = item.quantity / item.safety_stock
if ratio < 0.2:
send_alert(item, level='red')
elif ratio < 0.5:
send_alert(item, level='orange')
else:
send_alert(item, level='yellow')
采用RESTful风格设计时,有几个餐饮行业特有的注意事项:
python复制# 典型API端点示例
api.add_resource(MenuAPI, '/api/menu/<int:category_id>')
api.add_resource(OrderAPI, '/api/order', '/api/order/<int:order_id>')
api.add_resource(PaymentAPI, '/api/payment/<string:order_no>')
餐饮系统对页面响应速度要求极高,我们做了这些优化:
javascript复制// 订单状态实时更新(Vue + Socket.io)
mounted() {
this.socket = io('https://api.restaurant.com')
this.socket.on('order_update', (data) => {
const index = this.orders.findIndex(o => o.id === data.id)
if (index >= 0) {
this.$set(this.orders, index, data)
}
})
}
周五晚上用餐高峰期的系统压力测试数据:
我们采用的解决方案:
几个必装的插件:
重要设置:开启"Live Templates"功能,快速生成Flask路由模板
python复制# Flask-CORS配置
CORS(app, resources={
r"/api/*": {
"origins": ["http://localhost:8080"],
"methods": ["GET", "POST", "PUT", "DELETE"],
"allow_headers": ["Content-Type"]
}
})
现象:15%的订单在未支付状态下未自动关闭
排查过程:
解决方案:
dockerfile复制# Dockerfile增加时区配置
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime
现象:部分中文字符打印为问号
排查步骤:
修复代码:
javascript复制axios.defaults.headers.post['Content-Type'] =
'application/x-www-form-urlencoded;charset=GB2312'
nginx复制# 静态文件缓存配置
location /static {
alias /var/www/restaurant/static;
expires 30d;
add_header Cache-Control "public";
}
# WebSocket代理配置
location /socket.io {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
python复制# 登录限流实现
from flask_limiter import Limiter
limiter = Limiter(
app,
key_func=get_remote_address,
default_limits=["200 per day", "50 per hour"]
)
@app.route('/login', methods=['POST'])
@limiter.limit("10 per minute")
def login():
# 登录逻辑
这套系统上线后稳定运行9个月,最高单日处理订单量达2,837单。最大的收获是认识到餐饮系统的特殊性——不仅是个技术产品,更要理解餐饮行业的业务流程。比如后厨打印单据的字体大小、订单超时时间的设置(我们最终定为15分钟),都需要实际观察餐厅运营才能确定最佳值。