该webui的主要作用是作为一个数据库管理系统对本地mysql数据库进行管理。这里会手把手教学如何实现的,并在文末给出初代完整flask数据库管理系统的完整代码!希望能帮助到有需要的同学。本来是想用来干点其他的,但是想了一下决定还是完整开源出来,各位看官,用的话记得给个鸣谢或者引用呗!Thanks♪(・ω・)ノ
注:本人软工部分也是刚学习不久,代码规范和代码维护上存在欠缺,还需看官多多包涵,恳请批评指正!
这是我的界面截图(背景随便找的)
登录界面:
数据库选择界面:
数据库管理界面:
搜索结果:
现在我们开始
首先,先安装mysql数据库,这里给出一个windows的下载链接,我选择的是mysql8.4.0.lts版本,MySQL :: Download MySQL Community Server
以及mysql workbench-mysql的可视化界面
MySQL :: Download MySQL Workbench
下载后根据安装指引安装即可,记得先给设置一个从用户账户和密码,该账户用来给flask连接数据库。记住保存路径,并勾选world数据库(方便后期调试)
然后设置系统环境变量,右键此电脑→高级系统设置→系统变量设置→系统变量→path→新建→粘贴刚才的保存路径(默认是C:\Program Files\MySQL\MySQL Server 8.4\bin,需要查看该目录下是否存在mysql.exe)
mysql安装好后按道理理论上会自动启动,不过也可以通过win+r输入services.msc查询,找到mysql开头的,我的是MySQL84,右键属性可以看到
这样就可以了。
然后试一下,找一个空白的地方shift+右键,打开powershell,然后键入 mysql -u root账户名 -p,然后输入密码验证。显示<mysql>即成功安装。
然后就是python,python的安装自行搜索,不做过多停留,安装完python后给pip换为国内源,
windows环境下: 比如windows账号是 admin
那么建立 admin主目录下的 pip子目录,在此pip子目录下建立pip的配置文件:pip.ini
位于c:\users\admin\pip\pip.ini
coding: GBK
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
[install]
trusted-host = https://pypi.tuna.tsinghua.edu.cn
#清华大学:https://pypi.tuna.tsinghua.edu.cn/simple
#阿里云:http://mirrors.aliyun.com/pypi/simple/
#豆瓣:http://pypi.douban.com/simple/
=================================================================
推荐采用python虚拟环境中执行该系统环境配置
创建一个工程目录,并在该目录下执行powershell(shift + 右键)或者终端(ctrl+alt+T)
python -m venv venv
venv/script/activate
安装flask框架(mysql):
pip install flask
pip install mysql-connector-python
pip install Flask mysql-connector-python
pip install Flask-Session
这样环境就配置好了
然后就是执行python文件,python app.py
如果终端显示
则表示运行成功,并可在浏览器输入http://127.0.0.1:5000访问。
以下是app.py的示例代码:
################################app.py############################
from flask import Flask, request, jsonify, render_template, redirect, url_for, session
from flask_session import Session
import mysql.connector
app = Flask(__name__)
app.secret_key = 'root' # 用于会话管理
app.config['SESSION_TYPE'] = 'filesystem' # 使用文件系统存储会话
Session(app)
# 预定义账号和密码
USERS = {
'admin': 'admin',
'旅馆管理系统': '123456'
}
# 数据库连接配置
db_config = {
'host': 'localhost',
'user': '旅馆管理系统',
'password': '123456'
}
def get_db_connection():
conn = mysql.connector.connect(
host=db_config['host'],
user=db_config['user'],
password=db_config['password']
)
return conn
def get_databases():
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute("SHOW DATABASES")
databases = [database[0] for database in cursor.fetchall() if database[0] != 'information_schema'] # 排除系统数据库
cursor.close()
conn.close()
return databases
def get_tables(database):
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute(f"USE {database}")
cursor.execute("SHOW TABLES")
tables = [table[0] for table in cursor.fetchall()]
cursor.close()
conn.close()
return tables
def get_table_fields(database, table):
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute(f"USE {database}")
cursor.execute(f"SHOW COLUMNS FROM {table}")
fields = [field[0] for field in cursor.fetchall()]
cursor.close()
conn.close()
return fields
def get_table_records(database, table):
conn = get_db_connection()
cursor = conn.cursor(dictionary=True)
cursor.execute(f"USE {database}")
cursor.execute(f"SELECT * FROM {table}")
records = cursor.fetchall()
cursor.close()
conn.close()
return records
# 获取表的主键字段
def get_table_primary_key(database, table):
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute(f"USE {database}")
cursor.execute(f"SHOW KEYS FROM {table} WHERE Key_name = 'PRIMARY'")
primary_key = cursor.fetchone()
cursor.close()
conn.close()
return primary_key[4] if primary_key else None
# 用户登录页
@app.route('/', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
if username in USERS and USERS[username] == password:
session['username'] = username # 将用户名存储在session中
return redirect(url_for('home'))
else:
return 'Invalid username or password', 401
return render_template('login.html')
# 用户登出页
@app.route('/logout')
def logout():
session.pop('username', None) # 清除会话数据
return redirect(url_for('login'))
# 用户管理页
@app.route('/home')
def home():
if 'username' not in session:
return redirect(url_for('login'))
return render_template('index.html', databases=get_databases())
# 进入数据库
@app.route('/enter-database', methods=['POST'])
def enter_database():
if 'username' not in session:
return redirect(url_for('login'))
selected_database = request.form.get('database')
session['selected_database'] = selected_database
return redirect(url_for('database_home'))
# 数据库主页
@app.route('/database_home')
def database_home():
if 'username' not in session or 'selected_database' not in session:
return redirect(url_for('login'))
selected_database = session['selected_database']
tables = get_tables(selected_database)
selected_table = request.args.get('table', tables[0] if tables else None)
fields = get_table_fields(selected_database, selected_table) if selected_table else []
records = get_table_records(selected_database, selected_table) if selected_table else []
primary_key = get_table_primary_key(selected_database, selected_table)
return render_template('database_home.html',
database=selected_database,
tables=tables,
selected_table=selected_table,
fields=fields,
records=records,
field_names=fields,
primary_key=primary_key) # 将主键字段传递给模板
# 获取表的字段
@app.route('/get_table_fields', methods=['POST'])
def get_table_fields_route():
if 'username' not in session or 'selected_database' not in session:
return redirect(url_for('login'))
database = session['selected_database']
table = request.form.get('table')
fields = get_table_fields(database, table)
return jsonify(fields)
# 保存记录
@app.route('/save_record', methods=['POST'])
def save_record():
if 'username' not in session or 'selected_database' not in session:
return jsonify({'success': False, 'error': 'Unauthorized'}), 403
data = request.get_json()
database = data['database']
table = data['table']
record = data['record']
print("Saving record:", record) # 添加调试输出
if 'id' not in record:
return jsonify({'success': False, 'error': 'Missing id'}), 400
conn = get_db_connection()
cursor = conn.cursor()
update_query = f"UPDATE {database}.{table} SET "
update_query += ", ".join([f"{field} = %s" for field in record.keys() if field != 'id'])
update_query += " WHERE id = %s"
params = [record[field] for field in record.keys() if field != 'id'] + [record['id']]
try:
cursor.execute(update_query, params)
conn.commit()
success = True
except Exception as e:
print(e)
success = False
cursor.close()
conn.close()
return jsonify({'success': success})
# 删除记录
@app.route('/delete_record', methods=['POST'])
def delete_record():
if 'username' not in session or 'selected_database' not in session:
return jsonify({'success': False, 'error': 'Unauthorized'}), 403
data = request.get_json()
database = data['database']
table = data['table']
record_name = data['name'] # 修改为 'name' 字段
print("Deleting record with name:", record_name) # 添加调试输出
conn = get_db_connection()
cursor = conn.cursor()
delete_query = f"DELETE FROM {database}.{table} WHERE Name = %s" # 使用 'Name' 字段作为唯一标识
try:
cursor.execute(delete_query, (record_name,))
conn.commit()
success = True
except Exception as e:
print(e)
success = False
cursor.close()
conn.close()
return jsonify({'success': success})
# 保存新记录
@app.route('/save_new_record', methods=['POST'])
def save_new_record():
if 'username' not in session or 'selected_database' not in session:
return jsonify({'success': False, 'error': 'Unauthorized'}), 403
data = request.get_json()
database = data['database']
table = data['table']
record = data['record']
print("Saving new record:", record) # 添加调试输出
# 构造插入记录的 SQL 查询语句
insert_query = f"INSERT INTO {database}.{table} ({', '.join(record.keys())}) VALUES ({', '.join(['%s']*len(record))})"
params = tuple(record.values()) # 将记录的值转换为元组形式
conn = get_db_connection()
cursor = conn.cursor()
try:
cursor.execute(insert_query, params)
conn.commit()
success = True
except Exception as e:
print(e)
success = False
cursor.close()
conn.close()
return jsonify({'success': success})
# 执行搜索并返回结果
def search_records(database, table, keyword):
conn = get_db_connection()
cursor = conn.cursor(dictionary=True)
# 构造模糊搜索的 SQL 查询语句
search_query = f"SELECT * FROM {database}.{table} WHERE "
search_query += " OR ".join([f"{field} LIKE %s" for field in get_table_fields(database, table)])
params = ['%' + keyword + '%'] * len(get_table_fields(database, table))
cursor.execute(search_query, params)
records = cursor.fetchall()
cursor.close()
conn.close()
return records
# 搜索页面
@app.route('/search_results')
def search_results():
if 'username' not in session or 'selected_database' not in session:
return redirect(url_for('login'))
selected_database = session['selected_database']
selected_table = request.args.get('table')
keyword = request.args.get('keyword')
records = search_records(selected_database, selected_table, keyword)
fields = get_table_fields(selected_database, selected_table)
return render_template('search_results.html',
keyword=keyword,
database=selected_database,
selected_table=selected_table,
fields=fields,
records=records)
if __name__ == '__main__':
app.run(debug=True)
以下是一些示例html
####################database_home.html#########################
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Database Home</title>
<style>
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
background-image: url('/static/background.jpg');
background-size: cover;
background-position: center;
background-attachment: fixed;
height: 100vh;
overflow: auto;
}
.container {
background-color: rgba(255, 255, 255, 0.8);
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
margin: 20px;
}
h2 {
margin-bottom: 10px;
font-size: 24px;
}
button {
padding: 12px 24px;
cursor: pointer;
border: none;
border-radius: 5px;
font-size: 18px;
outline: none;
transition: background-color 0.3s ease;
}
.go-back-button {
background-color: #dc3545;
color: #fff;
margin-bottom: 20px;
text-align: right;
font-size: 18px;
}
.go-back-button:hover {
background-color: #c82333;
text-align: right;
}
.search-form-container,
.table-select-container {
text-align: left;
margin-bottom: 50px;
}
input[type="text"],
select {
width: calc(100% - 120px);
padding: 10px;
margin-bottom: 10px;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 5px;
background-color: #f8f8f8;
font-size: 18px;
outline: none;
}
button[type="submit"] {
padding: 12px 24px;
cursor: pointer;
border: none;
border-radius: 5px;
background-color: #007bff;
color: #fff;
font-size: 18px;
outline: none;
transition: background-color 0.3s ease;
}
button[type="submit"]:hover {
background-color: #0056b3;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
}
th,
td {
border: 1px solid black;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
.editable {
background-color: #e8f0fe;
}
#new-record-table {
display: none;
margin-top: 20px;
}
#new-record-table td {
width: 150px;
padding: 5px;
}
.icon-button {
background: none;
border: none;
cursor: pointer;
padding: 0;
outline: none;
}
.icon-button img {
width: 48px;
/* 调整SVG图标的尺寸 */
height: 48px;
/* 调整SVG图标的尺寸 */
}
.divider {
border-top: 2px solid #ccc;
margin-top: 20px;
margin-bottom: 20px;
}
.footer {
position: fixed;
bottom: 0;
width: 100%;
background-color: #d6dce1;
padding: 10px 0;
text-align: center;
font-size: 14px;
color: #6c757d;
}
</style>
</head>
<body>
<div class="footer">
Version 1.0.0
</div>
<div id="user-info"
style="position: absolute; top: 10px; right: 10px; padding: 10px; background-color: #3ec83e; border: 1px solid #007bff; border-radius: 5px;">
<span style="color: #0b0808; font-weight: bold;">你好!{{ session['username'] }}</span>
</div>
<div class="container">
<h2 style="font-size: 50px; font-weight: bold;">当前数据库:{{ database }}</h2>
<button class="go-back-button" style="float: right; background-color:#d05d63;"
onclick="goBack()">退出当前数据库</button>
<div class="search-form-container">
<form id="search-form" onsubmit="search(event)">
<input type="text" id="keyword" name="keyword" placeholder="搜索..."
style="height=45px; padding: 10px; border: 2px solid #ccc; border-radius: 10px; font-size: 16px;">
<input type="hidden" name="table" value="{{ selected_table }}">
<button type="submit" style="background-color:#a099dd;">搜索</button>
</form>
</div>
<div class="table-select-container" style="display: flex; align-items: center; margin-top: 20px;">
<label for="table-select" style="font-size: 20px; margin-right: 10px;"><strong>当前访问的表:</strong></label>
<select id="table-select" name="table" onchange="updateTable(this.value)"
style="font-size: 20px; width: 200px;">
{% for table in tables %}
<option value="{{ table }}" {% if table==selected_table %}selected{% endif %}>{{ table }}</option>
{% endfor %}
</select>
</div>
<button class="icon-button" onclick="toggleNewRecordForm()" style="text-align: center;">
<img src="/static/svg/档案.svg" alt="添加记录" style="vertical-align: middle;">
<br>
<span id="toggle-text" style="font-size: 20px; font-weight: bold;">{{ '添加记录明细' if button_new_record_activate
else '添加记录' }}</span>
</button>
<div id="new-record-table">
<h3>添加记录</h3>
<table id="new-record-form">
<tbody>
{% for field in field_names %}
<tr>
<td>{{ '*' if field == primary_key else '' }}{{ field }}</td>
<td><input type="text" id="new-{{ field }}" name="{{ field }}"></td>
</tr>
{% endfor %}
<tr>
<td colspan="2" style="text-align: center;"><button class="icon-button"
onclick="saveNewRecord()"><img src="/static/svg/上传.svg" alt="保存"></button></td>
</tr>
</tbody>
</table>
</div>
<div class="divider"></div>
<h3>记录列表</h3>
<table id="record-list">
<thead>
<tr>
{% for field in fields %}
<th>{{ field }}</th>
{% endfor %}
<th>保存修改</th>
<th>删除</th>
</tr>
</thead>
<tbody>
{% for record in records %}
<tr>
{% for field in fields %}
<td contenteditable="true" data-field="{{ field }}">{{ record[field] }}</td>
{% endfor %}
<td><button class="icon-button" onclick="saveRecord(this)"><img src="/static/svg/编辑.svg"
alt="保存"></button></td>
<td><button class="icon-button" onclick="confirmDelete(this)"><img src="/static/svg/删除.svg"
alt="删除"></button></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<script>
let button_new_record_activate = false;
function toggleNewRecordForm() {
button_new_record_activate = !button_new_record_activate;
document.getElementById('new-record-table').style.display = button_new_record_activate ? 'block' : 'none';
}
function updateTable(table) {
const urlParams = new URLSearchParams(window.location.search);
urlParams.set('table', table);
window.location.search = urlParams.toString();
}
function saveRecord(button) {
const row = button.closest('tr');
const fields = {};
row.querySelectorAll('td[data-field]').forEach(td => {
const fieldName = td.getAttribute('data-field');
fields[fieldName.toLowerCase()] = td.innerText;
});
fetch('/save_record', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
database: '{{ database }}',
table: '{{ selected_table }}',
record: fields
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('记录保存成功');
} else {
alert('记录保存失败');
}
});
}
function confirmDelete(button) {
if (confirm("确定要删除吗?")) {
deleteRecord(button);
} else {
// 用户取消删除操作
}
}
function deleteRecord(button) {
const row = button.closest('tr');
const recordName = row.querySelector('td[data-field="Name"]').innerText;
fetch('/delete_record', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
database: '{{ database }}',
table: '{{ selected_table }}',
name: recordName
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('记录删除成功');
row.remove();
} else {
alert('记录删除失败');
}
});
}
function search(event) {
event.preventDefault();
const keyword = document.getElementById('keyword').value.trim();
if (keyword === '') {
alert('请输入搜索关键字');
return;
}
const formData = new FormData(document.getElementById('search-form'));
const searchParams = new URLSearchParams(formData).toString();
window.location.href = `/search_results?${searchParams}`;
}
function showNewRecordForm() {
document.getElementById('new-record-table').style.display = 'block';
}
function saveNewRecord() {
const record = {};
{% for field in field_names %}
record['{{ field }}'] = document.getElementById('new-{{ field }}').value;
{% endfor %}
fetch('/save_new_record', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
database: '{{ database }}',
table: '{{ selected_table }}',
record: record
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('数据保存成功');
window.location.href = `/database_home?table={{ selected_table }}`;
} else {
alert('数据保存失败,请检查填写的数据格式或关键字错误');
}
});
}
function goBack() {
window.location.href = '/home';
}
function toggleNewRecordForm() {
button_new_record_activate = !button_new_record_activate;
document.getElementById('new-record-table').style.display = button_new_record_activate ? 'block' : 'none';
document.getElementById('toggle-text').innerText = button_new_record_activate ? '收起添加记录明细' : '添加记录';
}
</script>
</body>
</html>
##############################index.html#################################
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>数据库选择</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-image: url('/static/background.jpg');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.container {
background-color: rgba(255, 255, 255, 0.8);
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
margin: 20px;
width: 50%;
/* 设置容器的宽度为页面宽度的 80% */
}
form {
display: inline-block;
text-align: left;
width: 100%;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input[type="text"],
input[type="password"],
select {
width: 100%;
padding: 10px;
margin-bottom: 20px;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 5px;
background-color: #f8f8f8;
font-size: 16px;
outline: none;
}
.button-container {
display: flex;
justify-content: space-between;
}
button[type="submit"],
.logout-button {
padding: 10px 40px;
cursor: pointer;
border: none;
border-radius: 5px;
font-size: 16px;
outline: none;
transition: background-color 0.3s ease;
width: 48%;
/* 设置按钮宽度为48% */
text-align: center;
}
button[type="submit"] {
background-color: #007bff;
color: #fff;
}
button[type="submit"]:hover {
background-color: #0056b3;
}
.logout-button {
background-color: #dc3545;
color: #fff;
text-decoration: none;
display: inline-block;
line-height: 1.5;
}
.logout-button:hover {
background-color: #c82333;
}
h2 {
margin-bottom: 10px;
color: white;
}
h4 {
margin-bottom: 20px;
font-size: 14px;
text-align: right;
color: white;
}
.footer {
position: fixed;
bottom: 0;
width: 100%;
background-color: #d5dee7;
padding: 10px 0;
text-align: center;
font-size: 14px;
color: #6c757d;
}
</style>
</head>
<body>
<div id="user-info"
style="position: absolute; top: 10px; right: 10px; padding: 10px; background-color: #3ec83e; border: 1px solid #007bff; border-radius: 5px;">
<span style="color: #0b0808; font-weight: bold;">你好!{{ session['username'] }}</span>
</div>
<div class="container">
<h2>数据库信息管理系统</h2>
<h4>——buid by 𝓣𝔀𝓲𝓽𝓲𝓰𝓱𝓽@yhy2021_IEE</h4>
<form action="/enter-database" method="post">
<label for="db_user">数据库用户:</label>
<input type="text" id="db_user" name="db_user" required>
<label for="db_password">数据库密码:</label>
<input type="password" id="db_password" name="db_password" required>
<label for="database">选择数据库:</label>
<select id="database" name="database">
#############模拟权限管理,这一版已经被淘汰了,这个写法不好################
{% if session['username'] == '旅馆管理系统' %}
<option value="world">world</option>
<option value="test_db">test_db</option>
{% else %}
{% for database in databases %}
<option value="{{ database }}">{{ database }}</option>
{% endfor %}
{% endif %}
</select>
<div class="button-container">
<a href="/" class="logout-button">退出登录</a>
<button type="submit">进入数据库</button>
</div>
</form>
</div>
<div class="footer">
Version 1.0.0
</div>
</body>
</html>
#################################login.html#################################
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-image: url('/static/background.jpg');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.login-container {
text-align: center;
position: relative;
border-radius: 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
width: 400px;
}
.gif-background {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 120%;
height: 150%;
background-image: url('/static/img.gif');
background-size: cover;
/* 自适应拉伸 */
border-radius: 20px;
z-index: -1;
}
h2 {
color: white;
}
form {
display: inline-block;
text-align: left;
position: relative;
z-index: 1;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: white;
}
input[type="text"],
input[type="password"] {
width: 100%;
padding: 10px;
margin-bottom: 20px;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 5px;
background-color: #f8f8f8;
font-size: 16px;
color: white;
outline: none;
}
button[type="submit"] {
padding: 10px 100px;
cursor: pointer;
border: none;
border-radius: 5px;
background-color: #007bff;
color: #fff;
font-size: 16px;
outline: none;
transition: background-color 0.3s ease;
}
button[type="submit"]:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<div class="login-container">
<div class="gif-background"></div>
<h2>MySQL信息管理系统统一登录</h2>
<form method="post">
<label for="username">信息管理系统账户:</label>
<input type="text" id="username" name="username" required><br><br>
<label for="password">密码:</label>
<input type="password" id="password" name="password" required><br><br>
<button type="submit">登录</button>
</form>
</div>
</body>
</html>
#################################search_results.html#############################
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Search Results</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-image: url('/static/background.jpg');
background-size: cover;
background-position: center;
height: 100vh;
overflow: auto;
}
.container {
background-color: rgba(255, 255, 255, 0.8);
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
margin: 20px;
}
h1 {
margin-top: 0;
}
button {
padding: 10px 20px;
cursor: pointer;
border: none;
border-radius: 5px;
font-size: 16px;
outline: none;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #0056b3;
color: #fff;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
th,
td {
border: 1px solid #ccc;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
.editable {
background-color: #e8f0fe;
}
</style>
</head>
<body>
<div id="user-info"
style="position: absolute; top: 10px; right: 10px; padding: 10px; background-color: #3ec83e; border: 1px solid #007bff; border-radius: 5px;">
<span style="color: #0b0808; font-weight: bold;">你好!{{ session['username'] }}</span>
</div>
<div class="container">
<h1>搜索条件 <button class="go-back-button" style="float: right; background-color:#d05d63;"
onclick="goBack()">返回上一级</button></h1>
<p style="font-size: 18px; font-weight: bold;">搜索关键词: {{ keyword }}</p>
<p style="font-size: 18px; font-weight: bold;">被搜索数据库: {{ database }}</p>
<p style="font-size: 18px; font-weight: bold;">被搜索表: {{ selected_table }}</p>
<form id="search-form" style="text-align: left;" onsubmit="search(event)">
<input type="text" id="keyword" name="keyword" placeholder="搜索..."
style="width: 50%; padding: 10px; border: 2px solid #ccc; border-radius: 10px; font-size: 16px;">
<input type="hidden" name="table" value="{{ selected_table }}">
<button type="submit" style="background-color:#a099dd;">搜索</button>
</form>
<h2>搜索结果列表:</h2>
<table>
<thead>
<tr>
{% for field in fields %}
<th>{{ field }}</th>
{% endfor %}
<th>修改</th>
<th>删除</th>
</tr>
</thead>
<tbody>
{% for record in records %}
<tr>
{% for field in fields %}
<td contenteditable="true" data-field="{{ field }}">{{ record[field] }}</td>
{% endfor %}
<td><button onclick="saveRecord(this)">保存</button></td>
<td><button onclick="confirmDelete(this, '{{ record.Name }}')">删除</button></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<script>
function goBack() {
window.history.back(); // 返回到上一个页面,即database_home.html页面
}
function search(event) {
event.preventDefault(); // 阻止表单默认提交行为
const keyword = document.getElementById('keyword').value.trim();
if (keyword === '') {
alert('请输入搜索关键字');
return;
}
const formData = new FormData(document.getElementById('search-form'));
const searchParams = new URLSearchParams(formData).toString();
window.location.href = `/search_results?${searchParams}`;
}
function saveRecord(button) {
const row = button.closest('tr');
const fields = {};
row.querySelectorAll('td[data-field]').forEach(td => {
const fieldName = td.getAttribute('data-field');
fields[fieldName.toLowerCase()] = td.innerText;
});
fetch('/save_record', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
database: '{{ database }}',
table: '{{ selected_table }}',
record: fields
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('记录保存成功');
} else {
alert('记录保存失败');
}
});
}
function confirmDelete(button, name) {
if (confirm("确定要删除吗?")) {
deleteRecord(button, name);
} else {
// 用户取消删除操作
}
}
function deleteRecord(button, name) {
const row = button.closest('tr');
fetch('/delete_record', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
database: '{{ database }}',
table: '{{ selected_table }}',
name: name // 将记录的名称作为参数传递
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('记录删除成功');
row.remove();
} else {
alert('记录删除失败');
}
});
}
</script>
</body>
</html>
注,需要把html放到名为templates的文件夹下。
That’s All,THANKS!
版权归原作者 能不能不要报错! 所有, 如有侵权,请联系我们删除。