完成实验7的代码部分

This commit is contained in:
Jingfan Ke 2024-06-02 23:47:31 +08:00
parent 875a5dcd61
commit 4721dda1fa
17 changed files with 100796 additions and 100024 deletions

View File

@ -0,0 +1,22 @@
执行语句: DROP TABLE IF EXISTS passengers;
执行语句: DROP TRIGGER IF EXISTS BeforeInsertPassenger;
执行语句: DROP TRIGGER IF EXISTS BeforeModifyPassengerInfo;
执行语句: DROP PROCEDURE IF EXISTS RegisterPassenger;
执行语句: DROP PROCEDURE IF EXISTS VerifyUser;
执行语句: DROP PROCEDURE IF EXISTS ModifyPassengerInfo;
执行语句: 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}$')
);
执行语句: DELIMITER //
CREATE TRIGGER BeforeInsertPassenger
BEFORE INSERT ON passengers
FOR EACH ROW
BEGIN
DECLARE id_exist INT DEFAULT 0;
执行过程中出现错误: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER //\n\nCREATE TRIGGER BeforeInsertPassenger\nBEFORE INSERT ON passengers\nF' at line 1")

View File

@ -0,0 +1,119 @@
DROP TABLE IF EXISTS passengers;
DROP TRIGGER IF EXISTS BeforeInsertPassenger;
DROP TRIGGER IF EXISTS BeforeModifyPassengerInfo;
DROP PROCEDURE IF EXISTS RegisterPassenger;
DROP PROCEDURE IF EXISTS VerifyUser;
DROP PROCEDURE IF EXISTS ModifyPassengerInfo;
CREATE TABLE passengers (
ID BIGINT PRIMARY KEY,
`Name` VARCHAR (255) NOT NULL,
Phone_number BIGINT NOT NULL,
`Password` VARCHAR (255) NOT NULL,
CHECK (ID REGEXP '^\\d{18}$'),
CHECK (Phone_number REGEXP '^\\d{11}$')
);
DELIMITER //
CREATE TRIGGER BeforeInsertPassenger
BEFORE INSERT ON passengers
FOR EACH ROW
BEGIN
DECLARE id_exist INT DEFAULT 0;
SELECT COUNT(*) INTO id_exist
FROM passengers
WHERE ID = NEW.ID;
IF id_exist != 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '乘客已存在,无法重复注册';
END IF;
END;
//
CREATE TRIGGER BeforeModifyPassengerInfo
BEFORE UPDATE ON passengers
FOR EACH ROW
BEGIN
DECLARE id_exist INT DEFAULT 0;
SELECT COUNT(*) INTO id_exist
FROM passengers
WHERE ID = NEW.ID;
IF id_exist = 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '用户不存在,无法修改';
END IF;
END;
//
CREATE PROCEDURE RegisterPassenger(
IN p_id BIGINT,
IN p_name VARCHAR(255),
IN p_phone_number BIGINT,
IN p_password VARCHAR(255),
OUT result_message VARCHAR(255)
)
BEGIN
INSERT INTO passengers (ID, `Name`, Phone_number, `Password`)
VALUES (p_id, p_name, p_phone_number, p_password);
SET result_message = '注册成功';
END;
//
CREATE PROCEDURE VerifyUser(
IN p_id BIGINT,
IN p_password VARCHAR(255),
OUT verify_status VARCHAR(255)
)
BEGIN
DECLARE id_exist INT DEFAULT 0;
DECLARE record_password VARCHAR(255);
SELECT COUNT(*) INTO id_exist
FROM passengers
WHERE ID = p_id;
IF id_exist = 0 THEN
SET verify_status = 'NO_USER';
ELSE
SELECT `Password` INTO record_password
FROM passengers
WHERE ID = p_id;
IF record_password != p_password THEN
SET verify_status = 'WRONG_PASSWORD';
ELSE
SET verify_status = 'USER_VERIFIED';
END IF;
END IF;
END;
//
CREATE PROCEDURE ModifyPassengerInfo(
IN p_id BIGINT,
IN p_modify_type VARCHAR(255),
IN p_new_password VARCHAR(255),
IN p_phone_number BIGINT,
OUT result_message VARCHAR(255)
)
BEGIN
IF p_modify_type = 'delete account' THEN
DELETE FROM passengers WHERE ID = p_id;
SET result_message = '删除账户成功';
ELSEIF p_modify_type = 'modify Password' THEN
UPDATE passengers SET `Password` = p_new_password WHERE ID = p_id;
SET result_message = '修改密码成功';
ELSEIF p_modify_type = 'modify Phone_Number' THEN
UPDATE passengers SET Phone_number = p_phone_number WHERE ID = p_id;
SET result_message = '修改手机号成功';
ELSE
SET result_message = '无效的修改类型';
END IF;
END;
//
DELIMITER ;

