From 01503d68620c158372c7b9d428dc0737d05e093c Mon Sep 17 00:00:00 2001 From: bwadmin <7469504@qq.com> Date: Thu, 18 Sep 2025 17:17:35 +0800 Subject: [PATCH] 20250918 --- car_info.db | Bin 36864 -> 40960 bytes check_db.py | 31 ++ templates/change_password.html | 179 ++++++ templates/footer.html | 7 + templates/header.html | 42 ++ templates/js/utils.js | 214 +++++++ templates/parameter_config.html | 271 +++++++++ templates/query.html | 960 +++++++------------------------- templates/user_profile.html | 127 +++++ templates/users_management.html | 670 ++-------------------- user.py | 381 ++++++++----- 11 files changed, 1378 insertions(+), 1504 deletions(-) create mode 100644 check_db.py create mode 100644 templates/change_password.html create mode 100644 templates/footer.html create mode 100644 templates/header.html create mode 100644 templates/js/utils.js create mode 100644 templates/parameter_config.html create mode 100644 templates/user_profile.html diff --git a/car_info.db b/car_info.db index 4a964b0903b47c587f7eeca26cc51b6e4e1d337c..f682b6942f42998a7cfba2c117079acf67af89ad 100644 GIT binary patch delta 1989 zcmaJ?TW=dh6rKcGU9T_G5JD6X@>WqOA@yo5yF0t%y9Fq13hrV6u#;@J3w>9dpPcK=p~M>FYcM$4uTAIoUF zquMj724g{uTAqKi9j970^HTP}cEtbFAKL-eD!^L>j8*}&DUi~%w`TIW*}~ZDY>NN|rAASLCx+x{#Y@SHivI(J`!^S_uYdH@);nL-5)rCV!)5Rl>)+qZm`r26RaG=t_EFH1I(ChhfofEULHS0tY;T}Rb;^STO{z1- zb;e9rzFx)eUoDqc%kw+@_N$%<+UaC^I3UKgF3f`H;698^$kIt9}ikYS># z`#`hqW~;9kZnkwt0q`DHT|eZ>J?LN`xt+!VH^_-M}$1<%kBHLLGFjS zgi)ajHYf{Ku?BW|6!w)bmRGTOlgXfUI*8!Pd==j;HmO&;TK*=zeY6DY27?=}9QT)v zdK+BQusNv59q_iz9N1Gep=}NZr>;CxL5CYXM(ghUA9FM45>OwMxr)fjz{5;J9nUhT zV_C$g_nCvmnPJJ-s+#X_)VyAGlS6GABp;GvKDEC$nk5&3LAK=FFk{XO)TnO|!_cWs z2IZ?Qdq(OTY;*pDBMq8U0=f}vX+~3HaLl#g`v~7Jb!fk0gZb}>E_exW!=S~YVKBIO Ru|8_2o`2R_u1Q@k{sW}J7!Uve delta 1601 zcmaJ>J5Ll*7`+fM!@e%KJVeD^rC3(n@jm9x+`BxCuMiVU8e>I}!cN6#K`|&d7D5!G zi7{G;N@9!^tBKi05(;CXm5HqdAp8IyoqogY%+A82$h#Y;24&Ze6}UaRpv0&-m4g*Cs@Rfl8k;PHUnGmk|De zOZY2Z0sM1(zjUm(AzS)->~NMt?atT=!pnFDkKkRY52?A-*;F$5IXRykO?D){BpxQt zB@V>D#h=D6#QS1DV^E`YGUhg)M_s(T+sK?5-JE&J2onXO3e?F`r$}_xfUoI}?O$b< z*hQg=L|pJ6${drxj~>;TEl9dPL>7eu-AztTRuHa9l|JA>P;X1VMgy_7SZGlQ$`v90 zK@~HpElo;IYAL0A>SIL&>v&l22(XM3Q<5RQ-#~5#h>iSexx8AQjTk^81stXBULgk%|Pm0ZpY{)O#xE+?xCD=Gv2T6dn=2 zogLa1YFKx9Xo#zSn`^SbX(*j?>Dlfb0Xvn_WQ+~!PQQSW+gNb7`9@f^f>MsH1SgIR zDnRrQgYKxCIgOI2?f lOx(CCL`Du`KUHJA%}oUtMf~5k^9cKn)EyhHH}ULJ_Ag0mopk^J diff --git a/check_db.py b/check_db.py new file mode 100644 index 0000000..0b9abac --- /dev/null +++ b/check_db.py @@ -0,0 +1,31 @@ +import sqlite3 + +# 连接数据库 +conn = sqlite3.connect('car_info.db') +cursor = conn.cursor() + +# 查询所有表 +cursor.execute("SELECT name FROM sqlite_master WHERE type='table'") +tables = cursor.fetchall() +print('数据库中的表:', tables) + +# 查询参数配置表 +cursor.execute("SELECT sql FROM sqlite_master WHERE type='table' AND name='parameter_config'") +result = cursor.fetchone() +print('参数配置表SQL:', result) + +# 如果参数配置表存在,查询其结构 +if result: + cursor.execute("PRAGMA table_info(parameter_config)") + columns = cursor.fetchall() + print('参数配置表结构:') + for col in columns: + print(f"字段: {col[1]}, 类型: {col[2]}") + + # 查询数据 + cursor.execute("SELECT * FROM parameter_config") + data = cursor.fetchall() + print('参数配置数据:', data) + +# 关闭连接 +conn.close() \ No newline at end of file diff --git a/templates/change_password.html b/templates/change_password.html new file mode 100644 index 0000000..2928858 --- /dev/null +++ b/templates/change_password.html @@ -0,0 +1,179 @@ + + + + + + 修改密码 - 车主信息查询系统 + + + + + + + + + + + {% include 'header.html' %} + + +
+ + + + +
+
+
+ +
+

