This commit is contained in:
2025-09-18 17:17:35 +08:00
parent 8de14edf9d
commit 01503d6862
11 changed files with 1378 additions and 1504 deletions
+256 -125
View File
@@ -23,16 +23,6 @@ def init_user_db():
)
''')
# 创建登录信息表
cursor.execute('''
CREATE TABLE IF NOT EXISTS login_info (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
password TEXT NOT NULL,
otp_code TEXT
)
''')
# 检查是否存在admin用户,如果不存在则创建
cursor.execute("SELECT * FROM users WHERE username = 'admin'")
if not cursor.fetchone():
@@ -41,9 +31,6 @@ def init_user_db():
"INSERT INTO users (username, password, name, phone, department) VALUES (?, ?, ?, ?, ?)",
('admin', 'admin123', '管理员', '13800138000', '管理部')
)
# 同时插入到登录信息表
cursor.execute("INSERT INTO login_info (username, password, otp_code) VALUES (?, ?, ?)",
('admin', 'admin123', ''))
# 插入一些测试数据
cursor.execute("SELECT COUNT(*) FROM users")
@@ -60,8 +47,6 @@ def init_user_db():
"INSERT INTO users (username, password, name, phone, department) VALUES (?, ?, ?, ?, ?)",
user
)
cursor.execute("INSERT INTO login_info (username, password, otp_code) VALUES (?, ?, ?)",
(user[0], user[1], ''))
conn.commit()
conn.close()
@@ -93,19 +78,7 @@ def login():
session['department'] = user[5] # 部门
session['login_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# 检查是否有login_info记录,如果没有则创建
cursor.execute("SELECT * FROM login_info WHERE username = ?", (username,))
login_info = cursor.fetchone()
if not login_info:
cursor.execute("INSERT INTO login_info (username, password, otp_code) VALUES (?, ?, ?)",
(username, password, ""))
conn.commit()
# 设置session中的OTP码为空
session['otp_code'] = ""
else:
# 设置session中的OTP码
session['otp_code'] = login_info[3] if login_info[3] else ""
conn.close()
@@ -154,9 +127,7 @@ def register():
"INSERT INTO users (username, password, name, phone, department) VALUES (?, ?, ?, ?, ?)",
(username, password, name, phone, department)
)
# 同时插入到登录信息表,不自动生成OTP码
cursor.execute("INSERT INTO login_info (username, password, otp_code) VALUES (?, ?, ?)",
(username, password, ""))
conn.commit()
conn.close()
# 注册成功,跳转到登录页并显示成功消息
@@ -203,8 +174,7 @@ def change_password():
# 更新密码
cursor.execute("UPDATE users SET password = ? WHERE username = ?", (new_password, session['username']))
# 同时更新login_info表中的密码
cursor.execute("UPDATE login_info SET password = ? WHERE username = ?", (new_password, session['username']))
conn.commit()
conn.close()
@@ -283,91 +253,7 @@ def update_user_profile():
conn.close()
return jsonify({'success': False, 'error': f'更新失败,请重试。错误:{str(e)}'})
# 获取登录信息路由
@bp.route('/get_login_info', methods=['GET'])
def get_login_info():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
# 获取登录时间 - 如果会话中没有存储登录时间,可以使用当前时间
login_time = session.get('login_time', datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
# 获取登录IP地址
login_ip = request.remote_addr
# 构造返回数据
return jsonify({
'success': True,
'login_time': login_time,
'login_ip': login_ip
})
# 登录信息更新路由
@bp.route('/update_login_info', methods=['POST'])
def update_login_info():
import re
if 'username' not in session:
return jsonify({'success': False, 'error': '请先登录'}), 401
data = request.get_json()
username = data.get('username')
password = data.get('password')
otp_code = data.get('otp_code')
# 验证输入
if not username or not otp_code:
return jsonify({'success': False, 'error': '用户名和OTP码不能为空'})
# 验证OTP码长度必须是6位
if len(otp_code) != 6:
return jsonify({'success': False, 'error': 'OTP码长度必须是6位'})
# 确保用户只能更新自己的信息
if username != session['username'] and session['username'] != 'admin':
return jsonify({'success': False, 'error': '无权更新其他用户的信息'})
# 连接数据库
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
try:
# 构建更新语句
if session['username'] == 'admin':
# admin用户可以更新所有字段
if password:
# 只验证密码不为空,不限制格式
cursor.execute("UPDATE login_info SET password = ?, otp_code = ? WHERE username = ?",
(password, otp_code, username))
else:
cursor.execute("UPDATE login_info SET otp_code = ? WHERE username = ?", (otp_code, username))
else:
# 普通用户只能更新自己的OTP码
cursor.execute("UPDATE login_info SET otp_code = ? WHERE username = ?", (otp_code, session['username']))
# 检查是否有行被更新
if cursor.rowcount == 0:
# 如果没有找到记录,则插入新记录
if session['username'] == 'admin':
# admin用户可以为任何用户创建登录信息
cursor.execute("INSERT INTO login_info (username, password, otp_code) VALUES (?, ?, ?)",
(username, password or 'default_password', otp_code))
else:
# 普通用户只能创建自己的登录信息
cursor.execute("INSERT INTO login_info (username, password, otp_code) VALUES (?, ?, ?)",
(session['username'], 'default_password', otp_code))
# 提交更改
conn.commit()
# 如果更新的是当前登录用户的信息,更新session中的OTP码
if username == session['username']:
session['otp_code'] = otp_code
conn.close()
return jsonify({'success': True, 'message': '登录信息更新成功'})
except Exception as e:
conn.close()
return jsonify({'success': False, 'error': f'更新失败:{str(e)}'})
# 登出路由
@bp.route('/logout')
@@ -535,13 +421,7 @@ def reset_user_password():
# 更新users表中的密码
cursor.execute("UPDATE users SET password = ? WHERE id = ?", (default_password, user_id))
# 更新login_info表中的密码
cursor.execute("UPDATE login_info SET password = ? WHERE username = ?", (default_password, username))
# 如果login_info表中没有该用户的记录,则插入
if cursor.rowcount == 0:
cursor.execute("INSERT INTO login_info (username, password, otp_code) VALUES (?, ?, ?)",
(username, default_password, ""))
conn.commit()
conn.close()
@@ -549,4 +429,255 @@ def reset_user_password():
return jsonify({'success': True, 'message': '密码已初始化为:' + default_password})
except Exception as e:
conn.close()
return jsonify({'success': False, 'error': f'密码重置失败:{str(e)}'})
return jsonify({'success': False, 'error': f'密码重置失败:{str(e)}'})
# 创建参数配置表(如果不存在)
def create_parameter_config_table():
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
# 创建参数配置表
cursor.execute('''
CREATE TABLE IF NOT EXISTS parameter_config (
id INTEGER PRIMARY KEY AUTOINCREMENT,
param1 TEXT,
param2 TEXT,
param3 TEXT,
param4 TEXT,
param5 TEXT,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
# 检查是否存在参数配置记录,如果不存在则插入第一条记录
cursor.execute("SELECT COUNT(*) FROM parameter_config")
count = cursor.fetchone()[0]
if count == 0:
cursor.execute(
"INSERT INTO parameter_config (param1, param2, param3, param4, param5, update_time) VALUES (?, ?, ?, ?, ?, ?)",
('默认参数1', '默认参数2', '默认参数3', '默认参数4', '默认参数5', datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
)
conn.commit()
conn.close()
# 获取参数配置路由
@bp.route('/get_parameter_config', methods=['GET'])
def get_parameter_config():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
try:
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
# 查询参数配置
cursor.execute("SELECT param1, param2, param3, param4, param5, update_time FROM parameter_config ORDER BY update_time DESC LIMIT 1")
config = cursor.fetchone()
conn.close()
if not config:
return jsonify({'success': False, 'error': '未找到参数配置'})
# 构造返回数据
parameters = {
'param1': config[0],
'param2': config[1],
'param3': config[2],
'param4': config[3],
'param5': config[4],
'update_time': config[5]
}
return jsonify({'success': True, 'parameters': parameters})
except Exception as e:
return jsonify({'success': False, 'error': f'获取参数配置失败:{str(e)}'})
# 保存参数配置路由
@bp.route('/save_parameter_config', methods=['POST'])
def save_parameter_config():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
# 只有管理员可以修改参数配置
if session['username'] != 'admin':
return jsonify({'success': False, 'error': '无权限修改参数配置'}), 403
# 获取请求数据
data = request.get_json()
if not data:
return jsonify({'success': False, 'error': '请求数据格式错误'}), 400
param1 = data.get('param1', '').strip()
param2 = data.get('param2', '').strip()
param3 = data.get('param3', '').strip()
param4 = data.get('param4', '').strip()
param5 = data.get('param5', '').strip()
# 验证参数
if not param1:
return jsonify({'success': False, 'error': '参数1不能为空'})
try:
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
# 更新参数配置
cursor.execute(
"UPDATE parameter_config SET param1 = ?, param2 = ?, param3 = ?, param4 = ?, param5 = ?, update_time = ? WHERE id = 1",
(param1, param2, param3, param4, param5, datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
)
# 如果没有更新任何记录,插入新记录
if cursor.rowcount == 0:
cursor.execute(
"INSERT INTO parameter_config (param1, param2, param3, param4, param5, update_time) VALUES (?, ?, ?, ?, ?, ?)",
(param1, param2, param3, param4, param5, datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
)
conn.commit()
conn.close()
return jsonify({'success': True, 'message': '参数配置保存成功'})
except Exception as e:
return jsonify({'success': False, 'error': f'保存参数配置失败:{str(e)}'})
# 参数配置页面路由
@bp.route('/parameter_config_page', methods=['GET', 'POST'])
def parameter_config_page():
if 'username' not in session:
return redirect(url_for('user.login'))
# 只有管理员可以访问参数配置页面
if session['username'] != 'admin':
return redirect(url_for('user.user_profile_page', error='无权限访问参数配置页面'))
# 渲染参数配置页面
return render_template('parameter_config.html', current_year=datetime.now().year)
# 修改密码页面路由
@bp.route('/change_password_page', methods=['GET', 'POST'])
def change_password_page():
if 'username' not in session:
return redirect(url_for('user.login'))
if request.method == 'POST':
old_password = request.form.get('old_password')
new_password = request.form.get('new_password')
confirm_password = request.form.get('confirm_password')
# 验证参数
if not old_password or not new_password or not confirm_password:
return render_template('change_password.html', error='请填写所有必填字段')
# 验证新密码和确认密码是否一致
if new_password != confirm_password:
return render_template('change_password.html', error='两次输入的新密码不一致')
# 验证新密码复杂度
if len(new_password) < 8 or not any(c.isalpha() for c in new_password) or not any(c.isdigit() for c in new_password):
return render_template('change_password.html', error='新密码长度至少8位,且必须包含字母和数字')
# 连接数据库,验证旧密码并更新新密码
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
# 验证旧密码是否正确
cursor.execute("SELECT password FROM users WHERE username = ?", (session['username'],))
result = cursor.fetchone()
if not result or result[0] != old_password:
conn.close()
return render_template('change_password.html', error='旧密码不正确')
# 更新密码
cursor.execute("UPDATE users SET password = ? WHERE username = ?", (new_password, session['username']))
conn.commit()
conn.close()
# 密码修改成功,先执行退出功能,再跳转到登录页面
session.clear()
return redirect(url_for('user.login', success='修改密码成功,请重新登录'))
# GET请求,渲染修改密码页面
return render_template('change_password.html', current_year=datetime.now().year)
# 个人信息页面路由
@bp.route('/user_profile_page', methods=['GET', 'POST'])
def user_profile_page():
if 'username' not in session:
return redirect(url_for('user.login'))
# 连接数据库,获取用户信息
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
cursor.execute("SELECT username, name, phone, department FROM users WHERE username = ?", (session['username'],))
user_tuple = cursor.fetchone()
conn.close()
if not user_tuple:
return redirect(url_for('user.login', error='用户不存在'))
# 将元组转换为字典,以便在模板中使用属性访问
user = {
'username': user_tuple[0],
'name': user_tuple[1],
'phone': user_tuple[2],
'department': user_tuple[3]
}
if request.method == 'POST':
name = request.form.get('name', '').strip()
phone = request.form.get('phone', '').strip()
department = request.form.get('department', '').strip()
# 验证参数
if not name or not phone or not department:
return render_template('user_profile.html', user=user, error='请填写所有必填字段', current_year=datetime.now().year)
# 连接数据库,更新用户信息
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
try:
cursor.execute(
"UPDATE users SET name = ?, phone = ?, department = ? WHERE username = ?",
(name, phone, department, session['username'])
)
conn.commit()
# 更新会话中的部门信息
session['department'] = department
session['name'] = name
conn.close()
# 重新获取用户信息
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
cursor.execute("SELECT username, name, phone, department FROM users WHERE username = ?", (session['username'],))
updated_user_tuple = cursor.fetchone()
conn.close()
# 将元组转换为字典
updated_user = {
'username': updated_user_tuple[0],
'name': updated_user_tuple[1],
'phone': updated_user_tuple[2],
'department': updated_user_tuple[3]
}
return render_template('user_profile.html', user=updated_user, success='个人信息更新成功', current_year=datetime.now().year)
except Exception as e:
conn.close()
return render_template('user_profile.html', user=user, error=f'更新失败,请重试。错误:{str(e)}', current_year=datetime.now().year)
# GET请求,渲染个人信息页面
return render_template('user_profile.html', user=user, current_year=datetime.now().year)