View File

@ -0,0 +1,34 @@
import pymysql
# 数据库连接配置
db_config = {
'host': 'localhost',
'user': 'kejingfan',
'password': 'KJF2811879',
'database': 'DBLab_7_1',
'charset': 'utf8mb4',
'cursorclass': pymysql.cursors.DictCursor
}
with open('db.sql', 'r', encoding='utf-8') as file:
sql_script = file.read()
connection = pymysql.connect(**db_config)
try:
with connection.cursor() as cursor:
for statement in sql_script.split(";"):
statement = statement.strip() + ';'
if statement:
print(f"执行语句: {statement}")
cursor.execute(statement)
# 提交更改
connection.commit()
print("SQL 脚本执行成功")
except pymysql.MySQLError as e:
print(f"执行过程中出现错误: {e}")
connection.rollback()
finally:
connection.close()

View File

@ -0,0 +1,128 @@
from flask import Flask, render_template, request, flash, redirect, url_for
import pymysql
from pymysql.cursors import Cursor
import os
from typing import Dict
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='DBLab_7_1',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor
)
@app.route("/")
def index():
return render_template("index.html")
@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()
try:
cursor.callproc('RegisterPassenger', (id, name, phone_number, password, "@result_message"))
cursor.fetchall()
cursor.execute("SELECT @_RegisterPassenger_4;")
result_message = cursor.fetchone()['@_RegisterPassenger_4']
print(result_message)
flash(result_message)
db.commit()
except pymysql.MySQLError as e:
db.rollback()
if e.args[0] == 1644: # SQLSTATE 45000 corresponds to error code 1644
flash("乘客已存在,无法重复注册")
else:
print(e)
flash("数据库异常,注册失败")
db.close()
return redirect(url_for('index'))
def verify_user(cursor: Cursor, id: str, password: str) -> str:
try:
cursor.callproc('VerifyUser', (id, password, "@verify_status"))
cursor.fetchall()
cursor.execute("SELECT @_VerifyUser_2;")
verify_status = cursor.fetchone()['@_VerifyUser_2']
except pymysql.MySQLError as e:
print(e)
if e.args[0] == 1644: # SQLSTATE 45000 corresponds to error code 1644
return "NO_USER"
return "DB_ERROR"
return verify_status
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'] if form['mobileNo'] != "" else "11111111111"
modifyType2command = {
'1': 'delete account',
'2': 'modify Password',
'3': 'modify Phone_Number'
}
self.command = modifyType2command[modifyType]
def get_args(self):
return (self.id, self.command, self.new_password, self.phone_number, "@result_message")
def get_ok_message(self, cursor):
cursor.execute("SELECT @_ModifyPassengerInfo_4;")
return cursor.fetchone()['@_ModifyPassengerInfo_4']
@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'))
elif verify_info == "DB_ERROR":
db.close()
return redirect(url_for('modify'))
modifyInfo = ModifyInfo(request.form)
try:
cursor.callproc('ModifyPassengerInfo', modifyInfo.get_args())
cursor.fetchall()
db.commit()
flash(modifyInfo.get_ok_message(cursor))
except pymysql.MySQLError as e:
db.rollback()
if e.args[0] == 1644: # SQLSTATE 45000 corresponds to error code 1644
flash("用户不存在,无法修改")
else:
print(e)
flash("数据库异常,修改失败")
db.close()
return redirect(url_for('index'))
if __name__ == "__main__":
app.run(debug=True)

View File

