1. 项目概述:Python台球厅管理系统开发实录
去年帮本地一家台球厅升级管理系统时,我基于Python生态的Flask+Django混合架构开发了一套开台计费系统。这种混合架构既能利用Django的ORM和Admin快速搭建后台,又能通过Flask的灵活性实现定制化前端交互。系统上线后,老板反馈每月人工统计时长的工作量减少了80%,错单率从15%降到3%以下。
传统台球厅管理普遍存在几个痛点:手工记录开台时间易出错、不同时段费率计算复杂、交接班对账困难。这套系统核心要解决的就是这三个问题,同时需要兼顾收银员的操作效率和老板的数据可视化需求。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术选型与架构设计
2.1 为什么选择混合架构
Django的全家桶优势在后台管理场景非常明显:
- 自带Admin后台可快速实现员工权限管理
- ORM简化了台桌状态、会员信息等数据模型定义
- 内置的Auth模块直接满足登录认证需求
但纯Django模板在前端交互上比较笨重,因此我在用户端采用Flask+Jinja2:
- 轻量级路由更适合频繁的AJAX请求(如计时器刷新)
- 可自由组合前端组件(我们用了Vue.js实现实时计时看板)
- 更灵活的WSGI部署方案(最终采用Nginx+Gunicorn方案)
2.2 数据库设计要点
核心表结构设计考虑了台球厅的特殊业务场景:
python复制class BilliardTable(models.Model):
STATUS_CHOICES = [
('free', '空闲'),
('in_use', '使用中'),
('maintenance', '维修中')
]
number = models.CharField(max_length=10, unique=True)
status = models.CharField(max_length=20, choices=STATUS_CHOICES)
hourly_rate = models.DecimalField(max_digits=6, decimal_places=2)
class Session(models.Model):
table = models.ForeignKey(BilliardTable, on_delete=models.PROTECT)
start_time = models.DateTimeField(auto_now_add=True)
end_time = models.DateTimeField(null=True)
total_amount = models.DecimalField(max_digits=10, decimal_places=2)
is_paid = models.BooleanField(default=False)
特别注意:
- 采用DecimalField而非FloatField存储金额,避免浮点精度问题
- 会话表设计为"开始即插入记录",避免漏单
- 通过status字段实现简单的状态机控制
3. 核心功能实现细节
3.1 动态计费算法实现
台球厅常有分时段计价需求,比如:
- 工作日白天80元/小时
- 工作日晚上/周末100元/小时
- 会员享8折优惠
在models.py中定义计费规则:
python复制def calculate_amount(start, end, is_member=False):
weekday = start.weekday()
base_rate = 100 if weekday >= 5 or start.hour >= 18 else 80
duration = (end - start).total_seconds() / 3600
amount = base_rate * duration
return amount * 0.8 if is_member else amount
重要提示:实际业务中建议将费率配置抽离到数据库,避免硬编码
3.2 实时计时看板开发
前端采用Vue.js实现动态刷新,关键代码:
javascript复制// 每10秒刷新一次剩余时间
setInterval(() => {
axios.get('/api/session/remaining')
.then(response => {
this.remaining = response.data.remaining
this.amount = response.data.amount
})
}, 10000)
后端接口示例:
python复制@app.route('/api/session/remaining')
def get_remaining():
session = Session.objects.filter(end_time__isnull=True).first()
if session:
elapsed = datetime.now() - session.start_time
return jsonify({
'remaining': str(elapsed),
'amount': calculate_amount(session.start_time, datetime.now())
})
4. 部署与性能优化
4.1 生产环境部署方案
采用Docker Compose编排服务:
yaml复制version: '3'
services:
web:
build: .
command: gunicorn -w 4 -b :8000 main:app
volumes:
- .:/code
ports:
- "8000:8000"
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
4.2 高频写入场景优化
台球厅高峰时段可能同时有几十张台子频繁更新状态,我们做了这些优化:
- 为session表的start_time字段添加索引
- 使用Django的select_for_update()处理并发开台
- 重要操作记录审计日志(如修改费率)
5. 实际运营中的经验总结
5.1 收银员培训要点
系统上线后我们发现几个常见操作问题:
- 误触"结束会话"按钮 → 解决方案:添加二次确认弹窗
- 忘记切换会员账号 → 增加会员卡刷卡器集成
- 交接班时漏打印对账单 → 系统自动生成交接班报告
5.2 硬件集成建议
经过实测推荐这些外设:
- 佳博GP-5890X热敏打印机(小票打印)
- 新大陆FR20扫码枪(会员二维码识别)
- 客显屏显示金额(减少沟通错误)
这套系统经过三个月的迭代,目前已经稳定运行一年多。最大的收获是认识到:即使是看似简单的台球厅管理,在计费规则、状态管理和硬件集成等方面都有很多细节需要考虑。后续计划加入手机预约和智能灯控功能,进一步提升运营效率。