修改密码

+

请填写以下信息以修改您的密码

+
+ + + {% if error %} +
+ + {{ error }} +
+ {% endif %} + + +
+
+ +
+ + +
+
+
+ +
+ + +
+

密码长度至少8位,包含字母和数字

+
+
+ +
+ + +
+
+
+ + +
+
+
+
+ + {% include 'footer.html' %} + + + + + \ No newline at end of file diff --git a/templates/footer.html b/templates/footer.html new file mode 100644 index 0000000..bad5a4e --- /dev/null +++ b/templates/footer.html @@ -0,0 +1,7 @@ + +
+
+

© {{ current_year }} 车主信息查询系统 - 版权所有

+

免责声明:本系统为内部测试使用,仅供学习和研究。

+
+
\ No newline at end of file diff --git a/templates/header.html b/templates/header.html new file mode 100644 index 0000000..5a6aeea --- /dev/null +++ b/templates/header.html @@ -0,0 +1,42 @@ + +
+
+
+ +

车主信息查询系统

+
+ +
+ +
+
+ 欢迎 {{ session.department }} {{ session.name }} + +
+ + +
+
+
+
\ No newline at end of file diff --git a/templates/js/utils.js b/templates/js/utils.js new file mode 100644 index 0000000..efee893 --- /dev/null +++ b/templates/js/utils.js @@ -0,0 +1,214 @@ +// 通用工具函数 + +/** + * 显示模态框 + * @param {string} modalId - 模态框的ID + */ +function showModal(modalId) { + const modal = document.getElementById(modalId); + if (modal) { + modal.classList.remove('hidden'); + } +} + +/** + * 关闭模态框 + * @param {string} modalId - 模态框的ID + */ +function closeModal(modalId) { + const modal = document.getElementById(modalId); + if (modal) { + modal.classList.add('hidden'); + } +} + +/** + * 绑定模态框点击外部关闭事件 + * @param {string} modalId - 模态框的ID + */ +function bindModalOutsideClick(modalId) { + const modal = document.getElementById(modalId); + if (modal) { + modal.addEventListener('click', function(e) { + if (e.target === this) { + closeModal(modalId); + } + }); + } +} + +/** + * 显示消息提示 + * @param {string} message - 消息内容 + * @param {boolean} isSuccess - 是否为成功消息 + * @param {number} duration - 消息显示时长(毫秒) + */ +function showMessage(message, isSuccess = true, duration = 5000) { + const messageContainer = document.getElementById('messageContainer'); + const successMessage = document.getElementById('successMessage'); + const errorMessage = document.getElementById('errorMessage'); + + if (!messageContainer || !successMessage || !errorMessage) return; + + if (isSuccess) { + successMessage.querySelector('span').textContent = message; + successMessage.classList.remove('hidden'); + errorMessage.classList.add('hidden'); + } else { + errorMessage.querySelector('span').textContent = message; + errorMessage.classList.remove('hidden'); + successMessage.classList.add('hidden'); + } + + messageContainer.classList.remove('hidden'); + + // 自动隐藏 + setTimeout(() => { + (isSuccess ? successMessage : errorMessage).classList.add('hidden'); + messageContainer.classList.add('hidden'); + }, duration); +} + +/** + * 显示表单错误消息 + * @param {string} errorId - 错误容器的ID + * @param {string} messageId - 错误消息的ID + * @param {string} message - 错误消息内容 + * @param {string} successId - 成功消息容器的ID + */ +function showFormError(errorId, messageId, message, successId = '') { + const errorContainer = document.getElementById(errorId); + const errorMessage = document.getElementById(messageId); + const successContainer = successId ? document.getElementById(successId) : null; + + if (!errorContainer || !errorMessage) return; + + errorMessage.textContent = message; + errorContainer.classList.remove('hidden'); + + if (successContainer) { + successContainer.classList.add('hidden'); + } + + // 滚动到错误信息 + errorContainer.scrollIntoView({ behavior: 'smooth', block: 'start' }); +} + +/** + * 显示表单成功消息 + * @param {string} successId - 成功容器的ID + * @param {string} messageId - 成功消息的ID + * @param {string} message - 成功消息内容 + * @param {string} errorId - 错误消息容器的ID + */ +function showFormSuccess(successId, messageId, message, errorId = '') { + const successContainer = document.getElementById(successId); + const successMessage = document.getElementById(messageId); + const errorContainer = errorId ? document.getElementById(errorId) : null; + + if (!successContainer || !successMessage) return; + + successMessage.textContent = message; + successContainer.classList.remove('hidden'); + + if (errorContainer) { + errorContainer.classList.add('hidden'); + } + + // 滚动到成功信息 + successContainer.scrollIntoView({ behavior: 'smooth', block: 'start' }); +} + +/** + * 发起API请求的通用函数 + * @param {string} url - 请求URL + * @param {string} method - 请求方法 + * @param {object} data - 请求数据 + * @param {object} options - 附加选项 + * @returns {Promise} - 返回Promise对象 + */ +async function apiRequest(url, method = 'GET', data = null, options = {}) { + const defaultOptions = { + headers: { + 'Content-Type': 'application/json' + }, + method, + ...options + }; + + if (data) { + // 根据Content-Type处理数据 + if (defaultOptions.headers['Content-Type'] === 'application/json') { + defaultOptions.body = JSON.stringify(data); + } else if (defaultOptions.headers['Content-Type'] === 'application/x-www-form-urlencoded') { + defaultOptions.body = new URLSearchParams(data); + } + } + + try { + const response = await fetch(url, defaultOptions); + return await response.json(); + } catch (error) { + console.error(`API请求错误 [${url}]:`, error); + throw error; + } +} + +/** + * 重置表单 + * @param {string} formId - 表单ID + */ +function resetForm(formId) { + const form = document.getElementById(formId); + if (form) { + form.reset(); + } +} + +/** + * 填充表单数据 + * @param {string} formId - 表单ID + * @param {object} data - 表单数据对象 + */ +function fillForm(formId, data) { + const form = document.getElementById(formId); + if (!form || !data) return; + + Object.keys(data).forEach(key => { + const element = form.elements[key] || document.getElementById(key); + if (element) { + element.value = data[key] || ''; + } + }); +} + +/** + * 防抖函数 + * @param {Function} func - 要防抖的函数 + * @param {number} delay - 延迟时间(毫秒) + * @returns {Function} - 返回防抖后的函数 + */ +function debounce(func, delay) { + let timeoutId; + return function(...args) { + clearTimeout(timeoutId); + timeoutId = setTimeout(() => func.apply(this, args), delay); + }; +} + +/** + * 节流函数 + * @param {Function} func - 要节流的函数 + * @param {number} limit - 时间限制(毫秒) + * @returns {Function} - 返回节流后的函数 + */ +function throttle(func, limit) { + let inThrottle; + return function(...args) { + if (!inThrottle) { + func.apply(this, args); + inThrottle = true; + setTimeout(() => inThrottle = false, limit); + } + }; +} \ No newline at end of file diff --git a/templates/parameter_config.html b/templates/parameter_config.html new file mode 100644 index 0000000..0123b7b --- /dev/null +++ b/templates/parameter_config.html @@ -0,0 +1,271 @@ + + + + + + 参数配置 - 车主信息查询系统 + + + + + + + + + + + {% include 'header.html' %} + + +
+ + + + +
+
+
+ +
+

