完善查询逻辑

This commit is contained in:
2025-07-31 22:28:51 +08:00
parent 7d0c1a5896
commit a55d8f0921
3 changed files with 960 additions and 295 deletions

238
app.py
View File

@@ -73,12 +73,12 @@ def ensure_database():
try:
conn = sqlite3.connect(DATABASE_PATH)
cursor = conn.cursor()
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='config_groups'")
result = cursor.fetchone()
conn.close()
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name IN ('config_groups', 'query_history')")
results = cursor.fetchall()
existing_tables = [row[0] for row in results]
if not result:
logger.info("config_groups表不存在,正在创建...")
if 'config_groups' not in existing_tables or 'query_history' not in existing_tables:
logger.info("数据库表不完整,正在重新创建...")
return init_database()
return True
@@ -417,6 +417,141 @@ def delete_config_group(group_id):
finally:
conn.close()
def save_query_history(name, description, pro_config, test_config, query_config, query_keys,
results_summary, execution_time, total_keys, differences_count, identical_count):
"""保存查询历史记录"""
if not ensure_database():
logger.error("数据库初始化失败")
return False
conn = get_db_connection()
cursor = conn.cursor()
try:
cursor.execute('''
INSERT INTO query_history
(name, description, pro_config, test_config, query_config, query_keys,
results_summary, execution_time, total_keys, differences_count, identical_count)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
''', (
name, description,
json.dumps(pro_config),
json.dumps(test_config),
json.dumps(query_config),
json.dumps(query_keys),
json.dumps(results_summary),
execution_time,
total_keys,
differences_count,
identical_count
))
conn.commit()
logger.info(f"查询历史记录 '{name}' 保存成功")
return True
except Exception as e:
logger.error(f"保存查询历史记录失败: {e}")
return False
finally:
conn.close()
def get_query_history():
"""获取所有查询历史记录"""
if not ensure_database():
logger.error("数据库初始化失败")
return []
conn = get_db_connection()
cursor = conn.cursor()
try:
cursor.execute('''
SELECT id, name, description, execution_time, total_keys,
differences_count, identical_count, created_at
FROM query_history
ORDER BY created_at DESC
''')
rows = cursor.fetchall()
history_list = []
for row in rows:
history_list.append({
'id': row['id'],
'name': row['name'],
'description': row['description'],
'execution_time': row['execution_time'],
'total_keys': row['total_keys'],
'differences_count': row['differences_count'],
'identical_count': row['identical_count'],
'created_at': row['created_at']
})
return history_list
except Exception as e:
logger.error(f"获取查询历史记录失败: {e}")
return []
finally:
conn.close()
def get_query_history_by_id(history_id):
"""根据ID获取查询历史记录详情"""
if not ensure_database():
logger.error("数据库初始化失败")
return None
conn = get_db_connection()
cursor = conn.cursor()
try:
cursor.execute('''
SELECT * FROM query_history WHERE id = ?
''', (history_id,))
row = cursor.fetchone()
if row:
return {
'id': row['id'],
'name': row['name'],
'description': row['description'],
'pro_config': json.loads(row['pro_config']),
'test_config': json.loads(row['test_config']),
'query_config': json.loads(row['query_config']),
'query_keys': json.loads(row['query_keys']),
'results_summary': json.loads(row['results_summary']),
'execution_time': row['execution_time'],
'total_keys': row['total_keys'],
'differences_count': row['differences_count'],
'identical_count': row['identical_count'],
'created_at': row['created_at']
}
return None
except Exception as e:
logger.error(f"获取查询历史记录详情失败: {e}")
return None
finally:
conn.close()
def delete_query_history(history_id):
"""删除查询历史记录"""
if not ensure_database():
logger.error("数据库初始化失败")
return False
conn = get_db_connection()
cursor = conn.cursor()
try:
cursor.execute('DELETE FROM query_history WHERE id = ?', (history_id,))
conn.commit()
success = cursor.rowcount > 0
if success:
logger.info(f"查询历史记录ID {history_id} 删除成功")
return success
except Exception as e:
logger.error(f"删除查询历史记录失败: {e}")
return False
finally:
conn.close()
def create_connection(config):
"""创建Cassandra连接"""
try:
@@ -684,6 +819,35 @@ def query_compare():
}
logger.info(f"比对完成:发现 {len(differences)} 处差异")
# 自动保存查询历史记录(可选,基于执行结果)
try:
# 生成历史记录名称
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
history_name = f"查询_{timestamp}"
history_description = f"自动保存 - 查询{len(values)}个Key发现{len(differences)}处差异"
# 保存历史记录
save_query_history(
name=history_name,
description=history_description,
pro_config=pro_config,
test_config=test_config,
query_config={
'keys': keys,
'fields_to_compare': fields_to_compare,
'exclude_fields': exclude_fields
},
query_keys=values,
results_summary=summary,
execution_time=0.0, # 可以后续优化计算实际执行时间
total_keys=len(values),
differences_count=len(differences),
identical_count=len(identical_results)
)
except Exception as e:
logger.warning(f"保存查询历史记录失败: {e}")
return jsonify(result)
except Exception as e:
@@ -769,5 +933,67 @@ def api_init_database():
else:
return jsonify({'success': False, 'error': '数据库初始化失败'}), 500
# 查询历史管理API
@app.route('/api/query-history', methods=['GET'])
def api_get_query_history():
"""获取所有查询历史记录"""
history_list = get_query_history()
return jsonify({'success': True, 'data': history_list})
@app.route('/api/query-history', methods=['POST'])
def api_save_query_history():
"""保存查询历史记录"""
try:
data = request.json
name = data.get('name', '').strip()
description = data.get('description', '').strip()
pro_config = data.get('pro_config', {})
test_config = data.get('test_config', {})
query_config = data.get('query_config', {})
query_keys = data.get('query_keys', [])
results_summary = data.get('results_summary', {})
execution_time = data.get('execution_time', 0.0)
total_keys = data.get('total_keys', 0)
differences_count = data.get('differences_count', 0)
identical_count = data.get('identical_count', 0)
if not name:
return jsonify({'success': False, 'error': '历史记录名称不能为空'}), 400
success = save_query_history(
name, description, pro_config, test_config, query_config,
query_keys, results_summary, execution_time, total_keys,
differences_count, identical_count
)
if success:
return jsonify({'success': True, 'message': '查询历史记录保存成功'})
else:
return jsonify({'success': False, 'error': '查询历史记录保存失败'}), 500
except Exception as e:
logger.error(f"保存查询历史记录API失败: {e}")
return jsonify({'success': False, 'error': str(e)}), 500
@app.route('/api/query-history/<int:history_id>', methods=['GET'])
def api_get_query_history_detail(history_id):
"""获取指定查询历史记录详情"""
history_record = get_query_history_by_id(history_id)
if history_record:
return jsonify({'success': True, 'data': history_record})
else:
return jsonify({'success': False, 'error': '查询历史记录不存在'}), 404
@app.route('/api/query-history/<int:history_id>', methods=['DELETE'])
def api_delete_query_history(history_id):
"""删除查询历史记录"""
success = delete_query_history(history_id)
if success:
return jsonify({'success': True, 'message': '查询历史记录删除成功'})
else:
return jsonify({'success': False, 'error': '查询历史记录删除失败'}), 500
if __name__ == '__main__':
app.run(debug=True, port=5001)
app.run(debug=True, port=5000)

