去年接手某连锁酒店数字化改造项目时,我基于Flask+Vue技术栈实现了一套三角色协同的管理系统。这套系统不仅需要处理高并发的客房预订业务,还要满足前台、客房服务和经理三个角色的差异化需求。本文将完整还原从技术选型到具体实现的思考过程,特别分享如何用PyCharm高效组织前后端分离项目的实战经验。
系统采用前后端分离架构,后端使用Flask构建RESTful API,前端采用Vue.js实现动态交互界面,数据库选用MySQL关系型数据库。三个角色分别对应:
提示:本文所有代码示例均基于Python 3.8+和Vue 2.6+环境,建议使用PyCharm Professional版获得完整的全栈开发支持
虽然项目标题提到Django,但实际开发中我们选择了更轻量级的Flask框架,主要基于以下考量:
python复制# 典型Flask Blueprint结构示例
from flask import Blueprint
room_bp = Blueprint('room', __name__)
@room_bp.route('/status', methods=['GET'])
def get_room_status():
# 实现客房状态查询逻辑
pass
前端采用Vue CLI创建的工程化项目结构,关键配置要点:
javascript复制// src/utils/http.js
axios.interceptors.response.use(
response => response,
error => {
if (error.response.status === 401) {
router.push('/login')
}
return Promise.reject(error)
}
)
javascript复制// src/router/index.js
router.beforeEach((to, from, next) => {
const userRole = store.getters.role
if (to.meta.roles && !to.meta.roles.includes(userRole)) {
next('/403')
} else {
next()
}
})
前台最核心的功能是可视化房态管理,我们采用的技术方案:
python复制# 后端事件推送逻辑
@socketio.on('connect')
def handle_connect():
emit('room_update', get_current_room_status())
@app.route('/check_in', methods=['POST'])
def check_in():
# 办理入住业务逻辑
socketio.emit('room_update', get_current_room_status())
客房服务模块的核心是智能任务分配,我们设计的调度策略:
python复制def assign_cleaning_task(room_list):
# 按楼层分组
floor_groups = defaultdict(list)
for room in room_list:
floor_groups[room.floor].append(room)
# 分配逻辑
tasks = []
for floor, rooms in floor_groups.items():
sorted_rooms = sorted(rooms, key=lambda x: x.priority, reverse=True)
tasks.extend(optimize_route(sorted_rooms))
return tasks
在PyCharm中配置Compound启动项,一键启动:
操作路径:Run -> Edit Configurations -> + -> Compound
初期采用简单的SELECT+UPDATE模式导致超卖问题,最终解决方案:
SELECT ... FOR UPDATEpython复制def reserve_room(room_id):
with redis.lock(f'room_{room_id}', timeout=5):
room = Room.query.filter_by(id=room_id).first()
if room.status == 'available':
room.status = 'reserved'
db.session.commit()
javascript复制// 路由懒加载示例
const ManagerDashboard = () => import('./views/ManagerDashboard.vue')
采用RBAC(基于角色的访问控制)模型,核心表结构:
| 表名 | 关键字段 |
|---|---|
| user | id, username, password_hash |
| role | id, name (前台/客房/经理) |
| permission | id, endpoint, method |
| user_roles | user_id, role_id |
| role_perms | role_id, permission_id |
权限验证中间件示例:
python复制def permission_required(permission):
def decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
if not current_user.can(permission):
abort(403)
return f(*args, **kwargs)
return wrapper
return decorator
测试环境与生产环境的不同配置:
| 环境 | 后端 | 前端 | 数据库 |
|---|---|---|---|
| 开发 | Flask调试模式 | Vue开发服务器 | 本地MySQL |
| 测试 | Gunicorn | Nginx静态服务 | Docker MySQL |
| 生产 | uWSGI+Nginx | CDN分发 | AWS RDS |
关键Nginx配置片段:
nginx复制location /api {
include uwsgi_params;
uwsgi_pass 127.0.0.1:5000;
}
location / {
root /var/www/hotel-frontend;
try_files $uri $uri/ /index.html;
}
经理看板的核心指标计算:
使用Pandas进行数据分析的典型代码:
python复制def generate_daily_report(date):
query = session.query(
Room.type,
func.count(Booking.id),
func.sum(Booking.total_price)
).join(Booking).filter(
Booking.check_in_date <= date,
Booking.check_out_date > date
).group_by(Room.type)
df = pd.read_sql(query.statement, session.bind)
df['occupancy'] = df['count_1'] / Room.type_count[df['type']]
df['revpar'] = df['sum_1'] / Room.type_count[df['type']]
return df
在实际运营过程中,我们陆续增加了以下功能:
特别提醒:在开发人脸识别模块时,务必注意:
完整的环境搭建步骤:
bash复制python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
bash复制npm install -g @vue/cli
cd frontend && npm install
sql复制CREATE DATABASE hotel CHARSET utf8mb4;
GRANT ALL ON hotel.* TO 'hotel'@'%' IDENTIFIED BY 'securepassword';
code复制# .env文件示例
FLASK_SECRET_KEY=your_random_string
DB_URI=mysql+pymysql://user:pass@localhost/hotel