diff --git a/Project/__pycache__/main.cpython-311.pyc b/Project/__pycache__/main.cpython-311.pyc index 5e510a5..6843b95 100644 Binary files a/Project/__pycache__/main.cpython-311.pyc and b/Project/__pycache__/main.cpython-311.pyc differ diff --git a/Project/db.sql b/Project/db.sql index 3a0b4ff..9f284b4 100644 --- a/Project/db.sql +++ b/Project/db.sql @@ -1,10 +1,102 @@ -DROP TABLE IF EXISTS passengers; +DROP TABLE IF EXISTS Sold; +DROP TABLE IF EXISTS Transactions; +DROP TABLE IF EXISTS Passbys; +DROP TABLE IF EXISTS Tickets; +DROP TABLE IF EXISTS Seats; +DROP TABLE IF EXISTS Users; +DROP TABLE IF EXISTS Passengers; +DROP TABLE IF EXISTS Rides; +DROP TABLE IF EXISTS Trains; +DROP TABLE IF EXISTS Stations; -CREATE TABLE passengers ( - ID BIGINT PRIMARY KEY, - `Name` VARCHAR (255) NOT NULL, - Phone_number BIGINT UNIQUE NOT NULL, - `Password` VARCHAR (255) NOT NULL, - CHECK (ID REGEXP '^\\d{18}$'), - CHECK (Phone_number REGEXP '^\\d{11}$') +CREATE TABLE Passengers ( + ID BIGINT PRIMARY KEY, + `Name` VARCHAR ( 255 ) NOT NULL, + Phone_number BIGINT UNIQUE NOT NULL, + CHECK ( REGEXP_LIKE ( ID, '^\\d{18}$' ) ), + CHECK ( REGEXP_LIKE ( Phone_number, '^\\d{11}$' ) ) +); + +CREATE TABLE Users ( + ID INT AUTO_INCREMENT PRIMARY KEY, + `Password` VARCHAR ( 255 ) NOT NULL, + Phone_number BIGINT UNIQUE NOT NULL, + CitizenID BIGINT UNIQUE NOT NULL, + FOREIGN KEY ( Phone_number ) REFERENCES Passengers ( Phone_number ) ON DELETE CASCADE, + FOREIGN KEY ( CitizenID ) REFERENCES Passengers ( ID ) ON DELETE CASCADE +); + +CREATE TABLE Stations ( + ID INT AUTO_INCREMENT PRIMARY KEY, + `Name` VARCHAR ( 255 ) UNIQUE NOT NULL, + Province VARCHAR ( 255 ) NOT NULL, + City VARCHAR ( 255 ) NOT NULL +); + +CREATE TABLE Trains ( + ID VARCHAR ( 255 ) PRIMARY KEY, + TrainName VARCHAR ( 255 ) NOT NULL, + StationID_start INT NOT NULL, + StationID_arrive INT NOT NULL, + FOREIGN KEY ( StationID_start ) REFERENCES Stations ( ID ) ON DELETE CASCADE, + FOREIGN KEY ( StationID_arrive ) REFERENCES Stations ( ID ) ON DELETE CASCADE +); + +CREATE TABLE Seats ( + ID VARCHAR ( 255 ) PRIMARY KEY, + Type VARCHAR ( 255 ) NOT NULL, + TrainID VARCHAR ( 255 ) NOT NULL, + FOREIGN KEY ( TrainID ) REFERENCES Trains ( ID ) ON DELETE CASCADE +); + +CREATE TABLE Tickets ( + ID INT AUTO_INCREMENT PRIMARY KEY, + Price DECIMAL ( 7, 2 ) NOT NULL, + Time_start DATETIME NOT NULL, + Time_arrive DATETIME NOT NULL, + StationID_start INT NOT NULL, + StationID_arrive INT NOT NULL, + SeatID VARCHAR ( 255 ) NOT NULL, + FOREIGN KEY ( StationID_start ) REFERENCES Stations ( ID ) ON DELETE CASCADE, + FOREIGN KEY ( StationID_arrive ) REFERENCES Stations ( ID ) ON DELETE CASCADE, + FOREIGN KEY ( SeatID ) REFERENCES Seats ( ID ) ON DELETE CASCADE, + CHECK ( Time_start <= Time_arrive ) +); + +CREATE TABLE Transactions ( + ID BIGINT AUTO_INCREMENT PRIMARY KEY, + `Time` DATETIME NOT NULL, + Paid TINYINT NOT NULL, + `User` INT NOT NULL, + PassengerID BIGINT NOT NULL, + TrainID VARCHAR ( 255 ) NOT NULL, + StationID_start INT NOT NULL, + StationID_arrive INT NOT NULL, + Time_start DATETIME NOT NULL, + Time_arrive DATETIME NOT NULL, + SeatID VARCHAR ( 255 ) NOT NULL, + FOREIGN KEY ( `User` ) REFERENCES Users ( ID ) ON DELETE CASCADE, + FOREIGN KEY ( PassengerID ) REFERENCES Passengers ( ID ) ON DELETE CASCADE, + FOREIGN KEY ( TrainID ) REFERENCES Trains ( ID ) ON DELETE CASCADE, + FOREIGN KEY ( StationID_start ) REFERENCES Stations ( ID ) ON DELETE CASCADE, + FOREIGN KEY ( StationID_arrive ) REFERENCES Stations ( ID ) ON DELETE CASCADE, + FOREIGN KEY ( SeatID ) REFERENCES Seats ( ID ) ON DELETE CASCADE, + CHECK ( Time_start < Time_arrive ) +); + +CREATE TABLE Sold ( + TransactionID BIGINT NOT NULL, + TicketID INT NOT NULL, + FOREIGN KEY ( TransactionID ) REFERENCES Transactions ( ID ) ON DELETE CASCADE, + FOREIGN KEY ( TicketID ) REFERENCES Tickets ( ID ) ON DELETE CASCADE +); + +CREATE TABLE Passbys ( + StationID INT NOT NULL, + TrainID VARCHAR ( 255 ) NOT NULL, + arrive_time DATETIME NOT NULL, + leave_time DATETIME NOT NULL, + FOREIGN KEY ( StationID ) REFERENCES Stations ( ID ) ON DELETE CASCADE, + FOREIGN KEY ( TrainID ) REFERENCES Trains ( ID ) ON DELETE CASCADE, + CHECK ( arrive_time <= leave_time ) ); \ No newline at end of file diff --git a/Project/func/__init__.py b/Project/func/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Project/func/__pycache__/__init__.cpython-311.pyc b/Project/func/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..96c1001 Binary files /dev/null and b/Project/func/__pycache__/__init__.cpython-311.pyc differ diff --git a/Project/func/__pycache__/get_db.cpython-311.pyc b/Project/func/__pycache__/get_db.cpython-311.pyc new file mode 100644 index 0000000..db01682 Binary files /dev/null and b/Project/func/__pycache__/get_db.cpython-311.pyc differ diff --git a/Project/func/__pycache__/index.cpython-311.pyc b/Project/func/__pycache__/index.cpython-311.pyc new file mode 100644 index 0000000..7cabdea Binary files /dev/null and b/Project/func/__pycache__/index.cpython-311.pyc differ diff --git a/Project/func/__pycache__/modify.cpython-311.pyc b/Project/func/__pycache__/modify.cpython-311.pyc new file mode 100644 index 0000000..ef647e5 Binary files /dev/null and b/Project/func/__pycache__/modify.cpython-311.pyc differ diff --git a/Project/func/__pycache__/signup.cpython-311.pyc b/Project/func/__pycache__/signup.cpython-311.pyc new file mode 100644 index 0000000..0ca3dfe Binary files /dev/null and b/Project/func/__pycache__/signup.cpython-311.pyc differ diff --git a/Project/func/__pycache__/verify_user.cpython-311.pyc b/Project/func/__pycache__/verify_user.cpython-311.pyc new file mode 100644 index 0000000..cf6a4bc Binary files /dev/null and b/Project/func/__pycache__/verify_user.cpython-311.pyc differ diff --git a/Project/func/get_db.py b/Project/func/get_db.py new file mode 100644 index 0000000..7101cb3 --- /dev/null +++ b/Project/func/get_db.py @@ -0,0 +1,7 @@ +import pymysql + +def get_db(): + return pymysql.connect( + host='localhost', user='kejingfan', + password='KJF2811879', database='TESTDB' + ) \ No newline at end of file diff --git a/Project/func/index.py b/Project/func/index.py new file mode 100644 index 0000000..64f8a9a --- /dev/null +++ b/Project/func/index.py @@ -0,0 +1,4 @@ +from flask import render_template + +def index(): + return render_template("index.html") \ No newline at end of file diff --git a/Project/func/modify.py b/Project/func/modify.py new file mode 100644 index 0000000..474a028 --- /dev/null +++ b/Project/func/modify.py @@ -0,0 +1,79 @@ +from flask import render_template, request, flash, redirect, url_for +from typing import Dict + +from .get_db import get_db +from .verify_user import verify_user + + +class ModifyInfo: + def __init__(self, form:Dict[str, str]): + self.id = form['cardCode'] + modifyType = form['modifyType'] + self.new_password = form['encryptedNewPassword'] + self.phone_number = form['mobileNo'] + modifyType2command = { + '1':'delete account', + '2':'modify Password', + '3':'modify Phone_Number' + } + self.sql_dict = { + 'delete account': 'DELETE FROM passengers WHERE ID = %s;', + 'modify Password': 'UPDATE passengers SET `Password` = %s WHERE ID = %s;', + 'modify Phone_Number': 'UPDATE passengers SET Phone_number = %s WHERE ID = %s;' + } + self.sql_args_dict = { + 'delete account': (self.id,), + 'modify Password': (self.new_password, self.id), + 'modify Phone_Number': (self.phone_number, self.id) + } + self.ok_message_dict = { + 'delete account': "删除账户成功", + 'modify Password': "修改密码成功", + 'modify Phone_Number': "修改手机号成功" + } + self.fail_message_dict = { + 'delete account': "数据库异常,删除账户失败", + 'modify Password': "数据库异常,修改密码失败", + 'modify Phone_Number': "数据库异常,修改手机号失败" + } + 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': + return render_template('modify.html') + + if request.method == 'POST': + id = request.form['cardCode'] + password = request.form['encryptedPassword'] + db = get_db() + cursor = db.cursor() + + verify_info = verify_user(cursor, id, password) + if (verify_info == "NO_USER"): + flash("您未注册过,无法修改账号") + db.close() + return redirect(url_for('signup')) + elif (verify_info == "WRONG_PASSWORD"): + flash("密码错误") + db.close() + return redirect(url_for('modify')) + + modifyInfo = ModifyInfo(request.form) + try: + cursor.execute(modifyInfo.get_sql(), modifyInfo.get_args()) + db.commit() + flash(modifyInfo.get_ok_message()) + except Exception as e: + db.rollback() + print(e) + flash(modifyInfo.get_fail_message()) + db.close() + return redirect(url_for('index')) \ No newline at end of file diff --git a/Project/func/signup.py b/Project/func/signup.py new file mode 100644 index 0000000..38b217a --- /dev/null +++ b/Project/func/signup.py @@ -0,0 +1,48 @@ +from flask import render_template, request, flash, redirect, url_for +from .get_db import get_db + +def signup(): + if request.method == 'GET': + return render_template('signup.html') + + if request.method == 'POST': + id = request.form['cardCode'] + name = request.form['name'] + phone_number = request.form['mobileNo'] + password = request.form['encryptedPassword'] + + db = get_db() + cursor = db.cursor() + + # 检查已有用户 + sql = """ + SELECT COUNT(*) FROM Users \ + WHERE ID = %s; + """ + try: + cursor.execute(sql, (id,)) + id_exist = cursor.fetchall()[0][0] + except Exception as e: + flash("数据库异常,查询失败") + print(e) + return redirect(url_for('signup')) + if (id_exist != 0): + flash("您已注册过,请勿重复注册") + db.close() + return redirect(url_for('index')) + + # 插入 + sql = ''' + INSERT INTO passengers (ID, `Name`, Phone_number, `Password`) \ + VALUES (%s, %s, %s, %s); \ + ''' + try: + cursor.execute(sql, (id, name, phone_number, password)) + db.commit() + flash("注册成功") + except Exception as e: + db.rollback() + print(e) + flash("数据库异常,注册失败") + db.close() + return redirect(url_for('index')) \ No newline at end of file diff --git a/Project/func/verify_user.py b/Project/func/verify_user.py new file mode 100644 index 0000000..8201e9b --- /dev/null +++ b/Project/func/verify_user.py @@ -0,0 +1,35 @@ +from flask import flash, redirect, url_for +from pymysql.cursors import Cursor + +def verify_user(cursor:Cursor, id:str, password:str) -> str: + # 检查已有用户 + sql = """ + SELECT COUNT(*) FROM passengers \ + WHERE ID = %s; + """ + try: + cursor.execute(sql, (id,)) + id_exist = cursor.fetchall()[0][0] + except Exception as e: + flash("数据库异常,查询失败") + print(e) + return redirect(url_for('signup')) + if (id_exist == 0): + return "NO_USER" + + # 检查密码 + sql = """ + SELECT `Password` FROM passengers \ + WHERE ID = %s; + """ + try: + cursor.execute(sql, (id,)) + record_password = cursor.fetchall()[0][0] + except Exception as e: + flash("数据库异常,查询失败") + print(e) + return redirect(url_for('modify')) + if (record_password != password): + return "WRONG_PASSWORD" + + return "USER_VERIFIED" \ No newline at end of file diff --git a/Project/main.py b/Project/main.py index f2677d9..623f790 100644 --- a/Project/main.py +++ b/Project/main.py @@ -1,179 +1,22 @@ -from flask import Flask, render_template, request, flash, redirect, url_for -import pymysql -from pymysql.cursors import Cursor +from flask import Flask import os -from typing import Dict +import func.index +import func.signup +import func.modify app = Flask(__name__) app.secret_key = os.environ.get('SECRET_KEY', 'OPTIONALSECRETKEY') -def get_db(): - return pymysql.connect( - host='localhost', user='kejingfan', - password='KJF2811879', database='TESTDB' - ) - - @app.route("/") def index(): - return render_template("index.html") - + return func.index.index() @app.route("/signup.html", methods=('GET', 'POST')) def signup(): - if request.method == 'GET': - return render_template('signup.html') - - if request.method == 'POST': - id = request.form['cardCode'] - name = request.form['name'] - phone_number = request.form['mobileNo'] - password = request.form['encryptedPassword'] - - db = get_db() - cursor = db.cursor() - - # 检查已有用户 - sql = """ - SELECT COUNT(*) FROM passengers \ - WHERE ID = %s; - """ - try: - cursor.execute(sql, (id,)) - id_exist = cursor.fetchall()[0][0] - except Exception as e: - flash("数据库异常,查询失败") - print(e) - return redirect(url_for('signup')) - if (id_exist != 0): - flash("您已注册过,请勿重复注册") - db.close() - return redirect(url_for('index')) - - # 插入 - sql = ''' - INSERT INTO passengers (ID, `Name`, Phone_number, `Password`) \ - VALUES (%s, %s, %s, %s); \ - ''' - try: - cursor.execute(sql, (id, name, phone_number, password)) - db.commit() - flash("注册成功") - except Exception as e: - db.rollback() - print(e) - flash("数据库异常,注册失败") - db.close() - return redirect(url_for('index')) - - -def verify_user(cursor:Cursor, id:str, password:str) -> str: - # 检查已有用户 - sql = """ - SELECT COUNT(*) FROM passengers \ - WHERE ID = %s; - """ - try: - cursor.execute(sql, (id,)) - id_exist = cursor.fetchall()[0][0] - except Exception as e: - flash("数据库异常,查询失败") - print(e) - return redirect(url_for('signup')) - if (id_exist == 0): - return "NO_USER" - - # 检查密码 - sql = """ - SELECT `Password` FROM passengers \ - WHERE ID = %s; - """ - try: - cursor.execute(sql, (id,)) - record_password = cursor.fetchall()[0][0] - except Exception as e: - flash("数据库异常,查询失败") - print(e) - return redirect(url_for('modify')) - if (record_password != password): - return "WRONG_PASSWORD" - - return "USER_VERIFIED" - - -class ModifyInfo: - def __init__(self, form:Dict[str, str]): - self.id = form['cardCode'] - modifyType = form['modifyType'] - self.new_password = form['encryptedNewPassword'] - self.phone_number = form['mobileNo'] - modifyType2command = { - '1':'delete account', - '2':'modify Password', - '3':'modify Phone_Number' - } - self.sql_dict = { - 'delete account': 'DELETE FROM passengers WHERE ID = %s;', - 'modify Password': 'UPDATE passengers SET `Password` = %s WHERE ID = %s;', - 'modify Phone_Number': 'UPDATE passengers SET Phone_number = %s WHERE ID = %s;' - } - self.sql_args_dict = { - 'delete account': (self.id,), - 'modify Password': (self.new_password, self.id), - 'modify Phone_Number': (self.phone_number, self.id) - } - self.ok_message_dict = { - 'delete account': "删除账户成功", - 'modify Password': "修改密码成功", - 'modify Phone_Number': "修改手机号成功" - } - self.fail_message_dict = { - 'delete account': "数据库异常,删除账户失败", - 'modify Password': "数据库异常,修改密码失败", - 'modify Phone_Number': "数据库异常,修改手机号失败" - } - 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] - + return func.signup.signup() @app.route("/modify.html", methods=('GET', 'POST')) def modify(): - if request.method == 'GET': - return render_template('modify.html') - - if request.method == 'POST': - id = request.form['cardCode'] - password = request.form['encryptedPassword'] - db = get_db() - cursor = db.cursor() - - verify_info = verify_user(cursor, id, password) - if (verify_info == "NO_USER"): - flash("您未注册过,无法修改账号") - db.close() - return redirect(url_for('signup')) - elif (verify_info == "WRONG_PASSWORD"): - flash("密码错误") - db.close() - return redirect(url_for('modify')) - - modifyInfo = ModifyInfo(request.form) - try: - cursor.execute(modifyInfo.get_sql(), modifyInfo.get_args()) - db.commit() - flash(modifyInfo.get_ok_message()) - except Exception as e: - db.rollback() - print(e) - flash(modifyInfo.get_fail_message()) - db.close() - return redirect(url_for('index')) \ No newline at end of file + return func.modify.modify() \ No newline at end of file diff --git a/Project/run.sh b/Project/run.sh index dc861d9..18ba559 100644 --- a/Project/run.sh +++ b/Project/run.sh @@ -1 +1,3 @@ -SECRET_KEY='ILOVEDATABASETECH' FLASK_APP=main FLASK_ENV=development flask run \ No newline at end of file +SECRET_KEY='ILOVEDATABASETECH' FLASK_APP=main FLASK_ENV=development flask run \ + --host 0.0.0.0 \ + --port 5000 # default 5000 \ No newline at end of file diff --git a/Project/static/css/index.css b/Project/static/css/index.css new file mode 100644 index 0000000..f9854f9 --- /dev/null +++ b/Project/static/css/index.css @@ -0,0 +1,95 @@ +body { + font-family: Arial, sans-serif; + margin: 0; + padding: 0; + background-color: #ffffff; + height: 100vh; + display: flex; + flex-direction: column; + align-items: center; +} + +header { + background-color: rgba(28, 108, 178, 0.9); + color: white; + padding: 20px 0; + text-align: center; + width: 100%; +} + +nav ul { + list-style: none; + padding: 0; + margin: 0; +} + +nav ul li { + display: inline; + margin: 0 10px; +} + +nav ul li a { + color: white; + text-decoration: none; + font-weight: bold; +} + +main { + flex: 1; + display: flex; + align-items: center; + justify-content: center; + width: 100%; +} + +.background-container { + width: 100%; + max-width: 1500px; + height: 600px; /* Adjust according to the desired size */ + background-image: url('/static/images/banner-login-20200629.jpg'); + background-size: cover; + background-position: center; + background-repeat: no-repeat; + display: flex; + align-items: center; + justify-content: center; + position: relative; +} + +.content { + background-color: rgba(255, 255, 255, 0.8); + padding: 20px; + border-radius: 10px; + text-align: center; + position: absolute; +} + +h2 { + color: #1c6cb2; +} + +.links { + margin-top: 20px; +} + +.links .btn { + background-color: #1c6cb2; + color: white; + padding: 10px 20px; + text-decoration: none; + border-radius: 5px; + margin: 10px; + display: inline-block; +} + +.links .btn:hover { + background-color: #155a8c; +} + +footer { + background-color: rgba(28, 108, 178, 0.9); + color: white; + text-align: center; + padding: 10px 0; + width: 100%; +} diff --git a/Project/static/images/banner-login-20200629.jpg b/Project/static/images/banner-login-20200629.jpg new file mode 100644 index 0000000..21677f4 Binary files /dev/null and b/Project/static/images/banner-login-20200629.jpg differ diff --git a/Project/static/js/index.js b/Project/static/js/index.js new file mode 100644 index 0000000..7190b81 --- /dev/null +++ b/Project/static/js/index.js @@ -0,0 +1,8 @@ +window.onload = function() { + // Display flashed messages, if any + const messages = []; + // Assuming messages are added via server-side templating + if (messages.length > 0) { + alert(messages.join("\n")); + } +}; diff --git a/Project/templates/index.html b/Project/templates/index.html index a08a5b8..a9783d0 100644 --- a/Project/templates/index.html +++ b/Project/templates/index.html @@ -1,24 +1,36 @@
+ +