File diff suppressed because it is too large Load Diff

View File

@@ -94,6 +94,56 @@
max-width: 600px !important;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3) !important;
}
/* 树形视图样式 */
.tree-view {
font-family: 'Courier New', monospace;
font-size: 0.9em;
max-height: 500px;
overflow-y: auto;
border: 1px solid #e9ecef;
border-radius: 5px;
padding: 10px;
background-color: #f8f9fa;
}
.tree-node {
margin: 2px 0;
}
.tree-toggle {
cursor: pointer;
user-select: none;
margin-right: 5px;
color: #6c757d;
}
.tree-toggle:hover {
color: #495057;
}
.tree-children {
margin-left: 15px;
}
.tree-item {
margin: 1px 0;
padding: 1px 0;
}
/* 原生数据搜索高亮 */
.raw-data-container mark {
background-color: #fff3cd !important;
padding: 1px 2px;
border-radius: 2px;
}
/* 自定义分页输入框 */
.form-control:focus {
border-color: #86b7fe;
outline: 0;
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
}
</style>
</head>
<body>
@@ -164,6 +214,18 @@
</button>
</div>
</div>
<div class="row mt-2">
<div class="col-6">
<button class="btn btn-warning btn-sm w-100" onclick="showQueryHistoryDialog()">
<i class="fas fa-history"></i> 查询历史
</button>
</div>
<div class="col-6">
<button class="btn btn-secondary btn-sm w-100" onclick="showSaveHistoryDialog()">
<i class="fas fa-bookmark"></i> 保存历史
</button>
</div>
</div>
</div>
</div>