@ -0,0 +1,12 @@
blinker==1.8.1
cffi==1.16.0
click==8.1.7
configparser==7.0.0
cryptography==42.0.6
Flask==3.0.3
itsdangerous==2.2.0
Jinja2==3.1.3
MarkupSafe==2.1.5
pycparser==2.22
PyMySQL==1.1.0
Werkzeug==3.0.2

View File

@ -0,0 +1 @@
SECRET_KEY='ILOVEDATABASETECH' FLASK_APP=main FLASK_ENV=development flask run --host 0.0.0.0 --port 5000

View File

@ -0,0 +1,9 @@
/* h1, ul, li, a, body {
margin: 0;
padding: 0;
text-decoration: none;
} */
li {
list-style: none;
}

View File

@ -0,0 +1,51 @@
var checkInfo = {}
checkInfo.checkCardCode = function() {
let cardCode = document.getElementById('cardCode').value
let regexCardCode = /^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
if(!regexCardCode.test(cardCode)) {
alert('身份证号格式有误')
return false
}
return true
}
checkInfo.checkMobileNo = function() {
let mobileNo = document.getElementById('mobileNo').value
let regexMobileNo = /^1[3-9]\d{9}$/
if (!regexMobileNo.test(mobileNo)) {
alert('手机号格式有误')
return false
}
return true
}
checkInfo.checkPassword = function() {
let password = document.getElementById('password')
let regexPassword = /^[A-Za-z0-9\W_]{6,20}$/
if (!regexPassword.test(password.value)) {
alert("密码须为长度为6-20位字母、数字或符号")
return false
}
let confirmPassword = document.getElementById('confirmPassword')
if (password.value !== confirmPassword.value) {
alert("两次输入的密码不一致")
return false
}
return true
}
checkInfo.checkNewPassword = function() {
let password = document.getElementById('newPassword')
let regexPassword = /^[A-Za-z0-9\W_]{6,20}$/
if (!regexPassword.test(password.value)) {
alert("密码须为长度为6-20位字母、数字或符号")
return false
}
let confirmPassword = document.getElementById('confirmNewPassword')
if (password.value !== confirmPassword.value) {
alert("两次输入的密码不一致")
return false
}
return true
}

View File

@ -0,0 +1,28 @@
var modify = {}
modify.showModifyPassword = function() {
let modifyType = document.getElementById('modifyType').value
let info = {
modifyPasswordLis: document.getElementsByClassName('modifyPassword'),
modifymobileNoLis: document.getElementsByClassName('modifymobileNo'),
}
// 遍历隐藏所有元素
for (let key in info) {
let elements = info[key];
for (let item of elements) {
item.style.display = 'none'; // 确保所有相关元素被隐藏
}
}
// 根据 modifyType 显示相关元素
if (modifyType === "2") {
for (let item of info.modifyPasswordLis) {
item.style.display = 'block';
}
} else if (modifyType === "3") {
for (let item of info.modifymobileNoLis) {
item.style.display = 'block';
}
}
}

View File

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>我的12306官网</title>
<script>
window.onload = function() {
{% with messages = get_flashed_messages() %}
{% if messages %}
var message = "";
{% for msg in messages %}
message += "{{ msg }}\n";
{% endfor %}
alert(message);
{% endif %}
{% endwith %}
};
</script>
</head>
<body>
<h1>Coming soon~</h1>
<div><a href="signup.html">点击跳转注册</a></div>
<div><a href="modify.html">点击跳转修改账号</a></div>
</body>
</html>

View File