参数配置

+

请配置系统参数

+
+ + + {% if error %} +
+ + {{ error }} +
+ {% endif %} + {% if success %} +
+ + {{ success }} +
+ {% endif %} + + + +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+
+ + + + {% include 'footer.html' %} + + \ No newline at end of file diff --git a/templates/query.html b/templates/query.html index e48c269..707c453 100644 --- a/templates/query.html +++ b/templates/query.html @@ -32,6 +32,8 @@ } + + - -
-
-
- -

车主信息查询系统

-
-
- -
-
- 欢迎 {{ session.department }} {{ session.name }} - -
- - -
-
-
-
+ {% include 'header.html' %}
@@ -248,751 +212,223 @@ - -
-
-

© 2025 车主信息查询系统 - 内部使用

-

免责声明:本系统数据仅供内部人员工作参考,请勿外传或用于其他用途。

-
-
+ {% include 'footer.html' %} - + - - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/templates/user_profile.html b/templates/user_profile.html new file mode 100644 index 0000000..30d50c9 --- /dev/null +++ b/templates/user_profile.html @@ -0,0 +1,127 @@ + + + + + + 个人信息 - 车主信息查询系统 + + + + + + + + + + + {% include 'header.html' %} + + +
+ + + + +
+
+
+ +
+

个人信息

+

请查看并更新您的个人信息

+
+ + + {% if error %} +
+ + {{ error }} +
+ {% endif %} + {% if success %} +
+ + {{ success }} +
+ {% endif %} + + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + {% include 'footer.html' %} + + \ No newline at end of file diff --git a/templates/users_management.html b/templates/users_management.html index effeb9e..ecf6aeb 100644 --- a/templates/users_management.html +++ b/templates/users_management.html @@ -32,6 +32,9 @@ } + + + - -
-
-
- -

车主信息查询系统

-
-
- -
-
- 欢迎 {{ session.department }} {{ session.name }} - -
- - -
-
-
-
+ {% include 'header.html' %}
+ + +

用户管理

@@ -197,6 +169,8 @@
+ {% include 'footer.html' %} + - - - - - - - - - + + + \ No newline at end of file diff --git a/user.py b/user.py index f78dc78..54ef1bb 100644 --- a/user.py +++ b/user.py @@ -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)}'}) \ No newline at end of file + 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) \ No newline at end of file