This commit is contained in:
2025-09-17 22:33:49 +08:00
parent 461c5bb508
commit 04f77853ba
4 changed files with 573 additions and 525 deletions
+18 -519
View File
@@ -1,13 +1,18 @@
from flask import Flask, render_template, request, redirect, url_for, session
from flask import Flask, render_template, request, redirect, url_for, session, jsonify
from datetime import datetime, timedelta
import sqlite3
import os
import random
from flask import Flask, render_template, request, redirect, url_for, session, jsonify
# 导入用户模块
from user import bp as user_bp, init_user_db
app = Flask(__name__)
app.secret_key = 'your_secret_key' # 生产环境中应该使用更安全的密钥
# 注册用户蓝图
app.register_blueprint(user_bp)
# 确保模板文件夹存在
templates_dir = os.path.join(os.path.dirname(__file__), 'templates')
if not os.path.exists(templates_dir):
@@ -15,20 +20,12 @@ if not os.path.exists(templates_dir):
# 初始化数据库
def init_db():
# 初始化用户相关的数据库
init_user_db()
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
# 创建用户表
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
password TEXT NOT NULL,
name TEXT NOT NULL,
phone TEXT NOT NULL,
department TEXT NOT NULL,
status TEXT DEFAULT 'active' NOT NULL
)
''')
# 创建车辆信息表
cursor.execute('''
CREATE TABLE IF NOT EXISTS car_owners (
@@ -41,6 +38,7 @@ def init_db():
address TEXT
)
''')
# 创建查询历史表
cursor.execute('''
CREATE TABLE IF NOT EXISTS query_history (
@@ -54,30 +52,8 @@ def init_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 NOT NULL,
FOREIGN KEY (username) REFERENCES users (username)
)
''')
# 插入测试数据
# 插入用户和车辆数据
# 插入一些测试车辆数据
try:
# 先检查用户表结构是否有新字段,如果没有则跳过插入,避免错误
cursor.execute("PRAGMA table_info(users)")
columns = [column[1] for column in cursor.fetchall()]
if 'name' in columns and 'phone' in columns and 'department' in columns:
# 检查admin用户是否已存在
cursor.execute("SELECT id FROM users WHERE username = ?", ('admin',))
if not cursor.fetchone():
cursor.execute("INSERT INTO users (username, password, name, phone, department) VALUES (?, ?, ?, ?, ?)", ('admin', 'admin123', '管理员', '13800138000', 'IT部'))
# 同时插入到登录信息表
cursor.execute("INSERT INTO login_info (username, password, otp_code) VALUES (?, ?, ?)", ('admin', 'admin123', str(random.randint(100000, 999999))))
# 插入一些测试车辆数据
test_cars = [
('京A12345', '13800138001', '110101199001011234', '张三', 'zhangsan@example.com', '北京市朝阳区'),
('沪B54321', '13900139001', '310101199001012345', '李四', 'lisi@example.com', '上海市静安区'),
@@ -160,63 +136,16 @@ def init_db():
conn.commit()
conn.close()
# 登录路由
@app.route('/', methods=['GET', 'POST'])
def login():
# 检查用户是否已登录,如果已登录则自动跳转到查询页面
if 'username' in session:
return redirect(url_for('query'))
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
# 先检查用户是否存在于users表中
cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
user = cursor.fetchone()
if user:
# 从login_info表中验证密码
cursor.execute("SELECT password, otp_code FROM login_info WHERE username = ?", (username,))
login_info = cursor.fetchone()
# 如果login_info表中没有该用户的记录,创建一个
if not login_info:
# 不自动生成OTP码,设置为空字符串
otp_code = ""
# 插入到login_info表
cursor.execute("INSERT INTO login_info (username, password, otp_code) VALUES (?, ?, ?)",
(username, password, otp_code))
conn.commit()
is_valid = True
else:
# 验证密码
is_valid = (login_info[0] == password)
otp_code = login_info[1]
if is_valid:
# 登录成功,设置会话信息
session['username'] = username
session['department'] = user[5] if len(user) > 5 else '未知部门'
session['name'] = user[3] if len(user) > 3 else username # 存储用户姓名,默认使用用户名
# 存储登录时间
session['login_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# 存储OTP码
session['otp_code'] = otp_code
conn.close()
return redirect(url_for('query'))
conn.close()
return render_template('login.html', error='用户名或密码错误')
return render_template('login.html')
# 首页重定向到登录页
@app.route('/')
def index():
return redirect(url_for('user.login'))
# 查询路由
@app.route('/query', methods=['GET', 'POST'])
def query():
if 'username' not in session:
return redirect(url_for('login'))
return redirect(url_for('user.login'))
# 获取最近查询历史
formatted_recent_queries = get_recent_queries()
@@ -370,436 +299,6 @@ def get_recent_queries():
})
return formatted_recent_queries
# 注册路由
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
username = request.form.get('username', '').strip()
name = request.form.get('name', '').strip()
phone = request.form.get('phone', '').strip()
department = request.form.get('department', '').strip()
password = request.form.get('password', '')
confirm_password = request.form.get('confirm_password', '')
# 表单验证
if not username or not name or not phone or not department or not password:
return render_template('register.html', error='请填写所有必填字段')
# 密码匹配检查
if password != confirm_password:
return render_template('register.html', error='两次输入的密码不一致')
# 检查用户名是否已存在
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
cursor.execute("SELECT id FROM users WHERE username = ?", (username,))
if cursor.fetchone():
conn.close()
return render_template('register.html', error='该用户名已被注册')
# 插入新用户
try:
cursor.execute(
"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()
# 注册成功,跳转到登录页并显示成功消息
return render_template('login.html', success='注册成功,请登录')
except Exception as e:
conn.close()
return render_template('register.html', error=f'注册失败,请重试。错误:{str(e)}')
return render_template('register.html')
# 修改密码路由
@app.route('/change_password', methods=['POST'])
def change_password():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
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 jsonify({'success': False, 'error': '请填写所有必填字段'})
# 验证新密码和确认密码是否一致
if new_password != confirm_password:
return jsonify({'success': False, '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 jsonify({'success': False, '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 jsonify({'success': False, 'error': '旧密码不正确'})
# 更新密码
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()
return jsonify({'success': True, 'message': '修改密码成功,请重新登录'})
# 获取个人信息路由
@app.route('/get_user_profile', methods=['GET'])
def get_user_profile():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
# 连接数据库,获取用户信息
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
cursor.execute("SELECT username, name, phone, department FROM users WHERE username = ?", (session['username'],))
user = cursor.fetchone()
conn.close()
if not user:
return jsonify({'success': False, 'error': '用户不存在'})
# 构造返回数据
user_data = {
'username': user[0],
'name': user[1],
'phone': user[2],
'department': user[3]
}
return jsonify({'success': True, 'user': user_data})
# 更新个人信息路由
@app.route('/update_user_profile', methods=['POST'])
def update_user_profile():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
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 jsonify({'success': False, 'error': '请填写所有必填字段'})
# 连接数据库,更新用户信息
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()
# 获取更新后的用户信息
cursor.execute("SELECT username, name, phone, department FROM users WHERE username = ?", (session['username'],))
updated_user = cursor.fetchone()
conn.close()
# 更新会话中的部门信息
session['department'] = department
# 构造返回数据
user_data = {
'username': updated_user[0],
'name': updated_user[1],
'phone': updated_user[2],
'department': updated_user[3]
}
return jsonify({'success': True, 'message': '个人信息更新成功', 'user': user_data})
except Exception as e:
conn.close()
return jsonify({'success': False, 'error': f'更新失败,请重试。错误:{str(e)}'})
# 获取登录信息路由
@app.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
})
# 登录信息更新路由
@app.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)}'})
# 登出路由
@app.route('/logout')
def logout():
session.clear()
return redirect(url_for('login'))
# 用户管理页面路由
@app.route('/users_management')
def users_management():
if 'username' not in session:
return redirect(url_for('login'))
# 只有admin用户才能访问用户管理页面
if session['username'] != 'admin':
return redirect(url_for('query'))
# 获取所有部门列表(用于筛选和修改)
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
cursor.execute("SELECT DISTINCT department FROM users")
departments = [dept[0] for dept in cursor.fetchall()]
conn.close()
return render_template('users_management.html', departments=departments)
# 获取用户列表路由
@app.route('/get_users', methods=['GET'])
def get_users():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
# 只有admin用户才能获取用户列表
if session['username'] != 'admin':
return jsonify({'success': False, 'error': '无权限访问'}), 403
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
# 获取所有用户信息
cursor.execute("SELECT id, username, name, department, status FROM users")
users = cursor.fetchall()
conn.close()
# 格式化用户数据
formatted_users = []
for user in users:
formatted_users.append({
'id': user[0],
'username': user[1],
'name': user[2],
'department': user[3],
'status': user[4]
})
return jsonify({'success': True, 'users': formatted_users})
# 更新用户状态路由
@app.route('/update_user_status', methods=['POST'])
def update_user_status():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
# 只有admin用户才能更新用户状态
if session['username'] != 'admin':
return jsonify({'success': False, 'error': '无权限访问'}), 403
data = request.get_json()
user_id = data.get('user_id')
status = data.get('status')
# 验证输入
if not user_id or not status:
return jsonify({'success': False, 'error': '缺少必要参数'})
# 验证状态值
if status not in ['active', 'inactive']:
return jsonify({'success': False, 'error': '状态值无效'})
# 不能禁用admin用户
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
cursor.execute("SELECT username FROM users WHERE id = ?", (user_id,))
user = cursor.fetchone()
if user and user[0] == 'admin' and status == 'inactive':
conn.close()
return jsonify({'success': False, 'error': '不能禁用管理员用户'})
# 更新用户状态
try:
cursor.execute("UPDATE users SET status = ? WHERE id = ?", (status, user_id))
conn.commit()
conn.close()
return jsonify({'success': True, 'message': '用户状态更新成功'})
except Exception as e:
conn.close()
return jsonify({'success': False, 'error': f'更新失败:{str(e)}'})
# 更新用户部门路由
@app.route('/update_user_department', methods=['POST'])
def update_user_department():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
# 只有admin用户才能更新用户部门
if session['username'] != 'admin':
return jsonify({'success': False, 'error': '无权限访问'}), 403
data = request.get_json()
user_id = data.get('user_id')
department = data.get('department')
# 验证输入
if not user_id or not department:
return jsonify({'success': False, 'error': '缺少必要参数'})
# 更新用户部门
try:
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
cursor.execute("UPDATE users SET department = ? WHERE id = ?", (department, user_id))
conn.commit()
conn.close()
return jsonify({'success': True, 'message': '部门信息更新成功'})
except Exception as e:
conn.close()
return jsonify({'success': False, 'error': f'更新失败:{str(e)}'})
# 重置用户密码路由
@app.route('/reset_user_password', methods=['POST'])
def reset_user_password():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
# 只有admin用户才能重置用户密码
if session['username'] != 'admin':
return jsonify({'success': False, 'error': '无权限访问'}), 403
data = request.get_json()
user_id = data.get('user_id')
username = data.get('username')
# 验证输入
if not user_id or not username:
return jsonify({'success': False, 'error': '缺少必要参数'})
# 重置密码为默认值
default_password = 'default123'
try:
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
# 检查用户ID和用户名是否匹配
cursor.execute("SELECT id FROM users WHERE username = ?", (username,))
db_user_id = cursor.fetchone()
if not db_user_id or db_user_id[0] != user_id:
conn.close()
return jsonify({'success': False, 'error': '用户信息不匹配'})
# 更新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()
return jsonify({'success': True, 'message': '密码已初始化为:' + default_password})
except Exception as e:
conn.close()
return jsonify({'success': False, 'error': f'密码重置失败:{str(e)}'})
if __name__ == '__main__':
init_db()
app.run(debug=True)
BIN
View File
Binary file not shown.
+3 -6
View File
@@ -695,13 +695,10 @@
.then(response => response.json())
.then(data => {
if (data.success) {
// 密码修改成功
// 密码修改成功,先执行退出功能,再跳转到登录页面
alert(data.message);
closeChangePasswordModal();
// 跳转到登录页面
setTimeout(() => {
window.location.href = '{{ url_for('login') }}';
}, 1000);
// 重定向到退出路由,系统会自动完成退出并跳转到登录页面
window.location.href = '{{ url_for('logout') }}';
} else if (data.error) {
// 显示服务器返回的错误信息
showPasswordError(data.error);
+552
View File
@@ -0,0 +1,552 @@
import sqlite3
from datetime import datetime
from flask import Blueprint, render_template, request, jsonify, redirect, url_for, session
# 创建用户相关的蓝图
bp = Blueprint('user', __name__)
# 初始化数据库(用户相关部分)
def init_user_db():
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
# 创建用户表
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
password TEXT NOT NULL,
name TEXT NOT NULL,
phone TEXT NOT NULL,
department TEXT NOT NULL,
status TEXT DEFAULT 'active'
)
''')
# 创建登录信息表
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():
# 创建admin用户,默认密码为'admin123'
cursor.execute(
"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")
if cursor.fetchone()[0] <= 1: # 只有admin用户时
# 插入几个测试用户
test_users = [
('user1', 'password1', '张三', '13800138001', '技术部'),
('user2', 'password2', '李四', '13800138002', '销售部'),
('user3', 'password3', '王五', '13800138003', '财务部')
]
for user in test_users:
cursor.execute(
"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()
# 登录路由
@bp.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
# 连接数据库
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
# 验证用户名和密码
cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?", (username, password))
user = cursor.fetchone()
if user:
# 检查用户状态
if user[6] != 'active':
conn.close()
return render_template('login.html', error='用户已被禁用')
# 设置会话信息
session['username'] = user[1] # 用户名
session['name'] = user[3] # 姓名
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()
# 登录成功,跳转到查询页面
return redirect(url_for('query'))
else:
conn.close()
return render_template('login.html', error='用户名或密码错误')
return render_template('login.html')
# 注册路由
@bp.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
confirm_password = request.form.get('confirm_password')
name = request.form.get('name')
phone = request.form.get('phone')
department = request.form.get('department')
# 验证参数
if not username or not password or not confirm_password or not name or not phone or not department:
return render_template('register.html', error='请填写所有必填字段')
# 验证密码是否一致
if password != confirm_password:
return render_template('register.html', error='两次输入的密码不一致')
# 验证密码复杂度
if len(password) < 8 or not any(c.isalpha() for c in password) or not any(c.isdigit() for c in password):
return render_template('register.html', error='密码长度至少8位,且必须包含字母和数字')
# 连接数据库,检查用户名是否已存在
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE username = ?", (username,))
if cursor.fetchone():
conn.close()
return render_template('register.html', error='用户名已存在')
try:
cursor.execute(
"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()
# 注册成功,跳转到登录页并显示成功消息
return render_template('login.html', success='注册成功,请登录')
except Exception as e:
conn.close()
return render_template('register.html', error=f'注册失败,请重试。错误:{str(e)}')
return render_template('register.html')
# 修改密码路由
@bp.route('/change_password', methods=['POST'])
def change_password():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
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 jsonify({'success': False, 'error': '请填写所有必填字段'})
# 验证新密码和确认密码是否一致
if new_password != confirm_password:
return jsonify({'success': False, '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 jsonify({'success': False, '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 jsonify({'success': False, 'error': '旧密码不正确'})
# 更新密码
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()
return jsonify({'success': True, 'message': '修改密码成功,请重新登录'})
# 获取个人信息路由
@bp.route('/get_user_profile', methods=['GET'])
def get_user_profile():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
# 连接数据库,获取用户信息
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
cursor.execute("SELECT username, name, phone, department FROM users WHERE username = ?", (session['username'],))
user = cursor.fetchone()
conn.close()
if not user:
return jsonify({'success': False, 'error': '用户不存在'})
# 构造返回数据
user_data = {
'username': user[0],
'name': user[1],
'phone': user[2],
'department': user[3]
}
return jsonify({'success': True, 'user': user_data})
# 更新个人信息路由
@bp.route('/update_user_profile', methods=['POST'])
def update_user_profile():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
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 jsonify({'success': False, 'error': '请填写所有必填字段'})
# 连接数据库,更新用户信息
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()
# 获取更新后的用户信息
cursor.execute("SELECT username, name, phone, department FROM users WHERE username = ?", (session['username'],))
updated_user = cursor.fetchone()
conn.close()
# 更新会话中的部门信息
session['department'] = department
# 构造返回数据
user_data = {
'username': updated_user[0],
'name': updated_user[1],
'phone': updated_user[2],
'department': updated_user[3]
}
return jsonify({'success': True, 'message': '个人信息更新成功', 'user': user_data})
except Exception as e:
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')
def logout():
session.clear()
return redirect(url_for('user.login'))
# 用户管理页面路由
@bp.route('/users_management')
def users_management():
if 'username' not in session:
return redirect(url_for('user.login'))
# 只有admin用户才能访问用户管理页面
if session['username'] != 'admin':
return redirect(url_for('query'))
# 获取所有部门列表(用于筛选和修改)
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
cursor.execute("SELECT DISTINCT department FROM users")
departments = [dept[0] for dept in cursor.fetchall()]
conn.close()
return render_template('users_management.html', departments=departments)
# 获取用户列表路由
@bp.route('/get_users', methods=['GET'])
def get_users():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
# 只有admin用户才能获取用户列表
if session['username'] != 'admin':
return jsonify({'success': False, 'error': '无权限访问'}), 403
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
# 获取所有用户信息
cursor.execute("SELECT id, username, name, department, status FROM users")
users = cursor.fetchall()
conn.close()
# 格式化用户数据
formatted_users = []
for user in users:
formatted_users.append({
'id': user[0],
'username': user[1],
'name': user[2],
'department': user[3],
'status': user[4]
})
return jsonify({'success': True, 'users': formatted_users})
# 更新用户状态路由
@bp.route('/update_user_status', methods=['POST'])
def update_user_status():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
# 只有admin用户才能更新用户状态
if session['username'] != 'admin':
return jsonify({'success': False, 'error': '无权限访问'}), 403
data = request.get_json()
user_id = data.get('user_id')
status = data.get('status')
# 验证输入
if not user_id or not status:
return jsonify({'success': False, 'error': '缺少必要参数'})
# 验证状态值
if status not in ['active', 'inactive']:
return jsonify({'success': False, 'error': '状态值无效'})
# 不能禁用admin用户
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
cursor.execute("SELECT username FROM users WHERE id = ?", (user_id,))
user = cursor.fetchone()
if user and user[0] == 'admin' and status == 'inactive':
conn.close()
return jsonify({'success': False, 'error': '不能禁用管理员用户'})
# 更新用户状态
try:
cursor.execute("UPDATE users SET status = ? WHERE id = ?", (status, user_id))
conn.commit()
conn.close()
return jsonify({'success': True, 'message': '用户状态更新成功'})
except Exception as e:
conn.close()
return jsonify({'success': False, 'error': f'更新失败:{str(e)}'})
# 更新用户部门路由
@bp.route('/update_user_department', methods=['POST'])
def update_user_department():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
# 只有admin用户才能更新用户部门
if session['username'] != 'admin':
return jsonify({'success': False, 'error': '无权限访问'}), 403
data = request.get_json()
user_id = data.get('user_id')
department = data.get('department')
# 验证输入
if not user_id or not department:
return jsonify({'success': False, 'error': '缺少必要参数'})
# 更新用户部门
try:
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
cursor.execute("UPDATE users SET department = ? WHERE id = ?", (department, user_id))
conn.commit()
conn.close()
return jsonify({'success': True, 'message': '部门信息更新成功'})
except Exception as e:
conn.close()
return jsonify({'success': False, 'error': f'更新失败:{str(e)}'})
# 重置用户密码路由
@bp.route('/reset_user_password', methods=['POST'])
def reset_user_password():
if 'username' not in session:
return jsonify({'success': False, 'error': '未登录'}), 401
# 只有admin用户才能重置用户密码
if session['username'] != 'admin':
return jsonify({'success': False, 'error': '无权限访问'}), 403
data = request.get_json()
user_id = data.get('user_id')
username = data.get('username')
# 验证输入
if not user_id or not username:
return jsonify({'success': False, 'error': '缺少必要参数'})
# 重置密码为默认值
default_password = 'default123'
try:
conn = sqlite3.connect('car_info.db')
cursor = conn.cursor()
# 检查用户ID和用户名是否匹配
cursor.execute("SELECT id FROM users WHERE username = ?", (username,))
db_user_id = cursor.fetchone()
if not db_user_id or db_user_id[0] != user_id:
conn.close()
return jsonify({'success': False, 'error': '用户信息不匹配'})
# 更新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()
return jsonify({'success': True, 'message': '密码已初始化为:' + default_password})
except Exception as e:
conn.close()
return jsonify({'success': False, 'error': f'密码重置失败:{str(e)}'})