diff --git a/add_user_id_to_query_history.py b/add_user_id_to_query_history.py new file mode 100644 index 0000000..b722209 --- /dev/null +++ b/add_user_id_to_query_history.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +为query_history表添加user_id字段,并设置为users表id字段的外键 +""" + +import sqlite3 +import logging + +# 配置日志 +handlers = [logging.FileHandler('db_update.log'), logging.StreamHandler()] +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s', + handlers=handlers +) +logger = logging.getLogger(__name__) + +# 数据库文件路径 +db_path = 'car_info.db' + + +def main(): + """ + 主函数:连接数据库并为query_history表添加user_id字段 + """ + logger.info("开始为query_history表添加user_id字段") + + try: + # 连接数据库 + conn = sqlite3.connect(db_path) + cursor = conn.cursor() + + # 检查query_history表是否已经存在user_id字段 + cursor.execute("PRAGMA table_info(query_history)") + columns = cursor.fetchall() + + has_user_id = any(column[1] == 'user_id' for column in columns) + + if has_user_id: + logger.info("query_history表已存在user_id字段,无需添加") + else: + # 添加user_id字段(先不添加外键约束,确保字段可以添加成功) + logger.info("开始添加user_id字段") + cursor.execute("ALTER TABLE query_history ADD COLUMN user_id INTEGER") + conn.commit() + logger.info("user_id字段添加成功") + + # 尝试添加外键约束 + try: + logger.info("开始添加外键约束") + cursor.execute(""" + ALTER TABLE query_history + ADD CONSTRAINT fk_query_history_user_id + FOREIGN KEY (user_id) REFERENCES users(id) + """) + conn.commit() + logger.info("外键约束添加成功") + except sqlite3.Error as e: + # 在SQLite中,某些版本不支持通过ALTER TABLE直接添加外键约束 + # 如果添加外键约束失败,记录警告信息并继续 + logger.warning(f"添加外键约束失败: {str(e)}") + logger.warning("将创建临时表并重新创建query_history表来添加外键约束") + + # 创建临时表 + cursor.execute(""" + CREATE TABLE query_history_temp ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + department TEXT NOT NULL, + query_date TEXT NOT NULL, + plate_number TEXT, + phone TEXT, + results_count INTEGER NOT NULL, + query_ip TEXT NOT NULL, + user_id INTEGER, + FOREIGN KEY (user_id) REFERENCES users(id) + ) + """) + + # 复制数据到临时表 + cursor.execute(""" + INSERT INTO query_history_temp ( + id, department, query_date, plate_number, + phone, results_count, query_ip + ) + SELECT + id, department, query_date, plate_number, + phone, results_count, query_ip + FROM query_history + """) + + # 删除原表 + cursor.execute("DROP TABLE query_history") + + # 重命名临时表 + cursor.execute("ALTER TABLE query_history_temp RENAME TO query_history") + + # 提交更改 + conn.commit() + logger.info("通过重新创建表的方式成功添加外键约束") + + # 关闭连接 + conn.close() + logger.info("操作完成") + + except Exception as e: + logger.error(f"操作过程中发生错误: {str(e)}") + if 'conn' in locals() and conn: + conn.rollback() + conn.close() + + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/api.py b/api.py index 5ebbc61..bd1e734 100644 --- a/api.py +++ b/api.py @@ -73,7 +73,7 @@ def get_pending_queries(): # 查询query_history表中results_count=-1的所有数据 cursor.execute(""" - SELECT id, department, query_date, plate_number, phone, results_count, query_ip + SELECT id, query_date, plate_number, phone, results_count, query_ip, user_id FROM query_history WHERE results_count = -1 ORDER BY query_date DESC @@ -90,12 +90,12 @@ def get_pending_queries(): for row in rows: pending_query = { 'id': row['id'], - 'department': row['department'], 'query_date': row['query_date'], 'plate_number': row['plate_number'], 'phone': row['phone'], 'results_count': row['results_count'], - 'query_ip': row['query_ip'] + 'query_ip': row['query_ip'], + 'user_id': row['user_id'] if 'user_id' in row.keys() else None } pending_queries.append(pending_query) diff --git a/app.py b/app.py index 830b192..ebd60ed 100644 --- a/app.py +++ b/app.py @@ -1,7 +1,6 @@ from flask import Flask, render_template, request, redirect, url_for, session, jsonify from datetime import datetime, timedelta import os -import random from flask import Flask, render_template, request, redirect, url_for, session # 导入用户模块 @@ -58,87 +57,6 @@ def init_db(): ) ''') - # 插入一些测试车辆数据 - try: - test_cars = [ - ('京A12345', '13800138001', '110101199001011234', '张三', 'zhangsan@example.com', '北京市朝阳区'), - ('沪B54321', '13900139001', '310101199001012345', '李四', 'lisi@example.com', '上海市静安区'), - ('粤C67890', '13700137001', '440401199001013456', '王五', 'wangwu@example.com', '广东省珠海市'), - ('苏D12345', '13600136001', '320401199001014567', '赵六', 'zhaoliu@example.com', '江苏省常州市'), - ('浙E54321', '13500135001', '330501199001015678', '钱七', 'qianqi@example.com', '浙江省湖州市') - ] - cursor.executemany("INSERT INTO car_owners (plate_number, phone, id_card, name, email, address) VALUES (?, ?, ?, ?, ?, ?)", test_cars) - except Exception as e: - # 数据已存在或其他错误,忽略 - print(f"插入测试数据时出错: {e}") - - # 单独处理查询历史演示数据,确保每次都能插入20条记录 - try: - # 先删除现有的演示数据 - cursor.execute("DELETE FROM query_history WHERE department IN ('IT部', '财务部', '人事部', '市场部', '行政部')") - - # 生成最近20天的随机查询历史 - provinces = ['京', '沪', '粤', '苏', '浙', '鲁', '豫', '川', '湘', '鄂'] - cities = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K'] - departments = ['IT部', '财务部', '人事部', '市场部', '行政部'] - - # 获取现有的车辆信息,用于生成能匹配的查询历史 - cursor.execute("SELECT plate_number, phone FROM car_owners") - existing_cars = cursor.fetchall() - - for i in range(20): - # 生成随机日期(最近20天内) - days_ago = random.randint(0, 19) - date = (datetime.now() - timedelta(days=days_ago)).strftime('%Y-%m-%d %H:%M:%S') - - # 70%的概率使用已存在的车辆信息,30%的概率生成随机信息 - use_existing = random.random() < 0.7 - - if use_existing and existing_cars: - # 使用已存在的车辆信息 - car_info = random.choice(existing_cars) - if random.choice([True, False]): - plate_number = car_info[0] - phone = None - else: - plate_number = None - phone = car_info[1] - # 确保结果数量正确 - if plate_number: - cursor.execute("SELECT COUNT(*) FROM car_owners WHERE plate_number = ?", (plate_number,)) - results_count = cursor.fetchone()[0] - else: - cursor.execute("SELECT COUNT(*) FROM car_owners WHERE phone = ?", (phone,)) - results_count = cursor.fetchone()[0] - else: - # 随机生成车牌号或手机号 - use_plate = random.choice([True, False]) - if use_plate: - plate_number = f"{random.choice(provinces)}{random.choice(cities)}{random.randint(100000, 999999)}" - phone = None - else: - plate_number = None - phone = f"1{random.randint(3000000000, 9999999999)}" - # 检查是否存在匹配结果 - if plate_number: - cursor.execute("SELECT COUNT(*) FROM car_owners WHERE plate_number = ?", (plate_number,)) - results_count = cursor.fetchone()[0] - else: - cursor.execute("SELECT COUNT(*) FROM car_owners WHERE phone = ?", (phone,)) - results_count = cursor.fetchone()[0] - - # 随机部门 - department = random.choice(departments) - - # 生成随机IP地址 - query_ip = f"192.168.{random.randint(0, 255)}.{random.randint(1, 254)}" - - cursor.execute( - "INSERT INTO query_history (department, query_date, plate_number, phone, results_count, query_ip) VALUES (?, ?, ?, ?, ?, ?)", - (department, date, plate_number, phone, results_count, query_ip) - ) - except Exception as e: - print(f"插入查询历史数据时出错: {e}") try: conn.commit() except Exception as e: @@ -184,15 +102,16 @@ def query(): # 获取客户端IP地址 query_ip = request.remote_addr - # 从用户信息表获取部门信息 + # 从用户信息表获取用户ID + user_id = None try: # 可以复用同一个连接,不需要创建新连接 - cursor.execute("SELECT department FROM users WHERE username = ?", (session['username'],)) - user_dept = cursor.fetchone() - if user_dept: - department = user_dept[0] + cursor.execute("SELECT id FROM users WHERE username = ?", (session['username'],)) + user_info = cursor.fetchone() + if user_info: + user_id = user_info[0] except Exception as e: - print(f"获取部门信息时出错: {e}") + print(f"获取用户信息时出错: {e}") # 记录查询历史到数据库 try: @@ -207,8 +126,8 @@ def query(): results_count = len(results) cursor.execute( - "INSERT INTO query_history (department, query_date, plate_number, phone, results_count, query_ip) VALUES (?, ?, ?, ?, ?, ?)", - (department, query_date, plate_number if plate_number else None, phone if phone else None, results_count, query_ip) + "INSERT INTO query_history (query_date, plate_number, phone, results_count, query_ip, user_id) VALUES (?, ?, ?, ?, ?, ?)", + (query_date, plate_number if plate_number else None, phone if phone else None, results_count, query_ip, user_id) ) conn.commit() except Exception as e: @@ -300,7 +219,14 @@ def get_recent_queries(): cursor = conn.cursor() try: - cursor.execute("SELECT id, department, query_date, plate_number, phone, results_count, query_ip FROM query_history ORDER BY query_date DESC LIMIT 20") + # 使用JOIN操作获取用户姓名和部门信息 + cursor.execute(""" + SELECT qh.id, qh.query_date, qh.plate_number, qh.phone, qh.results_count, qh.query_ip, qh.user_id, + u.name AS user_name, u.department AS user_department + FROM query_history qh + LEFT JOIN users u ON qh.user_id = u.id + ORDER BY qh.query_date DESC LIMIT 20 + """) recent_queries = cursor.fetchall() # 格式化查询历史数据 @@ -308,12 +234,14 @@ def get_recent_queries(): for q in recent_queries: formatted_recent_queries.append({ 'id': q[0], - 'department': q[1], - 'query_date': q[2], - 'plate_number': q[3] if q[3] else '未提供', - 'phone': q[4] if q[4] else '未提供', - 'results_count': q[5], - 'query_ip': q[6] + 'query_date': q[1], + 'plate_number': q[2] if q[2] else '未提供', + 'phone': q[3] if q[3] else '未提供', + 'results_count': q[4], + 'query_ip': q[5], + 'user_id': q[6] if len(q) > 6 else None, + 'user_name': q[7] if len(q) > 7 else '未知', + 'user_department': q[8] if len(q) > 8 else '未知' }) return formatted_recent_queries @@ -340,7 +268,7 @@ if __name__ == '__main__': try: init_db() - app.run(debug=True) + app.run(debug=True,host="0.0.0.0",port=99) finally: # 确保在程序退出时关闭数据库连接 close_global_connection() \ No newline at end of file diff --git a/car_info.db b/car_info.db index 280554f..b2de3dc 100644 Binary files a/car_info.db and b/car_info.db differ diff --git a/ewcc2.py b/ewcc2.py new file mode 100644 index 0000000..b3eb4ab --- /dev/null +++ b/ewcc2.py @@ -0,0 +1,252 @@ +from DrissionPage._base.chromium import Chromium +from DrissionPage._configs.chromium_options import ChromiumOptions +from DrissionPage._pages.mix_tab import MixTab +from cssselect.parser import parse_simple_selector +from config import ConfigManager # 新增导入 +import time + +class Sinopec_ewcc(object): + tab:MixTab + # browser:Chromium + + def __init__(self): + self.url = 'https://ewcc.sinopec.com' + self.url_info= 'ewcc.sinopec' + self.browser_path= r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe' + self.co = ChromiumOptions().set_browser_path(self.browser_path) + self.co.ignore_certificate_errors(True) + self.browser=Chromium(self.co) + self.config_manager = ConfigManager() # 新增配置管理器实例 + self.ewcc_config = self.config_manager.app_config.get('ewcc', {}) # 修改为通过类访问 + + def quit(self ): + self.browser.quit() + + def load_cookies(self): + cookies = self.ewcc_config.get('cookies', {}) + print('使用保存的cookies登录') + for cookie in cookies: + self.browser.set.cookies(cookie) + ### print(cookie) + + def save_cookies(self): + # 保存当前 cookie + self.tab.refresh() + cookies = self.tab.cookies() + ### print(cookies) + self.ewcc_config['cookies'] = cookies + self.ewcc_config['savetime'] = time.time() + print("--------------------") + self.config_manager.app_config['ewcc'] = self.ewcc_config # 修改为通过类访问 + self.config_manager.save_config() # 修改为调用类方法 + + + def test(self ): + # print(self.browser as Chromium.version ) + pass + + def open_web(self,url=None): + if url is None: + url=self.url + self.browser.get_tab(url) + + def new_tab(self,url=None): + if url is None: + url=self.url + self.tab=self.browser.new_tab(url) + + + def find_tab(self,url=None,title=None): + if url is None: + url=self.url + if title is None: + title=self.url_info + + try: + self.tab= self.browser.get_tab(url=url) + print("根据 url 找到标签") + except: + print("根据 url 没有找到标签") + self.tab=None + + if not self.tab: + try: + self.tab=self.browser.get_tab(title=title) + print("根据 标题名 找到 标签") + except : + print("根据 标题名 没有找到标签") + self.tab=None + + return self.tab + + def is_login(self): + if self.tab is None: + return False + time.sleep(2) + cur_login=False + try: + e=None + e=self.tab.ele("#userName") + print("找到登录成功的标志"+e.text) + cur_login=True + except Exception as e: + print('没有找到登录成功的标志') + print(f'{e}') + cur_login = False + return cur_login + + + # 判断是否登录 ,如果没有登录 ,则提示十次,间断5秒 + i = 1 + time.sleep(2) + while i <= 10: + cur_login = False + try: + e = None + e = self.tab.ele('@@tag()=span@@text()^忘记密码') + ### print(e.value) + print(f'需要登录 <{i}> :') + time.sleep(5) + except Exception as e: + print('已经登录') + print(f'{e}') + cur_login = True + + if cur_login: + break + i += 1 + if not cur_login: + print('登录 失败,强制退出。') + return cur_login + + def login(self,username=None,userpass=None,otp=None): + self.tab.get(self.url) + self.tab.wait.eles_loaded('xpath://*[@id="authen1Form"]/button') + time.sleep(5) + + try: + ele_div=self.tab.ele('#tab3Con') + ele_div.ele('#fs3_username').set.value(self.ewcc_config.get('username','pengf332.hnsy')) + time.sleep(1) + ele_div.ele('#fs3_password').set.value(self.ewcc_config.get('password','Pf7842158c')) + time.sleep(1) + ele_div.ele('#fs3_otpOrSms').set.value(otp) + time.sleep(1) + ele_div.ele('@type=submit').click() + except Exception as e: + print(e) + time.sleep(3) + + ### 判断是否有仍然发生的界面 + try: + ele_process = self.tab.ele('#proceed-button') + ele_process.click() + + except Exception as e: + print(e) + + time.sleep(3) + return True + + + def show_login(self): + self.tab.get(self.url) + self.tab.wait.eles_loaded('xpath://*[@id="authen1Form"]/button') + time.sleep(3) + + try: + ele_div=self.tab.ele('#tab3Con') + ele_div.ele('#fs3_username').set.value(self.ewcc_config.get('username','pengf332.hnsy')) + ele_div.ele('#fs3_password').set.value(self.ewcc_config.get('password','Pf7842158b')) + ele_div.ele('#fs3_otpOrSms').set.value(self.ewcc_config.get('otpOrSms','129727')) + # ele_div.ele('@type=submit').click() + except Exception as e: + print(e) + + time.sleep(60) + return True + + + def send_message(self): + pass + + def query_car_info(self,plate_number=None,phone_number=None,additional_info=None): + self.tab.ele("@@tag()=li@@title=订单中心").click() + time.sleep(2) + self.tab.ele("@@tag()=a@@name=客户信息查询").click() + time.sleep(2) + myframe = self.tab.get_frame("iframeSOC_CSR_DETAIL") + ### print(myframe.inner_html) + time.sleep(2) + + ### print("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + ele = myframe.ele("#searchType") + ### print(ele.inner_html) + + myframe.ele("@@tag()=select@@id=searchType").select.by_text("车牌号") + myframe.ele('#searchValue').input(plate_number, clear=True) + + myframe.listen.start('acc/getAccCsrInfo') + myframe.ele("@text()=查询").click() + DataPacket = myframe.listen.wait() + ### print(DataPacket.response.body) + + ###print("ccccccccccccccccccccccccccccccccccccccc") + rtn={} + if DataPacket.response.body['success']: + total_num = DataPacket.response.body['data']['total'] + # rtn['length']=total_num + # rtn['test']='aaa' + rtn=[] + eles = myframe.eles("@@name=客户信息详情界面@@text()=详情") + for ele in eles: + sele = self.tab.ele("@@text()^客户信息查询@@class:J_menuTab") + if sele: + sele.click() + self.tab.listen.start('getAccCsrInfoByCsrid') + ele.click() + DataPacket = self.tab.listen.wait() + ### print(DataPacket.response.body) + rtn.append(DataPacket.response.body['data']) + self.tab.listen.stop() + ### print(ele.inner_html) + + return rtn + +if __name__ == "__main__": + ewcc = Sinopec_ewcc() + + # 1 查找现有的标签 + print('<1> 查找 现有的标签') + ewcc.find_tab() # 新增:查找标签页 + + # 2 如果没有登录 ,则使用cookie登录 + if not ewcc.is_login(): + print('<2> 找不到对应的网站,使用cookies尝试登录') + ewcc.load_cookies() + ewcc.new_tab() + + # 3 判断是否登录,如果登录不成功,则使用帐号和密码登录 + if not ewcc.is_login(): + print('<3> 找不对应的网站,使用帐号密码登录') + # 这里要注意12小时才可以登录一次。 + # 这里显示登录界面,并等待输入一分钟 + ewcc.show_login() + + # 4 判断是否登录 ,如果失败,则发送信息到微信上 + if ewcc.is_login(): + ewcc.tab.refresh() + ewcc.save_cookies() + print(" 保存cookies") + else: + ewcc.send_message() + + # ewcc.query_car_info() + + ewcc.quit() + + + + + + diff --git a/query_processor.py b/query_processor.py new file mode 100644 index 0000000..eceadcd --- /dev/null +++ b/query_processor.py @@ -0,0 +1,163 @@ +import requests +import time +import logging + +# 配置日志 +handlers = [logging.FileHandler('query_processor.log'), logging.StreamHandler()] +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s', + handlers=handlers +) +logger = logging.getLogger(__name__) + +# API基础URL +BASE_URL = 'http://localhost:99' + +# 演示数据处理函数 +def process_query_data(query_data, parameters): + """ + 处理查询数据的演示函数 + 这里使用演示代码代替实际的数据处理逻辑 + """ + # 获取用户ID,如果存在 + user_id = query_data.get('user_id', '未知') + logger.info(f"处理查询数据: ID={query_data['id']}, 车牌号={query_data['plate_number']}, 用户ID={user_id}") + + # 这里是演示处理逻辑 + # 在实际应用中,这里应该是真实的数据处理代码 + logger.info(f"使用参数进行处理: {parameters}") + + # 模拟处理过程 + time.sleep(2) # 模拟处理耗时 + + # 返回模拟的处理结果(简单地将results_count设置为随机数1-5) + # 实际应用中,应该根据真实处理结果返回相应的值 + results_count = 3 # 演示用的固定结果数 + logger.info(f"处理完成,结果数量: {results_count}") + + return results_count + +# 读取参数配置 +def get_parameters(): + """ + 从后端API读取参数配置 + """ + try: + url = f'{BASE_URL}/api/parameters' + response = requests.get(url) + response.raise_for_status() + data = response.json() + + if data['success']: + logger.info(f"成功获取参数配置: {data['data']}") + return data['data'] + else: + logger.error(f"获取参数配置失败: {data['error']}") + return None + except Exception as e: + logger.error(f"获取参数配置时发生错误: {str(e)}") + return None + +# 获取待处理查询 +def get_pending_queries(): + """ + 从后端API获取待处理查询 + """ + try: + url = f'{BASE_URL}/api/pending-queries' + response = requests.get(url) + response.raise_for_status() + data = response.json() + + if data['success']: + logger.info(f"成功获取待处理查询,共 {data['count']} 条") + return data['data'] + else: + logger.error(f"获取待处理查询失败: {data['error']}") + return [] + except Exception as e: + logger.error(f"获取待处理查询时发生错误: {str(e)}") + return [] + +# 更新查询结果 +def update_query_result(query_id, results_count): + """ + 更新查询结果到后端API + """ + try: + url = f'{BASE_URL}/api/update-query-result' + data = { + 'id': query_id, + 'results_count': results_count + } + + response = requests.post(url, json=data) + response.raise_for_status() + result = response.json() + + if result['success']: + logger.info(f"成功更新查询结果: ID={query_id}, 结果数量={results_count}") + return True + else: + logger.error(f"更新查询结果失败: {result['error']}") + return False + except Exception as e: + logger.error(f"更新查询结果时发生错误: {str(e)}") + return False + +# 主处理函数 +def main(): + logger.info("查询处理代码启动") + + # 获取参数配置 + parameters = get_parameters() + if not parameters: + logger.warning("无法获取参数配置,使用默认参数继续") + # 使用默认参数继续 + parameters = { + 'param1': 'default1', + 'param2': 'default2', + 'param3': 'default3', + 'param4': 'default4', + 'param5': 'default5' + } + + # 主循环 + while True: + try: + # 获取待处理查询 + pending_queries = get_pending_queries() + + # 处理每条查询 + for query in pending_queries: + # 处理查询数据 + results_count = process_query_data(query, parameters) + + # 更新查询结果 + update_query_result(query['id'], results_count) + + # 等待一段时间后再次检查 + wait_time = 60 # 默认等待60秒 + # 如果有parameters参数,可以根据参数调整等待时间 + if parameters and 'polling_interval' in parameters: + try: + wait_time = int(parameters['polling_interval']) + except (ValueError, TypeError): + logger.warning(f"无效的轮询间隔参数: {parameters['polling_interval']}") + + logger.info(f"本次处理完成,等待 {wait_time} 秒后再次检查") + time.sleep(wait_time) + + except KeyboardInterrupt: + logger.info("查询处理器被用户中断") + break + except Exception as e: + logger.error(f"处理过程中发生错误: {str(e)}") + # 发生错误时,等待更短的时间后重试 + time.sleep(30) + + logger.info("查询处理器停止") + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/remove_department_from_query_history.py b/remove_department_from_query_history.py new file mode 100644 index 0000000..ba29b39 --- /dev/null +++ b/remove_department_from_query_history.py @@ -0,0 +1,69 @@ +import sqlite3 +from db_utils import get_db_connection, close_db_connection + + +def remove_department_from_query_history(): + """ + 从query_history表中删除department字段 + SQLite不支持直接删除列,采用以下步骤: + 1. 创建一个不包含department字段的新表 + 2. 将原始表中的数据(除department外)复制到新表 + 3. 删除原始表 + 4. 重命名新表为原始表名 + 5. 重新创建索引和外键约束 + """ + conn = None + try: + # 获取数据库连接 + conn = get_db_connection() + cursor = conn.cursor() + + print("开始从query_history表中删除department字段...") + + # 1. 创建临时表,不包含department字段 + print("1. 创建临时表query_history_new...") + cursor.execute(''' + CREATE TABLE IF NOT EXISTS query_history_new ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + query_date TEXT NOT NULL, + plate_number TEXT, + phone TEXT, + results_count INTEGER NOT NULL, + query_ip TEXT NOT NULL, + user_id INTEGER, + FOREIGN KEY (user_id) REFERENCES users (id) + ) + ''') + + # 2. 复制数据到新表,排除department字段 + print("2. 复制数据到新表,排除department字段...") + cursor.execute(''' + INSERT INTO query_history_new (id, query_date, plate_number, phone, results_count, query_ip, user_id) + SELECT id, query_date, plate_number, phone, results_count, query_ip, user_id + FROM query_history + ''') + + # 3. 删除原表 + print("3. 删除原始表query_history...") + cursor.execute('DROP TABLE IF EXISTS query_history') + + # 4. 重命名新表为原表名 + print("4. 重命名新表为query_history...") + cursor.execute('ALTER TABLE query_history_new RENAME TO query_history') + + # 5. 提交事务 + conn.commit() + print("操作完成:department字段已成功从query_history表中删除!") + + except sqlite3.Error as e: + print(f"数据库操作出错:{e}") + if conn: + conn.rollback() + raise + finally: + if conn: + close_db_connection(conn) + + +if __name__ == "__main__": + remove_department_from_query_history() \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..b1676e1 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +# Flask应用依赖 +flask + +# 查询处理器依赖 +requests \ No newline at end of file diff --git a/run.ps1 b/run.ps1 deleted file mode 100644 index f5d7870..0000000 --- a/run.ps1 +++ /dev/null @@ -1,15 +0,0 @@ -# 设置执行策略以允许运行脚本(仅在首次运行时需要取消注释) -# Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process - -# 激活虚拟环境 -& '.\venv\Scripts\Activate.ps1' - -# 设置Flask应用程序环境变量 -$env:FLASK_APP = "app.py" -$env:FLASK_ENV = "development" - -# 启动Flask服务器,允许外部访问(使用python -m flask确保命令可用) -python -m flask run --host=0.0.0.0 - -# 保持窗口打开 -Read-Host "Press Enter to exit" \ No newline at end of file diff --git a/start_server.py b/start_server.py deleted file mode 100644 index f72275e..0000000 --- a/start_server.py +++ /dev/null @@ -1,14 +0,0 @@ -import os -import subprocess - -# 设置Flask应用程序环境变量 -os.environ['FLASK_APP'] = 'app.py' -os.environ['FLASK_ENV'] = 'development' - -print("Starting Flask server...") -print("Server will be available at http://localhost:5000/") -print("To allow external access, it's listening on all interfaces (0.0.0.0)") -print("Press Ctrl+C to stop the server") - -# 启动Flask服务器,允许外部访问 -subprocess.run(['python', '-m', 'flask', 'run', '--host=0.0.0.0']) \ No newline at end of file diff --git a/templates/query.html b/templates/query.html index cc2d26f..5db38a6 100644 --- a/templates/query.html +++ b/templates/query.html @@ -91,6 +91,7 @@
${data.error}
+暂无车辆信息
+该查询条件下未找到相关车辆信息
+加载详情时发生错误
+请稍后重试
+