添加期末大作业文件夹Project,目前与Assignment5中一致

This commit is contained in:
typingbugs 2024-05-26 21:49:58 +08:00
parent 53d8334ba3
commit 8dd5a17062
12 changed files with 542 additions and 0 deletions

Binary file not shown.

10
Project/db.sql Normal file
View File

@ -0,0 +1,10 @@
DROP TABLE IF EXISTS passengers;
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}$')
);

17
Project/init_db.py Normal file
View File

@ -0,0 +1,17 @@
import pymysql
db = pymysql.connect(
host='localhost', user='kejingfan',
password='KJF2811879', database='TESTDB'
)
cursor = db.cursor()
with open('db.sql', 'r') as f:
sql_commands = f.read().split(';')
for command in sql_commands:
if command.strip(): # 确保不执行空命令
cursor.execute(command)
db.close()

179
Project/main.py Normal file
View File

@ -0,0 +1,179 @@
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='TESTDB'
)
@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()
# 检查已有用户
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]
@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'))

12
Project/requirements.txt Normal file
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

1
Project/run.sh Normal file
View File

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

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>