用户进入房屋信息页面,点击“即刻预定的按钮”,那么client将会发送get请求booking.html?hid=HID ;后台接受到请求,返回booking.html静态页面,并且加载所有相关静态文件,包括booking.js。
// TODO: 判断用户是否登录
$.get('/api/v1.0/session',function(resp){
if(resp.errno=='0'){
if(!(resp.data.user_id && resp.data.name)){
location.href='login.html'
}
}
});
@api.route('/session')
def check_login():
user_id = session.get("user_id")
name = session.get("name")
return jsonify(errno=RET.OK, errmsg="OK", data={"user_id": user_id, "name": name})
client通过book.js文件发送ajax请求/api/v1.0/session,server接受到请求,会去请求上下文session中获取用户的名字和id,并返回name和id,没有登陆返回none。如果返回的结果是none,那么将会跳转到登陆页面;
function decodeQuery(){
var search = decodeURI(document.location.search);
return search.replace(/(^\?)/,'').split('&').reduce(function(result, item){
values = item.split('=');
result[values[0]] = values[1];
return result;
}, {});
}
var queryData = decodeQuery();
var houseId = queryData["hid"];
// TODO: 获取房屋的基本信息
$.get("/api/v1.0/houses/" + houseId, function (resp) {
if (resp.errno == "0") {
$(".house-info>img").attr("src", resp.data.house.img_urls[0]);
$(".house-text>h3").html(resp.data.house.title);
$(".house-text>p>span").html((resp.data.house.price / 100).toFixed(0))
}});
@api.route("/houses/")
def get_house_detail(house_id):
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.NODATA, errmsg="房屋不存在")
house_dict = house.to_full_dict()
return jsonify(errno=RET.OK, errmsg="OK", data={"user_id": user_id, "house": house_dict})
client通过book.js文件,首先获取url中的房屋id,然后发送ajax get请求/api/v1.0/houses/” + houseId,后台通过请求参数中的houseid,去数据库中查询房屋的信息,返回给前端,前端通过js渲染页面。
// TODO: 订单提交
$(".submit-btn").on("click", function () {
var startDate = $("#start-date").val();
var endDate = $("#end-date").val();
if (!(startDate && endDate)) {
return
}
var params = {
"start_date": startDate,
"end_date": endDate,
"house_id": houseId
};
$.ajax({
url: "/api/v1.0/orders",
type: "post",
headers: {
"X-CSRFToken": getCookie('csrf_token')
},
data: JSON.stringify(params),
contentType: "application/json",
success: function (resp) {
if (resp.errno == "0"){
location.href = "/orders.html"
}else if (resp.errno == "4101") {
location.href = "/login.html"
}else {
alert(resp.errmsg)
}
}
})
})
@api.route("/orders", methods=["POST"])
@login_required
def add_order():
# 1. 获取参数
user_id = g.user_id
data_json = request.json
house_id = data_json.get("house_id")
start_date_str = data_json.get("start_date")
end_date_str = data_json.get("end_date")
# 2. 校验参数
if not all([house_id, start_date_str, end_date_str]):
return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
try:
# 将日期字符串转成 datetime 对象
start_date = datetime.datetime.strptime(start_date_str, "%Y-%m-%d")
end_date = datetime.datetime.strptime(end_date_str, "%Y-%m-%d")
# 判断开始时间与结束时间的大小
assert start_date < end_date, Exception("结束时间必须大于开始时间")
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
# 3. 判断房屋是否存在
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.NODATA, errmsg="房屋不存在")
# 判断是否是房主去预订
if user_id == house.user_id:
return jsonify(errno=RET.ROLEERR, errmsg="房东不能预订")
# 4. 判断该房屋指定时间段内是否有冲突的订单
try:
filters = [Order.house_id == house_id, Order.begin_date < end_date, Order.end_date > start_date]
# 取到冲突订单的数量
order_count = Order.query.filter(*filters).count()
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="查询数据错误")
# 如果冲突订单的数量大于0,代表该房屋已被预订
if order_count > 0:
return jsonify(errno=RET.DATAERR, errmsg="房屋已被预订")
# 5. 生成订单模型
order = Order()
# 设置属性值
days = (end_date - start_date).days
order.user_id = user_id
order.house_id = house_id
order.begin_date = start_date
order.end_date = end_date
order.days = days
order.house_price = house.price
order.amount = days * house.price
# 将房屋的订单数量加1
house.order_count += 1
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")
当用户点击提交按钮, client将发送ajax post请求/api/v1.0/orders,post推送的数据有,租住的开始时间,结束时间,和房屋id。后台首先获取参数,包括从g变量中获取user_id,从前端发过来的数据中获取houseid,start_date,end_date,判断参数是否完整,如果不完整,按照接口文档返回参数错误,如果参数完整,判断日期的结束时间是否大于开始时间,如果时间格式,或者结束时间小于开始时间,返回参数错误。否则判断房屋是否存在,如果不存在,返回房屋不存在信息,提醒用户。否则继续判断是否是房东自己预定自己的房子,如果是,则返回错误信息房东不能预定。否则判断下单房子在时间上是否冲突,如果冲突的话提示用户房屋已经被预定了,否则就可以将用户ip,房屋id,开始时间,结束时间,总天数,总价钱写入数据库。