@ -0,0 +1,96 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>修改账户</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<script src="https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js"></script>
<script>
window.onload = function() {
{% with messages = get_flashed_messages() %}
{% if messages %}
var message = "";
{% for msg in messages %}
message += "{{ msg }}\n";
{% endfor %}
alert(message);
{% endif %}
{% endwith %}
};
</script>
</head>
<body>
<form action="#" method="post">
<ul>
<div>
<div>证件号码:</div>
<input type="text" id="cardCode" name="cardCode" placeholder="请输入您的证件号码" required>
</div>
</li>
<li>
<div>
<div>登陆密码:</div>
<input type="password" id="password" placeholder="请输入您的密码" required>
<input id="encryptedPassword" name="encryptedPassword" type="hidden">
</div>
</li>
<li>
<div>
<div>修改内容:</div>
<select id="modifyType" name="modifyType" onchange="modify.showModifyPassword()" aria-label="请选择您的修改内容" title="请选择您的修改内容" required>
<option value="1">删除账户</option>
<option value="2">修改密码</option>
<option value="3">修改手机号</option>
</select>
</div>
</li>
<li class="modifyPassword" style="display: none;">
<div>
<div>修改密码:</div>
<input type="password" id="newPassword" placeholder="6-20位字母、数字或符号">
<input id="encryptedNewPassword" name="encryptedNewPassword" type="hidden">
</div>
</li>
<li class="modifyPassword" style="display: none;">
<div>
<div>确认密码:</div>
<input type="password" id="confirmPassword" placeholder="再次输入您的修改密码">
</div>
</li>
<li class="modifymobileNo" style="display: none;">
<div>
<div>修改手机号:</div>
<input type="text" id="mobileNo" name="mobileNo" value title="手机号码" aria-label="手机号码" maxlength="11" placeholder="11位手机号">
</div>
</li>
<div>
<button type="submit" onclick="return submitForm()">确认</button>
</div>
</ul>
</form>
<script src="{{ url_for('static', filename='js/checkInfo.js') }}"></script>
<script src="{{ url_for('static', filename='js/modify.js') }}"></script>
<script>
function submitForm() {
document.getElementById('encryptedPassword').value = md5(
document.getElementById('password').value
)
let modifyType = document.getElementById('modifyType').value
if (modifyType === '1') {
// document.getElementById('newPassword') = ''
return true
} else if (modifyType == '2') {
document.getElementById('encryptedNewPassword').value = md5(
document.getElementById('newPassword').value
)
return checkInfo.checkNewPassword()
} else if (modifyType == '3') {
return checkInfo.checkMobileNo()
}
}
</script>
</body>
</html>

View File

