diff --git a/api.py b/api.py new file mode 100644 index 0000000..0cdd625 --- /dev/null +++ b/api.py @@ -0,0 +1,75 @@ +from flask import Flask, jsonify +import sqlite3 +from datetime import datetime + +# 创建Flask蓝图 +api_bp = Flask(__name__) + +# 连接数据库的辅助函数 +def get_db_connection(): + conn = sqlite3.connect('car_info.db') + conn.row_factory = sqlite3.Row # 使返回的数据可以通过列名访问 + return conn + +# API函数1: 返回所有的参数信息 +@api_bp.route('/api/parameters', methods=['GET']) +def get_all_parameters(): + try: + # 连接数据库 + conn = get_db_connection() + cursor = conn.cursor() + + # 查询所有参数配置记录 + cursor.execute(""" + SELECT id, param1, param2, param3, param4, param5, update_time + FROM parameter_config + ORDER BY update_time DESC + """) + + # 获取所有查询结果 + rows = cursor.fetchall() + + # 关闭数据库连接 + conn.close() + + # 如果没有查询到数据 + if not rows: + return jsonify({ + 'success': False, + 'error': '未找到参数配置记录', + 'data': [] + }), 404 + + # 格式化查询结果 + parameters_list = [] + for row in rows: + parameters_list.append({ + 'id': row['id'], + 'param1': row['param1'], + 'param2': row['param2'], + 'param3': row['param3'], + 'param4': row['param4'], + 'param5': row['param5'], + 'update_time': row['update_time'] + }) + + # 返回JSON格式的参数信息 + return jsonify({ + 'success': True, + 'message': '参数信息获取成功', + 'data': parameters_list, + 'total': len(parameters_list) + }), 200 + + except Exception as e: + # 处理异常情况 + return jsonify({ + 'success': False, + 'error': f'获取参数信息失败: {str(e)}', + 'data': [] + }), 500 + +# 如果直接运行此文件(用于测试) +if __name__ == '__main__': + # 在生产环境中不应使用debug=True + api_bp.run(debug=True) \ No newline at end of file diff --git a/app.py b/app.py index 98d25ba..1592485 100644 --- a/app.py +++ b/app.py @@ -6,12 +6,16 @@ import random # 导入用户模块 from user import bp as user_bp, init_user_db +# 导入API模块 +from api import api_bp app = Flask(__name__) app.secret_key = 'your_secret_key' # 生产环境中应该使用更安全的密钥 # 注册用户蓝图 app.register_blueprint(user_bp) +# 注册API蓝图 +app.register_blueprint(api_bp) # 确保模板文件夹存在 templates_dir = os.path.join(os.path.dirname(__file__), 'templates') diff --git a/car_info.db b/car_info.db index f682b69..69db6b2 100644 Binary files a/car_info.db and b/car_info.db differ diff --git a/static/js/utils.js b/static/js/utils.js new file mode 100644 index 0000000..efee893 --- /dev/null +++ b/static/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