完成大作业服务端代码,新建管理端,管理端不可用
This commit is contained in:
0
Project/Service/func/__init__.py
Normal file
0
Project/Service/func/__init__.py
Normal file
BIN
Project/Service/func/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
Project/Service/func/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Project/Service/func/__pycache__/book.cpython-311.pyc
Normal file
BIN
Project/Service/func/__pycache__/book.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Project/Service/func/__pycache__/cancel_order.cpython-311.pyc
Normal file
BIN
Project/Service/func/__pycache__/cancel_order.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Project/Service/func/__pycache__/config.cpython-311.pyc
Normal file
BIN
Project/Service/func/__pycache__/config.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Project/Service/func/__pycache__/get_db.cpython-311.pyc
Normal file
BIN
Project/Service/func/__pycache__/get_db.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Project/Service/func/__pycache__/index.cpython-311.pyc
Normal file
BIN
Project/Service/func/__pycache__/index.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Project/Service/func/__pycache__/login.cpython-311.pyc
Normal file
BIN
Project/Service/func/__pycache__/login.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Project/Service/func/__pycache__/modify.cpython-311.pyc
Normal file
BIN
Project/Service/func/__pycache__/modify.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Project/Service/func/__pycache__/order.cpython-311.pyc
Normal file
BIN
Project/Service/func/__pycache__/order.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Project/Service/func/__pycache__/order_list.cpython-311.pyc
Normal file
BIN
Project/Service/func/__pycache__/order_list.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Project/Service/func/__pycache__/pay.cpython-311.pyc
Normal file
BIN
Project/Service/func/__pycache__/pay.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Project/Service/func/__pycache__/pay_confirm.cpython-311.pyc
Normal file
BIN
Project/Service/func/__pycache__/pay_confirm.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Project/Service/func/__pycache__/search.cpython-311.pyc
Normal file
BIN
Project/Service/func/__pycache__/search.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Project/Service/func/__pycache__/signup.cpython-311.pyc
Normal file
BIN
Project/Service/func/__pycache__/signup.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Project/Service/func/__pycache__/utils.cpython-311.pyc
Normal file
BIN
Project/Service/func/__pycache__/utils.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Project/Service/func/__pycache__/verify_user.cpython-311.pyc
Normal file
BIN
Project/Service/func/__pycache__/verify_user.cpython-311.pyc
Normal file
Binary file not shown.
92
Project/Service/func/book.py
Normal file
92
Project/Service/func/book.py
Normal file
@@ -0,0 +1,92 @@
|
||||
from flask import render_template, request, redirect, url_for, g, flash, session
|
||||
from .config import db
|
||||
import pymysql
|
||||
from datetime import datetime
|
||||
|
||||
def book():
|
||||
flight_id = request.args.get('flight_id')
|
||||
if request.method == 'GET':
|
||||
if not g.user:
|
||||
return redirect(url_for("login"))
|
||||
conn = pymysql.connect(**db)
|
||||
cursor = conn.cursor(pymysql.cursors.DictCursor)
|
||||
flight_sql = """
|
||||
SELECT f.*, d.Name as Departure_airport_name, a.Name as Arrival_airport_name
|
||||
FROM Flights f
|
||||
JOIN Airports d ON f.Departure_airport = d.ID
|
||||
JOIN Airports a ON f.Arrival_airport = a.ID
|
||||
WHERE f.ID = %s;
|
||||
"""
|
||||
cursor.execute(flight_sql, (flight_id,))
|
||||
flight = cursor.fetchone()
|
||||
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
return render_template('book.html', flight=flight, username=g.name)
|
||||
|
||||
if request.method == 'POST':
|
||||
passengers = []
|
||||
passenger_keys = ['card_code', 'name', 'phone_number', 'seat_class']
|
||||
|
||||
for i in range(len(request.form) // len(passenger_keys)):
|
||||
passenger = {}
|
||||
for key in passenger_keys:
|
||||
passenger[key] = request.form.get(f'passengers[{i}][{key}]')
|
||||
passengers.append(passenger)
|
||||
|
||||
conn = pymysql.connect(**db)
|
||||
cursor = conn.cursor()
|
||||
|
||||
try:
|
||||
# 插入订单记录
|
||||
insert_order_sql = """
|
||||
INSERT INTO Orders (Order_time, Paid, User_phone_number)
|
||||
VALUES (%s, 0, %s)
|
||||
"""
|
||||
cursor.execute(insert_order_sql, (datetime.now(), g.user))
|
||||
order_id = cursor.lastrowid
|
||||
|
||||
for passenger in passengers:
|
||||
passenger_id = passenger['card_code']
|
||||
name = passenger['name']
|
||||
phone_number = passenger['phone_number']
|
||||
seat_class = passenger['seat_class']
|
||||
|
||||
price_field = f"{seat_class.replace(' ', '_').lower()}_price"
|
||||
price_sql = f"SELECT {price_field} FROM Flights WHERE ID = %s"
|
||||
cursor.execute(price_sql, (flight_id,))
|
||||
price = cursor.fetchone()[0]
|
||||
|
||||
insert_passenger_sql = """
|
||||
INSERT INTO Passengers (ID, Name, Phone_number)
|
||||
VALUES (%s, %s, %s)
|
||||
ON DUPLICATE KEY UPDATE Name=VALUES(Name), Phone_number=VALUES(Phone_number);
|
||||
"""
|
||||
cursor.execute(insert_passenger_sql, (passenger_id, name, phone_number))
|
||||
|
||||
update_seat_sql = f"""
|
||||
UPDATE Flights
|
||||
SET {seat_class.replace(' ', '_').lower()}_seats_remaining = {seat_class.replace(' ', '_').lower()}_seats_remaining - 1
|
||||
WHERE ID = %s
|
||||
"""
|
||||
cursor.execute(update_seat_sql, (flight_id,))
|
||||
|
||||
insert_ticket_sql = """
|
||||
INSERT INTO Tickets (Price, FlightID, Seat_class, PassengerID, OrderID)
|
||||
VALUES (%s, %s, %s, %s, %s)
|
||||
"""
|
||||
cursor.execute(insert_ticket_sql, (price, flight_id, seat_class, passenger_id, order_id))
|
||||
|
||||
conn.commit()
|
||||
return redirect(url_for('order', order_id=order_id))
|
||||
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
print(e)
|
||||
flash("订票失败", "error")
|
||||
return redirect(url_for('search'))
|
||||
|
||||
finally:
|
||||
cursor.close()
|
||||
conn.close()
|
||||
51
Project/Service/func/cancel_order.py
Normal file
51
Project/Service/func/cancel_order.py
Normal file
@@ -0,0 +1,51 @@
|
||||
from flask import request, redirect, url_for, g
|
||||
from .config import db
|
||||
import pymysql
|
||||
|
||||
def cancel_order():
|
||||
order_id = request.args.get('order_id')
|
||||
if not g.user:
|
||||
return redirect(url_for("login"))
|
||||
conn = pymysql.connect(**db)
|
||||
cursor = conn.cursor(pymysql.cursors.DictCursor)
|
||||
|
||||
# 检查订单是否存在
|
||||
check_order_sql = "SELECT ID FROM Orders WHERE ID = %s"
|
||||
cursor.execute(check_order_sql, (order_id,))
|
||||
order_exists = cursor.fetchone()
|
||||
|
||||
if not order_exists:
|
||||
cursor.close()
|
||||
conn.close()
|
||||
return redirect(url_for("order_list"))
|
||||
|
||||
# 查询订单中所有机票的航班ID和座位级别
|
||||
tickets_sql = "SELECT FlightID, Seat_class FROM Tickets WHERE OrderID = %s"
|
||||
cursor.execute(tickets_sql, (order_id,))
|
||||
tickets = cursor.fetchall()
|
||||
|
||||
# 恢复航班的对应余座数
|
||||
for ticket in tickets:
|
||||
flight_id = ticket['FlightID']
|
||||
seat_class = ticket['Seat_class']
|
||||
seat_column = seat_class.replace(' ', '_').lower() + "_seats_remaining"
|
||||
update_seat_sql = f"""
|
||||
UPDATE Flights
|
||||
SET {seat_column} = {seat_column} + 1
|
||||
WHERE ID = %s
|
||||
"""
|
||||
cursor.execute(update_seat_sql, (flight_id,))
|
||||
|
||||
# 删除对应的机票
|
||||
delete_tickets_sql = "DELETE FROM Tickets WHERE OrderID = %s"
|
||||
cursor.execute(delete_tickets_sql, (order_id,))
|
||||
|
||||
# 删除订单
|
||||
delete_order_sql = "DELETE FROM Orders WHERE ID = %s"
|
||||
cursor.execute(delete_order_sql, (order_id,))
|
||||
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
return redirect(url_for('order_list'))
|
||||
18
Project/Service/func/config.py
Normal file
18
Project/Service/func/config.py
Normal file
@@ -0,0 +1,18 @@
|
||||
db = {
|
||||
'host':'localhost',
|
||||
'user':'kejingfan',
|
||||
'password':'KJF2811879',
|
||||
'database':'TESTDB'
|
||||
}
|
||||
|
||||
SECRET_KEY = 'ILOVEDATABASETECH'
|
||||
|
||||
slideshow_images = [
|
||||
{"link": "https://www.csair.com/mcms/mcms/SG/zh/2024/20240208_6/index-zh.html?lang=zh&country=sg&utm_campaign=2402gwstu&utm_source=gw&utm_channel=sg-lb", "src": "https://www.csair.com/mcms/20240321/3ee85acd463f481bb33f0d535a5814c6.jpg"},
|
||||
{"link": "https://www.csair.com/mcms/mcms/SG/zh/2024/20240605_10/index_sg_cn.html?lang=zh&country=sg&utm_source=sg&utm_campaign=ZB001lydc&utm_channel=gw", "src": "https://www.csair.com/mcms/20240605/a553252769834188b0c76a9698292f27.jpg"},
|
||||
{"link": "https://www.csair.com/mcms/mcms/SG/zh/2024/20240426_17/index_cn.html?lang=zh&country=sg&utm_source=sg&utm_campaign=ZB001znjp&utm_channel=gw", "src": "https://www.csair.com/mcms/20240321/820cd99c111849408b84c2b579086ef6.jpg"},
|
||||
{"link": "https://www.csair.com/mcms/mcms/SG/zh/2024/20240524_2/index_cn.html?lang=zh&country=sg&country=my&utm_source=us&utm_campaign=ZB001nhzgx&utm_channel=gw", "src": "https://www.csair.com/mcms/20240321/61889331ca174670babd144bb064d398.jpg"},
|
||||
{"link": "https://www.csair.com/mcms/mcms/SG/zh/2024/20240514_7/coupon.html?lang=zh&country=sg", "src": "https://www.csair.com/mcms/20240321/97e67c05291b4c64a8905e8a0c915d89.jpg"},
|
||||
{"link": "#", "src": "https://www.csair.com/mcms/1026/43124f5d5124487f8d6678745ae42f57.jpg"},
|
||||
{"link": "https://www.csair.com/mcms/mcms/SG/zh/2023/20231120_2/index_sg_cn.html?lang=zh&country=sg&utm_source=sg&utm_campaign=ZB001mq&utm_channel=gw", "src": "https://www.csair.com/mcms/1026/ea00e9cb9d9b43bea6497a6895c6d9e1.jpg"}
|
||||
]
|
||||
18
Project/Service/func/index.py
Normal file
18
Project/Service/func/index.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from flask import render_template, request, g, redirect, url_for, session
|
||||
from .config import slideshow_images
|
||||
from .utils import get_cities
|
||||
|
||||
def index():
|
||||
if request.method == 'GET':
|
||||
if not g.user:
|
||||
return redirect(url_for("login"))
|
||||
images = slideshow_images
|
||||
return render_template(
|
||||
'index.html', cities=get_cities(),
|
||||
images=images, username=g.name
|
||||
)
|
||||
|
||||
def logout():
|
||||
session.clear()
|
||||
session.pop('user_id', None)
|
||||
return redirect(url_for('login'))
|
||||
35
Project/Service/func/login.py
Normal file
35
Project/Service/func/login.py
Normal file
@@ -0,0 +1,35 @@
|
||||
from flask import request, jsonify, session, url_for, render_template
|
||||
from .config import db, slideshow_images
|
||||
import pymysql
|
||||
|
||||
|
||||
def connect(mobileNo, encrypted_password):
|
||||
conn = pymysql.connect(**db)
|
||||
cursor = conn.cursor(pymysql.cursors.DictCursor)
|
||||
args = (mobileNo, encrypted_password)
|
||||
verify_sql = "SELECT Phone_number FROM Users WHERE Phone_number = %s AND `Password` = %s;"
|
||||
cursor.execute(verify_sql, args)
|
||||
user = cursor.fetchone()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
return user
|
||||
|
||||
def login():
|
||||
if request.method == 'GET':
|
||||
images = slideshow_images
|
||||
return render_template('login.html', images=images)
|
||||
|
||||
if request.method == 'POST':
|
||||
session.pop('user_id', None)
|
||||
mobileNo = request.json.get('username')
|
||||
encrypted_password = request.json.get('password')
|
||||
try:
|
||||
user = connect(mobileNo, encrypted_password)
|
||||
if not user:
|
||||
return jsonify({'message': '用户不存在,请点击注册按钮注册'}), 401
|
||||
session['user_id'] = mobileNo
|
||||
session.modified = True
|
||||
return jsonify({'redirect': url_for('index')})
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return jsonify({'message': '数据库错误,请稍后再试'}), 500
|
||||
119
Project/Service/func/modify.py
Normal file
119
Project/Service/func/modify.py
Normal file
@@ -0,0 +1,119 @@
|
||||
from flask import render_template, request, flash, redirect, url_for, session, g
|
||||
from typing import Dict
|
||||
from pymysql.cursors import Cursor
|
||||
import pymysql
|
||||
from .config import db
|
||||
|
||||
def verify_user(cursor: Cursor, phone_number: str, password: str) -> str:
|
||||
sql = """
|
||||
SELECT Password FROM Users WHERE Phone_number = %s;
|
||||
"""
|
||||
cursor.execute(sql, (phone_number,))
|
||||
record = cursor.fetchone()
|
||||
if not record:
|
||||
return "NO_USER"
|
||||
if record[0] != password:
|
||||
return "WRONG_PASSWORD"
|
||||
return "USER_VERIFIED"
|
||||
|
||||
class ModifyInfo:
|
||||
def __init__(self, form: Dict[str, str], user_phone: str):
|
||||
self.phone_number = user_phone
|
||||
modifyType = form['modifyType']
|
||||
self.new_password = form.get('encryptedNewPassword', None)
|
||||
self.new_phone_number = form.get('mobileNo', None)
|
||||
self.new_username = form.get('username', None)
|
||||
modifyType2command = {
|
||||
'删除账户': 'delete account',
|
||||
'修改密码': 'modify Password',
|
||||
'修改手机号': 'modify Phone_Number',
|
||||
'修改用户名': 'modify Username'
|
||||
}
|
||||
self.sql_dict = {
|
||||
'delete account': 'DELETE FROM Users WHERE Phone_number = %s;',
|
||||
'modify Password': 'UPDATE Users SET Password = %s WHERE Phone_number = %s;',
|
||||
'modify Phone_Number': 'UPDATE Users SET Phone_number = %s WHERE Phone_number = %s;',
|
||||
'modify Username': 'UPDATE Users SET Username = %s WHERE Phone_number = %s;'
|
||||
}
|
||||
self.sql_args_dict = {
|
||||
'delete account': (self.phone_number,),
|
||||
'modify Password': (self.new_password, self.phone_number),
|
||||
'modify Phone_Number': (self.new_phone_number, self.phone_number),
|
||||
'modify Username': (self.new_username, self.phone_number)
|
||||
}
|
||||
self.ok_message_dict = {
|
||||
'delete account': "删除账户成功",
|
||||
'modify Password': "修改密码成功",
|
||||
'modify Phone_Number': "修改手机号成功",
|
||||
'modify Username': "修改用户名成功"
|
||||
}
|
||||
self.fail_message_dict = {
|
||||
'delete account': "数据库异常,删除账户失败",
|
||||
'modify Password': "数据库异常,修改密码失败",
|
||||
'modify Phone_Number': "数据库异常,修改手机号失败",
|
||||
'modify Username': "数据库异常,修改用户名失败"
|
||||
}
|
||||
self.command = modifyType2command[modifyType]
|
||||
|
||||
def get_sql(self):
|
||||
return self.sql_dict[self.command]
|
||||
|
||||
def get_args(self):
|
||||
return self.sql_args_dict[self.command]
|
||||
|
||||
def get_ok_message(self):
|
||||
return self.ok_message_dict[self.command]
|
||||
|
||||
def get_fail_message(self):
|
||||
return self.fail_message_dict[self.command]
|
||||
|
||||
def modify():
|
||||
if request.method == 'GET':
|
||||
if not g.user:
|
||||
return redirect(url_for("login"))
|
||||
user_phone = session.get('user_id')
|
||||
return render_template('modify.html', current_user_phone=user_phone, current_username=g.name)
|
||||
|
||||
|
||||
if request.method == 'POST':
|
||||
user_phone = session.get('user_id')
|
||||
password = request.form['encryptedPassword']
|
||||
conn = pymysql.connect(**db)
|
||||
cursor = conn.cursor(pymysql.cursors.DictCursor)
|
||||
|
||||
verify_info = verify_user(cursor, user_phone, password)
|
||||
if verify_info == "NO_USER":
|
||||
session.clear()
|
||||
return redirect(url_for('login'))
|
||||
elif verify_info == "WRONG_PASSWORD":
|
||||
flash("密码错误")
|
||||
conn.close()
|
||||
return redirect(url_for('modify'))
|
||||
|
||||
modifyInfo = ModifyInfo(request.form, user_phone)
|
||||
|
||||
if modifyInfo.command == 'modify Phone_Number':
|
||||
check_sql = "SELECT COUNT(*) FROM Users WHERE Phone_number = %s;"
|
||||
cursor.execute(check_sql, (modifyInfo.new_phone_number,))
|
||||
if cursor.fetchone()[0] > 0:
|
||||
flash("手机号已存在,请使用其他手机号")
|
||||
conn.close()
|
||||
return redirect(url_for('modify'))
|
||||
|
||||
try:
|
||||
cursor.execute(modifyInfo.get_sql(), modifyInfo.get_args())
|
||||
conn.commit()
|
||||
flash(modifyInfo.get_ok_message())
|
||||
conn.close()
|
||||
if modifyInfo.command in ['modify Phone_Number', 'modify Password', 'delete account']:
|
||||
session.clear()
|
||||
session.pop("user_id", None)
|
||||
return redirect(url_for('login'))
|
||||
elif modifyInfo.command == 'modify Username':
|
||||
return redirect(url_for('modify'))
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
print(e)
|
||||
flash(modifyInfo.get_fail_message())
|
||||
conn.close()
|
||||
return redirect(url_for('modify'))
|
||||
47
Project/Service/func/order.py
Normal file
47
Project/Service/func/order.py
Normal file
@@ -0,0 +1,47 @@
|
||||
from flask import render_template, request, redirect, url_for, g
|
||||
from .config import db
|
||||
import pymysql
|
||||
|
||||
def order():
|
||||
order_id = request.args.get('order_id')
|
||||
if not g.user:
|
||||
return redirect(url_for("login"))
|
||||
|
||||
conn = pymysql.connect(**db)
|
||||
cursor = conn.cursor(pymysql.cursors.DictCursor)
|
||||
|
||||
# 查询订单信息和航班信息
|
||||
order_sql = """
|
||||
SELECT o.*, f.*, d.Name as Departure_airport_name, a.Name as Arrival_airport_name
|
||||
FROM Orders o
|
||||
JOIN Tickets t ON o.ID = t.OrderID
|
||||
JOIN Flights f ON t.FlightID = f.ID
|
||||
JOIN Airports d ON f.Departure_airport = d.ID
|
||||
JOIN Airports a ON f.Arrival_airport = a.ID
|
||||
WHERE o.ID = %s
|
||||
"""
|
||||
cursor.execute(order_sql, (order_id,))
|
||||
order_info = cursor.fetchone()
|
||||
|
||||
# 如果订单信息不存在,返回订单列表页面
|
||||
if not order_info:
|
||||
cursor.close()
|
||||
conn.close()
|
||||
return redirect(url_for("order_list"))
|
||||
|
||||
# 查询乘客信息和票据信息
|
||||
tickets_sql = """
|
||||
SELECT t.*, p.Name, p.Phone_number
|
||||
FROM Tickets t
|
||||
JOIN Passengers p ON t.PassengerID = p.ID
|
||||
WHERE t.OrderID = %s
|
||||
"""
|
||||
cursor.execute(tickets_sql, (order_id,))
|
||||
tickets = cursor.fetchall()
|
||||
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
total_price = sum(ticket['Price'] for ticket in tickets)
|
||||
|
||||
return render_template('order.html', order=order_info, tickets=tickets, total_price=total_price, username=g.name)
|
||||
54
Project/Service/func/order_list.py
Normal file
54
Project/Service/func/order_list.py
Normal file
@@ -0,0 +1,54 @@
|
||||
from flask import render_template, request, redirect, url_for, g
|
||||
from .config import db
|
||||
import pymysql
|
||||
|
||||
def order_list():
|
||||
if not g.user:
|
||||
return redirect(url_for("login"))
|
||||
|
||||
conn = pymysql.connect(**db)
|
||||
cursor = conn.cursor(pymysql.cursors.DictCursor)
|
||||
|
||||
# 查询用户关联的所有订单信息
|
||||
orders_sql = """
|
||||
SELECT o.ID as OrderID, o.Order_time, o.Paid, f.ID as FlightID, f.Airline,
|
||||
d.Name as Departure_airport_name, a.Name as Arrival_airport_name,
|
||||
f.Departure_time, f.Status, p.Name as PassengerName, t.Price
|
||||
FROM Orders o
|
||||
JOIN Tickets t ON o.ID = t.OrderID
|
||||
JOIN Flights f ON t.FlightID = f.ID
|
||||
JOIN Airports d ON f.Departure_airport = d.ID
|
||||
JOIN Airports a ON f.Arrival_airport = a.ID
|
||||
JOIN Passengers p ON t.PassengerID = p.ID
|
||||
WHERE o.User_phone_number = %s
|
||||
"""
|
||||
cursor.execute(orders_sql, (g.user,))
|
||||
orders = cursor.fetchall()
|
||||
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
# 整理订单信息
|
||||
order_dict = {}
|
||||
for order in orders:
|
||||
order_id = order['OrderID']
|
||||
if order_id not in order_dict:
|
||||
order_dict[order_id] = {
|
||||
'OrderID': order_id,
|
||||
'Order_time': order['Order_time'],
|
||||
'Paid': order['Paid'],
|
||||
'FlightID': order['FlightID'],
|
||||
'Airline': order['Airline'],
|
||||
'Departure_airport_name': order['Departure_airport_name'],
|
||||
'Arrival_airport_name': order['Arrival_airport_name'],
|
||||
'Departure_time': order['Departure_time'],
|
||||
'Status': order['Status'],
|
||||
'Passengers': [],
|
||||
'TotalPrice': 0
|
||||
}
|
||||
order_dict[order_id]['Passengers'].append(order['PassengerName'])
|
||||
order_dict[order_id]['TotalPrice'] += order['Price']
|
||||
|
||||
order_list = list(order_dict.values())
|
||||
|
||||
return render_template('order_list.html', orders=order_list, username=g.name)
|
||||
30
Project/Service/func/pay_confirm.py
Normal file
30
Project/Service/func/pay_confirm.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from flask import redirect, url_for, g, request
|
||||
from .config import db
|
||||
import pymysql
|
||||
|
||||
def pay_confirm():
|
||||
order_id = request.args.get('order_id')
|
||||
if not g.user:
|
||||
return redirect(url_for("login"))
|
||||
|
||||
conn = pymysql.connect(**db)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# 检查订单是否存在
|
||||
check_order_sql = "SELECT ID FROM Orders WHERE ID = %s"
|
||||
cursor.execute(check_order_sql, (order_id,))
|
||||
order_exists = cursor.fetchone()
|
||||
|
||||
if not order_exists:
|
||||
cursor.close()
|
||||
conn.close()
|
||||
return redirect(url_for("order_list"))
|
||||
|
||||
update_order_sql = "UPDATE Orders SET Paid = 1 WHERE ID = %s"
|
||||
cursor.execute(update_order_sql, (order_id,))
|
||||
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
return redirect(url_for('order_list', order_id=order_id))
|
||||
49
Project/Service/func/search.py
Normal file
49
Project/Service/func/search.py
Normal file
@@ -0,0 +1,49 @@
|
||||
from flask import render_template, request, g, abort, redirect, url_for
|
||||
from .config import db
|
||||
from .utils import get_cities
|
||||
import pymysql
|
||||
import datetime
|
||||
|
||||
|
||||
def search():
|
||||
if not g.user:
|
||||
return redirect(url_for("login"))
|
||||
departure_city = request.args.get('departure')
|
||||
destination_city = request.args.get('destination')
|
||||
departure_date = request.args.get('departure-date')
|
||||
passengers = int(request.args.get('passengers', 1))
|
||||
|
||||
# Date validation
|
||||
try:
|
||||
departure_date_obj = datetime.datetime.strptime(departure_date, '%Y-%m-%d').date()
|
||||
if departure_date_obj < datetime.date.today():
|
||||
abort(400, description="Departure date cannot be in the past.")
|
||||
except ValueError:
|
||||
abort(400, description="Invalid date format.")
|
||||
|
||||
conn = pymysql.connect(**db)
|
||||
cursor = conn.cursor(pymysql.cursors.DictCursor)
|
||||
|
||||
search_sql = """
|
||||
SELECT f.*, d.Name as Departure_airport_name, a.Name as Arrival_airport_name
|
||||
FROM Flights f
|
||||
JOIN Airports d ON f.Departure_airport = d.ID
|
||||
JOIN Airports a ON f.Arrival_airport = a.ID
|
||||
WHERE d.City = %s AND a.City = %s
|
||||
AND DATE(f.Departure_time) = %s
|
||||
AND (f.First_class_seats_remaining + f.Business_class_seats_remaining + f.Economy_class_seats_remaining) >= %s
|
||||
AND f.Status NOT IN ('已起飞', '已降落');
|
||||
"""
|
||||
|
||||
cursor.execute(search_sql, (departure_city, destination_city, departure_date, passengers))
|
||||
flights = cursor.fetchall()
|
||||
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
return render_template(
|
||||
'search.html',
|
||||
cities=get_cities(),
|
||||
flights=flights,
|
||||
username=g.name
|
||||
)
|
||||
74
Project/Service/func/signup.py
Normal file
74
Project/Service/func/signup.py
Normal file
@@ -0,0 +1,74 @@
|
||||
from flask import render_template, request, redirect, url_for
|
||||
from .config import db
|
||||
import re
|
||||
import pymysql
|
||||
|
||||
def signup():
|
||||
error_messages = {
|
||||
'username': '',
|
||||
'mobileNo': '',
|
||||
'password': '',
|
||||
'confirmPassword': ''
|
||||
}
|
||||
|
||||
if request.method == 'GET':
|
||||
return render_template('signup.html', errors=error_messages)
|
||||
|
||||
if request.method == 'POST':
|
||||
username = request.form['username']
|
||||
phone_number = request.form['mobileNo']
|
||||
password = request.form['encryptedPassword']
|
||||
confirm_password = request.form['encryptedConfirmPassword']
|
||||
|
||||
# Basic validation for phone number
|
||||
if not re.match(r'^\d{11}$', phone_number):
|
||||
error_messages['mobileNo'] = '手机号格式有误'
|
||||
|
||||
# Check password length after MD5 hash
|
||||
if len(password) != 32: # MD5 hash length is 32 characters
|
||||
error_messages['password'] = '密码格式有误'
|
||||
|
||||
# Confirm password validation
|
||||
if password != confirm_password:
|
||||
error_messages['confirmPassword'] = '两次输入的密码不一致'
|
||||
|
||||
if any(error_messages.values()):
|
||||
return render_template('signup.html', errors=error_messages)
|
||||
|
||||
conn = pymysql.connect(**db)
|
||||
cursor = conn.cursor(pymysql.cursors.DictCursor)
|
||||
|
||||
# 检查已有用户
|
||||
sql = """
|
||||
SELECT COUNT(*) FROM Users \
|
||||
WHERE Phone_number = %s;
|
||||
"""
|
||||
try:
|
||||
cursor.execute(sql, (phone_number,))
|
||||
phone_exist = cursor.fetchall()[0]['COUNT(*)']
|
||||
except Exception as e:
|
||||
error_messages['mobileNo'] = "数据库异常,查询失败"
|
||||
print(e)
|
||||
return render_template('signup.html', errors=error_messages)
|
||||
|
||||
if phone_exist != 0:
|
||||
error_messages['mobileNo'] = "该手机号已注册,请勿重复注册"
|
||||
conn.close()
|
||||
return render_template('signup.html', errors=error_messages)
|
||||
|
||||
# 插入
|
||||
sql = '''
|
||||
INSERT INTO Users (Phone_number, Username, `Password`) \
|
||||
VALUES (%s, %s, %s); \
|
||||
'''
|
||||
try:
|
||||
cursor.execute(sql, (phone_number, username, password))
|
||||
conn.commit()
|
||||
return redirect(url_for('index'))
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
print(e)
|
||||
error_messages['mobileNo'] = "数据库异常,注册失败"
|
||||
return render_template('signup.html', errors=error_messages)
|
||||
finally:
|
||||
conn.close()
|
||||
20
Project/Service/func/utils.py
Normal file
20
Project/Service/func/utils.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from .config import db
|
||||
import pymysql
|
||||
from xpinyin import Pinyin
|
||||
from pymysql.cursors import Cursor
|
||||
|
||||
def get_cities():
|
||||
conn = pymysql.connect(**db)
|
||||
cursor = conn.cursor(pymysql.cursors.DictCursor)
|
||||
cursor.execute("SELECT DISTINCT City FROM Airports")
|
||||
cities = [row['City'] for row in cursor.fetchall()]
|
||||
cursor.close()
|
||||
conn.close()
|
||||
p = Pinyin()
|
||||
cities = [
|
||||
(row, p.get_pinyin(row).replace("-", ""))
|
||||
for row in cities
|
||||
]
|
||||
cities = sorted(cities, key=lambda x: x[1])
|
||||
cities = [row[0] for row in cities]
|
||||
return cities
|
||||
Reference in New Issue
Block a user