@ -0,0 +1,115 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>我的12306注册</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<script src="https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js"></script>
<script>
window.onload = function() {
{% with messages = get_flashed_messages() %}
{% if messages %}
var message = "";
{% for msg in messages %}
message += "{{ msg }}\n";
{% endfor %}
alert(message);
{% endif %}
{% endwith %}
};
</script>
</head>
<body>
<form action="#" method="post">
<ul>
<li>
<div>
<div>用 户 名:</div>
<input type="text" id="name" name="name" placeholder="用户名设置成功后不可修改" required>
</div>
</li>
<li>
<div>
<div>登陆密码:</div>
<input type="password" id="password" placeholder="6-20位字母、数字或符号" required>
<input id="encryptedPassword" name="encryptedPassword" type="hidden">
</div>
</li>
<li>
<div>
<div>确认密码:</div>
<input type="password" id="confirmPassword" placeholder="再次输入您的登录密码" required>
</div>
</li>
<li>
<div>
<div>证件类型:</div>
<input name="cardTypeCode" id="cardTypeCode" value="1" type="hidden">
<select id="cardType" aria-label="请选择您的证件类型" title="请选择您的证件类型" required>
<option value="1">中国居民身份证</option>
<option value="1">港澳台居民身份证</option>
</select>
</div>
</li>
<li>
<div>
<div>姓 名:</div>
<input type="text" id="regist_name" name="regist_name" placeholder="请输入姓名" required>
</div>
</li>
<li>
<div>
<div>证件号码:</div>
<input type="text" id="cardCode" name="cardCode" placeholder="请输入您的证件号码" maxlength="18" required>
</div>
</li>
<li>
<div>
<div>优惠(待)类型:</div>
<select id="passengerType" name="passengerType" aria-label="请选择旅客类型" title="请选择旅客类型" required>
<option value="1">成人</option>
<option value="2">儿童</option>
<option value="3">学生</option>
<option value="4">残疾军人</option>
</select>
</div>
</li>
<li style="height: 1px;border-top: 1px dashed #DEDEDE;margin: 15px 0;"></li>
<li>
<div>
<div>邮 箱:</div>
<input type="text" id="email" name="email" title="请正确填写邮箱地址" placeholder="请正确填写邮箱地址" aria-label="请正确填写邮箱地址" required>
</div>
</li>
<li>
<div>
<div>手机号码:</div>
<div>
<select id="mobileCode" name="mobileCode" required>
<option value="86">+86 中国</option>
</select>
<input type="text" id="mobileNo" name="mobileNo" value title="手机号码" aria-label="手机号码" maxlength="11" required>
</div>
</div>
</li>
<div>
<button type="submit" onclick="return submitForm()">下一步</button>
</div>
</ul>
</form>
<script src="{{ url_for('static', filename='js/checkInfo.js') }}"></script>
<script>
function submitForm() {
if (checkInfo.checkCardCode() && checkInfo.checkMobileNo() && checkInfo.checkPassword()) {
document.getElementById('encryptedPassword').value = md5(
document.getElementById('password').value
)
return true
}
return false
}
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,113 @@
anyio==4.4.0
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
arrow==1.3.0
asttokens==2.4.1
async-lru==2.0.4
attrs==23.2.0
Babel==2.15.0
beautifulsoup4==4.12.3
bleach==6.1.0
blinker==1.8.1 blinker==1.8.1
certifi==2024.2.2
cffi==1.16.0 cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7 click==8.1.7
comm==0.2.2
configparser==7.0.0 configparser==7.0.0
contourpy==1.2.1
cryptography==42.0.6 cryptography==42.0.6
cycler==0.12.1
debugpy==1.8.1
decorator==5.1.1
defusedxml==0.7.1
executing==2.0.1
fastjsonschema==2.19.1
Flask==3.0.3 Flask==3.0.3
fonttools==4.52.4
fqdn==1.5.1
h11==0.14.0
httpcore==1.0.5
httpx==0.27.0
idna==3.7
ipykernel==6.29.4
ipython==8.24.0
isoduration==20.11.0
itsdangerous==2.2.0 itsdangerous==2.2.0
jedi==0.19.1
Jinja2==3.1.3 Jinja2==3.1.3
json5==0.9.25
jsonpointer==2.4
jsonschema==4.22.0
jsonschema-specifications==2023.12.1
jupyter_client==8.6.2
jupyter_core==5.7.2
jupyter-events==0.10.0
jupyter-lsp==2.2.5
jupyter_server==2.14.1
jupyter_server_terminals==0.5.3
jupyterlab==4.2.1
jupyterlab_pygments==0.3.0
jupyterlab_server==2.27.2
kiwisolver==1.4.5
MarkupSafe==2.1.5 MarkupSafe==2.1.5
matplotlib==3.9.0
matplotlib-inline==0.1.7
mistune==3.0.2
nbclient==0.10.0
nbconvert==7.16.4
nbformat==5.10.4
nest-asyncio==1.6.0
notebook==7.2.0
notebook_shim==0.2.4
numpy==1.26.4
overrides==7.7.0
packaging==24.0
pandas==2.2.2
pandocfilters==1.5.1
parso==0.8.4
pexpect==4.9.0
pillow==10.3.0
pip==24.0
platformdirs==4.2.2
prometheus_client==0.20.0
prompt_toolkit==3.0.45
psutil==5.9.8
ptyprocess==0.7.0
pure-eval==0.2.2
pycparser==2.22 pycparser==2.22
Pygments==2.18.0
PyMySQL==1.1.0 PyMySQL==1.1.0
pyparsing==3.1.2
python-dateutil==2.9.0.post0
python-json-logger==2.0.7
pytz==2024.1
PyYAML==6.0.1
pyzmq==26.0.3
referencing==0.35.1
requests==2.32.3
rfc3339-validator==0.1.4
rfc3986-validator==0.1.1
rpds-py==0.18.1
Send2Trash==1.8.3
setuptools==69.5.1
six==1.16.0
sniffio==1.3.1
soupsieve==2.5
stack-data==0.6.3
terminado==0.18.1
tinycss2==1.3.0
tornado==6.4
tqdm==4.66.4
traitlets==5.14.3
types-python-dateutil==2.9.0.20240316
typing_extensions==4.12.0
tzdata==2024.1
uri-template==1.3.0
urllib3==2.2.1
wcwidth==0.2.13
webcolors==1.13
webencodings==0.5.1
websocket-client==1.8.0
Werkzeug==3.0.2 Werkzeug==3.0.2
jupyterlab wheel==0.43.0
notebook