完善查询逻辑
This commit is contained in:
238
app.py
238
app.py
@@ -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)
|
||||
|
955
static/js/app.js
955
static/js/app.js
File diff suppressed because it is too large
Load Diff
@@ -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>
|
||||
|
||||
|
Reference in New Issue
Block a user