下载地址:https://download.csdn.net/download/geek_xiong/11585216
预定房间功能
在房间详情页提供预定功能,点击进入预定页面,提交预定后页面跳转到我的订单中
房东可在客户订单中查看
后端代码编写
后端需要接收前端传递过来的参数,经过处理与验证后将数据保存到数据库中。
URL:127.0.0.1:5000/api/v1.0/orders/house_id
请求方式:POST
大致流程:
- 获取用户id
- 获取订单信息,房子id,入住时间,结束时间
- 转换时间格式,计算入住的天数
- 判断房子是否存在
- 判断预定用户是否是房东
- 判断这个时间段内,该房子是否被别人下单
- 计算总额
- 保存数据
# POST 127.0.0.1:5000/orders
@api.route("/orders", methods=['POST'])
@login_required
def save_order():
"""保存订单
需要的参数:用户id,房子id,入住与结束的日期
参数要求:json 格式
"""
# 获取用户的 id
user_id = g.user_id
# 获取参数
order_data = request.get_json()
if order_data:
return jsonify(errno=RET.PARAMERR, errmsg='参数错误')
house_id = order_data.get("house_id") # 预订的房屋编号
start_date_str = order_data.get("start_date") # 预订的入住时间
end_date_str = order_data.get("end_date") # 预订的结束时间
# 验证参数的完整性
if not all([house_id, start_date_str, end_date_str]):
return jsonify(errno=RET.PARAMERR, errmsg='参数错误')
# 处理日期
try:
# 将接受的日期字符串转换成日期格式
start_date = datetime.strptime(start_date_str, "%Y-%m%d")
end_date = datetime.strptime(end_date_str, "%y-%m-%d")
assert start_date <= end_date
# 计算预定的天数
days = (end_date - start_date).days + 1 # datetime.timedelta
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.PARAMERR, errmsg='日期格式错误')
# 查询房子是否存在
try:
house = House.query.get(house_id)
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg='获取房屋信息失败')
if not house:
return jsonify(errno=RET.DBERR, errmsg='房子不存在')
# 预定的房屋是否是房东自己
if user_id == house.user_id:
return jsonify(errno=RET.ROLEERR, errmsg='不能预定自己的房屋')
# 确保用户预定的时间内,房屋没有被别人下单
try:
# 查询时间冲突的订单数
count = Order.query.filter(Order.house_id == house_id,
Order.begin_date <= end_date,
Order.end_date >= start_date).count()
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg='检查出错,请稍后重试')
if count > 0:
return jsonify(errno=RET.DATAERR, errmsg="房屋已被预定")
# 预定总额
amount = days * house.price
# 保存订单数据
order = Order(
house_id=house_id,
user_id=user_id,
begin_date=start_date,
end_date=end_date,
days=days,
house_price=house.price,
amount=amount
)
try:
db.session.add(order)
db.session.commit()
except Exception as e:
current_app.logger.error(e)
db.session.rollback()
return jsonify(errno=RET.DBERR, errmsg='保存订单失败')
return jsonify(errno=RET.OK, errmsg='OK', data={"order_id": order.id})
我的订单
提交订单后,跳转到“我的订单”页面,倒叙显示提交的订单,状态为“待结单”,如果房东接单,则显示“待支付”
后端代码编写
URL:127.0.0.1:5000/api/v1.0/user/orders?role=xxx
role:custom(房客)、landlord(房东)
请求方式:GET
大致流程:
- 获取用户id
- 获取用户点击的是“我的订单”还是“客户订单”参数
- 如果是房东(客户订单)
- 先在房子表中获取所有属于自己的房子
- 在订单表中获取自己的房子中被下订单的所有的订单
- 如果是房客(我的订单)
- 查询自己预定的订单
- 将数据转换为字典
- 返回结果
# GET 127.0.0.1:5000/api/v1.0/user/orders?role=custom role=landlord
@api.route("/user/orders", methods=["GET"])
@login_required
def get_user_orders():
"""查询用户的订单信息"""
# 获取用户的 id
user_id = g.user_id
# 用户的身份,用户想要查询作为房客预定别人房子的订单,
# 还是想要作为房东查询别人下的订单
role = request.args.get("role", "")
# 查询订单信息
try:
if "landlord" == role:
# 以房东的身份查询订单,先查询属于自己的房子有哪些
houses = House.query.filter(House.user_id==user_id).all()
houses_ids = [house.id for house in houses]
# 再查询预定了自己房子的订单
orders = Order.query.filter(Order.house_id.in_(houses_ids)).order_by(Order.create_time.desc()).all()
else:
orders = Order.query.filter(Order.user_id==user_id).order_by(Order.create_time.desc()).all()
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg='查询订单信息失败')
# 将订单信息转换为字典数据
orders_dict_list = []
if orders:
for order in orders:
orders_dict_list.append(order.to_dict())
return jsonify(errno=RET.OK, errmsg="OK", data={"orders": orders_dict_list})
接单、拒单
接单和拒单是房东的权限,即在“客户订单”页面,如果有客户预定了该房东的房子,会显示在该页面,并显示接单和拒单的按钮。
后端代码编写
URL:127.0.0.1:5000/api/v1.0/orders/orderId/status
请求方式:PUT
大致流程:
- 获取用户id
- 获取请求方式(接单、拒单)
- 根据订单号查询该订单(要求待结单状态)
- 判断用户是否是该房子的房东
- 根据请求方式各自处理
- 如果是接单,将订单状态改为“待支付”
- 如果是拒单,获取拒单原因,将订单状态改为“已拒绝”
- 提交,更新数据库表
# PUT 127.0.0.1:5000/api/v1.0/orders/orderId/status
@api.route("/orders/<int:order_id>/status", methods=['PUT'])
@login_required
def accept_reject_order(order_id):
"""
接单、拒单
:param order_id: 订单 id
:return:
"""
# 获取用户id
user_id = g.user_id
# 获取参数
req_data = request.get_json()
if not req_data:
return jsonify(errno=RET.PARAMERR, errmsg='参数错误')
# action参数表明客户端请求的是接单还是拒单的行为
action = req_data.get("action")
if action not in ("accept", "reject"):
return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
try:
# 根据订单号查询订单,并且要求订单处于等待接单状态
order = Order.query.filter(Order.id==order_id, Order.status=="WAIT_ACCEPT").first()
house = order.house
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg='无法获取订单数据')
# 确保房东只能修改属于自己房子的订单
if not order or house.user_id != user_id:
return jsonify(errno=RET.REQERR, errmsg='操作无效')
if action == 'accept':
# 接单,将订单状态设置为等待支付
order.status = "WAIT_PAYMENT"
elif action == 'reject':
# 拒单,要求用户传递拒单原因
reason = req_data.get("reason")
if not reason:
return jsonify(errno=RET.PARAMERR, errmsg='参数错误')
order.status = "REJECTED"
order.comment = reason
try:
db.session.add(order)
db.session.commit()
except Exception as e:
current_app.logger.error(e)
db.session.rollback()
return jsonify(errno=RET.DBERR, errmsg='操作失败')
return jsonify(errno=RET.OK, errmsg='OK')