diff --git a/mvcar/backend/app.py b/mvcar/backend/app.py index cee2dfb..0f58f92 100644 --- a/mvcar/backend/app.py +++ b/mvcar/backend/app.py @@ -1,3 +1,6 @@ +# backend/app.py +import logging +from logging.handlers import RotatingFileHandler from flask import Flask, jsonify, request from flask_cors import CORS import sqlite3 @@ -7,9 +10,34 @@ import os basedir = os.path.abspath(os.path.dirname(__file__)) db_path = os.path.join(basedir, '..', 'data', 'cars.db') +# 创建 logs 目录 +logs_dir = os.path.join(basedir, '..', 'logs') +os.makedirs(logs_dir, exist_ok=True) + +# 配置日志 +log_formatter = logging.Formatter( + '%(asctime)s %(levelname)s %(name)s %(message)s' +) +log_file = os.path.join(logs_dir, 'app.log') + +# 创建 rotating file handler (最大5MB,保留5个备份) +file_handler = RotatingFileHandler( + log_file, + maxBytes=5*1024*1024, # 5MB + backupCount=5 +) +file_handler.setFormatter(log_formatter) +file_handler.setLevel(logging.INFO) + +# 创建 logger app = Flask(__name__) +app.logger.addHandler(file_handler) +app.logger.setLevel(logging.INFO) + +# 添加 CORS 支持 CORS(app) +# 数据库连接函数 def get_db_connection(): conn = sqlite3.connect(db_path) conn.row_factory = sqlite3.Row @@ -17,37 +45,65 @@ def get_db_connection(): @app.route('/api/cars', methods=['GET']) def get_all_cars(): - conn = get_db_connection() - cars = conn.execute('SELECT * FROM cars').fetchall() - conn.close() - - cars_list = [dict(car) for car in cars] - return jsonify(cars_list) + app.logger.info('获取所有车辆信息') + try: + conn = get_db_connection() + cars = conn.execute('SELECT * FROM cars').fetchall() + conn.close() + + cars_list = [dict(car) for car in cars] + app.logger.info(f'成功获取 {len(cars_list)} 条车辆记录') + return jsonify(cars_list) + except Exception as e: + app.logger.error(f'获取所有车辆信息时出错: {str(e)}') + return jsonify({'error': '服务器内部错误'}), 500 @app.route('/api/cars/search', methods=['GET']) def search_car(): plate = request.args.get('plate', '') + app.logger.info(f'搜索车牌号码: {plate}') if not plate: + app.logger.warning('用户未提供车牌号码') return jsonify({'error': '请输入车牌号码'}), 400 - conn = get_db_connection() - cars = conn.execute('SELECT * FROM cars WHERE plate LIKE ?', (f'%{plate}%',)).fetchall() - conn.close() - - cars_list = [dict(car) for car in cars] - return jsonify(cars_list) + try: + conn = get_db_connection() + cars = conn.execute('SELECT * FROM cars WHERE plate LIKE ?', (f'%{plate}%',)).fetchall() + conn.close() + + cars_list = [dict(car) for car in cars] + app.logger.info(f'搜索 "{plate}" 返回 {len(cars_list)} 条结果') + return jsonify(cars_list) + except Exception as e: + app.logger.error(f'搜索车牌号码时出错: {str(e)}') + return jsonify({'error': '服务器内部错误'}), 500 @app.route('/api/cars/', methods=['GET']) def get_car_by_plate(plate): - conn = get_db_connection() - car = conn.execute('SELECT * FROM cars WHERE plate = ?', (plate,)).fetchone() - conn.close() + app.logger.info(f'查询特定车牌号码: {plate}') - if car is None: - return jsonify({'error': '未找到该车牌号码对应的车主信息'}), 404 - - return jsonify(dict(car)) + try: + conn = get_db_connection() + car = conn.execute('SELECT * FROM cars WHERE plate = ?', (plate,)).fetchone() + conn.close() + + if car is None: + app.logger.warning(f'未找到车牌号码: {plate}') + return jsonify({'error': '未找到该车牌号码对应的车主信息'}), 404 + + app.logger.info(f'成功找到车牌号码: {plate}') + return jsonify(dict(car)) + except Exception as e: + app.logger.error(f'查询特定车牌时出错: {str(e)}') + return jsonify({'error': '服务器内部错误'}), 500 + +# 添加一个根路径用于健康检查 +@app.route('/', methods=['GET']) +def health_check(): + app.logger.info('健康检查请求') + return jsonify({'status': 'ok', 'message': '服务正常运行'}) if __name__ == '__main__': + app.logger.info('启动 Flask 应用') app.run(debug=True, host='0.0.0.0', port=5000) \ No newline at end of file diff --git a/mvcar/backend/requirements.txt b/mvcar/backend/requirements.txt index ef25c27..554e1b6 100644 --- a/mvcar/backend/requirements.txt +++ b/mvcar/backend/requirements.txt @@ -1,2 +1,3 @@ +# backend/requirements.txt Flask==2.3.2 flask-cors==4.0.0 \ No newline at end of file diff --git a/mvcar/backend/view_logs.py b/mvcar/backend/view_logs.py new file mode 100644 index 0000000..a5a4b4f --- /dev/null +++ b/mvcar/backend/view_logs.py @@ -0,0 +1,24 @@ +# backend/view_logs.py +import os + +# 获取当前文件所在目录 +basedir = os.path.abspath(os.path.dirname(__file__)) +log_file = os.path.join(basedir, '..', 'logs', 'app.log') + +def view_logs(lines=20): + """查看最新的日志条目""" + try: + with open(log_file, 'r', encoding='utf-8') as f: + all_lines = f.readlines() + # 获取最后几行 + latest_lines = all_lines[-lines:] if len(all_lines) > lines else all_lines + print(f"最新 {len(latest_lines)} 条日志:") + for line in latest_lines: + print(line.strip()) + except FileNotFoundError: + print("日志文件不存在,请先运行应用程序") + except Exception as e: + print(f"读取日志文件时出错: {e}") + +if __name__ == '__main__': + view_logs() \ No newline at end of file diff --git a/mvcar/frontend/js/result.js b/mvcar/frontend/js/result.js index 9066dcc..4cfbe8a 100644 --- a/mvcar/frontend/js/result.js +++ b/mvcar/frontend/js/result.js @@ -1,4 +1,7 @@ +// frontend/js/result.js document.addEventListener('DOMContentLoaded', function() { + console.log('页面加载完成 - 挪车电话结果页面'); + const phoneNumberElement = document.getElementById('phoneNumber'); const plateNumberElement = document.getElementById('plateNumber'); const carBrandElement = document.getElementById('carBrand'); @@ -6,9 +9,11 @@ document.addEventListener('DOMContentLoaded', function() { // 从 sessionStorage 获取车辆信息 const carInfoJson = sessionStorage.getItem('carInfo'); + console.log('从 sessionStorage 获取车辆信息'); if (carInfoJson) { const carInfo = JSON.parse(carInfoJson); + console.log(`车辆信息: ${JSON.stringify(carInfo)}`); // 显示车辆信息 phoneNumberElement.textContent = carInfo.phone; @@ -17,7 +22,9 @@ document.addEventListener('DOMContentLoaded', function() { // 设置拨号链接 callButton.href = 'tel:' + carInfo.phone.replace(/-/g, ''); + console.log(`设置拨号链接: ${callButton.href}`); } else { + console.warn('未找到车辆信息,重定向到搜索页面'); // 如果没有车辆信息,返回搜索页面 window.location.href = 'index.html'; } diff --git a/mvcar/frontend/js/script.js b/mvcar/frontend/js/script.js index 450cd95..6ae4b22 100644 --- a/mvcar/frontend/js/script.js +++ b/mvcar/frontend/js/script.js @@ -1,17 +1,22 @@ +// frontend/js/script.js document.addEventListener('DOMContentLoaded', function() { const searchButton = document.getElementById('searchButton'); const licensePlateInput = document.getElementById('licensePlate'); const errorMessage = document.getElementById('errorMessage'); + console.log('页面加载完成 - 挪车电话查询页面'); + // 添加搜索频率限制 let lastSearchTime = 0; const SEARCH_DELAY = 1000; // 1秒内只能搜索一次 searchButton.addEventListener('click', function() { const plate = licensePlateInput.value.trim(); + console.log(`用户尝试搜索车牌号码: ${plate}`); // 检查输入长度 if (plate.length < 3) { + console.warn('输入字符少于3个'); showError('请输入至少3个字符进行搜索'); return; } @@ -19,33 +24,41 @@ document.addEventListener('DOMContentLoaded', function() { // 检查搜索频率 const currentTime = new Date().getTime(); if (currentTime - lastSearchTime < SEARCH_DELAY) { + console.warn('搜索过于频繁'); showError('搜索过于频繁,请稍后再试'); return; } lastSearchTime = currentTime; if (!plate) { + console.warn('未输入车牌号码'); showError('请输入车牌号码'); return; } // 从后端API获取数据 + console.log(`发送请求到: http://localhost:5000/api/cars/search?plate=${encodeURIComponent(plate)}`); fetch(`http://localhost:5000/api/cars/search?plate=${encodeURIComponent(plate)}`) .then(response => { + console.log(`收到响应状态: ${response.status}`); if (!response.ok) { throw new Error('网络响应错误'); } return response.json(); }) .then(data => { + console.log(`收到数据,共 ${data.length} 条记录`); if (data.length > 0) { // 取第一个匹配的结果 const carInfo = data[0]; + console.log(`找到车辆信息: ${JSON.stringify(carInfo)}`); // 将车辆信息存储到 sessionStorage sessionStorage.setItem('carInfo', JSON.stringify(carInfo)); + console.log('跳转到结果页面'); // 跳转到结果页面 window.location.href = 'result.html'; } else { + console.warn('未找到匹配的车辆信息'); showError('没有找到该车牌号码对应的车主信息'); } }) @@ -58,16 +71,19 @@ document.addEventListener('DOMContentLoaded', function() { // 回车键触发搜索 licensePlateInput.addEventListener('keypress', function(e) { if (e.key === 'Enter') { + console.log('用户按下回车键触发搜索'); searchButton.click(); } }); function showError(message) { + console.log(`显示错误信息: ${message}`); errorMessage.textContent = message; errorMessage.style.display = 'block'; // 3秒后隐藏错误信息 setTimeout(() => { + console.log('隐藏错误信息'); errorMessage.style.display = 'none'; }, 3000); }