当前位置:   article > 正文

使用python的flask框架做一个本地mysql服务器的webui!_flask ui

flask ui

该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的示例代码:

  1. ################################app.py############################
  2. from flask import Flask, request, jsonify, render_template, redirect, url_for, session
  3. from flask_session import Session
  4. import mysql.connector
  5. app = Flask(__name__)
  6. app.secret_key = 'root' # 用于会话管理
  7. app.config['SESSION_TYPE'] = 'filesystem' # 使用文件系统存储会话
  8. Session(app)
  9. # 预定义账号和密码
  10. USERS = {
  11. 'admin': 'admin',
  12. '旅馆管理系统': '123456'
  13. }
  14. # 数据库连接配置
  15. db_config = {
  16. 'host': 'localhost',
  17. 'user': '旅馆管理系统',
  18. 'password': '123456'
  19. }
  20. def get_db_connection():
  21. conn = mysql.connector.connect(
  22. host=db_config['host'],
  23. user=db_config['user'],
  24. password=db_config['password']
  25. )
  26. return conn
  27. def get_databases():
  28. conn = get_db_connection()
  29. cursor = conn.cursor()
  30. cursor.execute("SHOW DATABASES")
  31. databases = [database[0] for database in cursor.fetchall() if database[0] != 'information_schema'] # 排除系统数据库
  32. cursor.close()
  33. conn.close()
  34. return databases
  35. def get_tables(database):
  36. conn = get_db_connection()
  37. cursor = conn.cursor()
  38. cursor.execute(f"USE {database}")
  39. cursor.execute("SHOW TABLES")
  40. tables = [table[0] for table in cursor.fetchall()]
  41. cursor.close()
  42. conn.close()
  43. return tables
  44. def get_table_fields(database, table):
  45. conn = get_db_connection()
  46. cursor = conn.cursor()
  47. cursor.execute(f"USE {database}")
  48. cursor.execute(f"SHOW COLUMNS FROM {table}")
  49. fields = [field[0] for field in cursor.fetchall()]
  50. cursor.close()
  51. conn.close()
  52. return fields
  53. def get_table_records(database, table):
  54. conn = get_db_connection()
  55. cursor = conn.cursor(dictionary=True)
  56. cursor.execute(f"USE {database}")
  57. cursor.execute(f"SELECT * FROM {table}")
  58. records = cursor.fetchall()
  59. cursor.close()
  60. conn.close()
  61. return records
  62. # 获取表的主键字段
  63. def get_table_primary_key(database, table):
  64. conn = get_db_connection()
  65. cursor = conn.cursor()
  66. cursor.execute(f"USE {database}")
  67. cursor.execute(f"SHOW KEYS FROM {table} WHERE Key_name = 'PRIMARY'")
  68. primary_key = cursor.fetchone()
  69. cursor.close()
  70. conn.close()
  71. return primary_key[4] if primary_key else None
  72. # 用户登录页
  73. @app.route('/', methods=['GET', 'POST'])
  74. def login():
  75. if request.method == 'POST':
  76. username = request.form['username']
  77. password = request.form['password']
  78. if username in USERS and USERS[username] == password:
  79. session['username'] = username # 将用户名存储在session中
  80. return redirect(url_for('home'))
  81. else:
  82. return 'Invalid username or password', 401
  83. return render_template('login.html')
  84. # 用户登出页
  85. @app.route('/logout')
  86. def logout():
  87. session.pop('username', None) # 清除会话数据
  88. return redirect(url_for('login'))
  89. # 用户管理页
  90. @app.route('/home')
  91. def home():
  92. if 'username' not in session:
  93. return redirect(url_for('login'))
  94. return render_template('index.html', databases=get_databases())
  95. # 进入数据库
  96. @app.route('/enter-database', methods=['POST'])
  97. def enter_database():
  98. if 'username' not in session:
  99. return redirect(url_for('login'))
  100. selected_database = request.form.get('database')
  101. session['selected_database'] = selected_database
  102. return redirect(url_for('database_home'))
  103. # 数据库主页
  104. @app.route('/database_home')
  105. def database_home():
  106. if 'username' not in session or 'selected_database' not in session:
  107. return redirect(url_for('login'))
  108. selected_database = session['selected_database']
  109. tables = get_tables(selected_database)
  110. selected_table = request.args.get('table', tables[0] if tables else None)
  111. fields = get_table_fields(selected_database, selected_table) if selected_table else []
  112. records = get_table_records(selected_database, selected_table) if selected_table else []
  113. primary_key = get_table_primary_key(selected_database, selected_table)
  114. return render_template('database_home.html',
  115. database=selected_database,
  116. tables=tables,
  117. selected_table=selected_table,
  118. fields=fields,
  119. records=records,
  120. field_names=fields,
  121. primary_key=primary_key) # 将主键字段传递给模板
  122. # 获取表的字段
  123. @app.route('/get_table_fields', methods=['POST'])
  124. def get_table_fields_route():
  125. if 'username' not in session or 'selected_database' not in session:
  126. return redirect(url_for('login'))
  127. database = session['selected_database']
  128. table = request.form.get('table')
  129. fields = get_table_fields(database, table)
  130. return jsonify(fields)
  131. # 保存记录
  132. @app.route('/save_record', methods=['POST'])
  133. def save_record():
  134. if 'username' not in session or 'selected_database' not in session:
  135. return jsonify({'success': False, 'error': 'Unauthorized'}), 403
  136. data = request.get_json()
  137. database = data['database']
  138. table = data['table']
  139. record = data['record']
  140. print("Saving record:", record) # 添加调试输出
  141. if 'id' not in record:
  142. return jsonify({'success': False, 'error': 'Missing id'}), 400
  143. conn = get_db_connection()
  144. cursor = conn.cursor()
  145. update_query = f"UPDATE {database}.{table} SET "
  146. update_query += ", ".join([f"{field} = %s" for field in record.keys() if field != 'id'])
  147. update_query += " WHERE id = %s"
  148. params = [record[field] for field in record.keys() if field != 'id'] + [record['id']]
  149. try:
  150. cursor.execute(update_query, params)
  151. conn.commit()
  152. success = True
  153. except Exception as e:
  154. print(e)
  155. success = False
  156. cursor.close()
  157. conn.close()
  158. return jsonify({'success': success})
  159. # 删除记录
  160. @app.route('/delete_record', methods=['POST'])
  161. def delete_record():
  162. if 'username' not in session or 'selected_database' not in session:
  163. return jsonify({'success': False, 'error': 'Unauthorized'}), 403
  164. data = request.get_json()
  165. database = data['database']
  166. table = data['table']
  167. record_name = data['name'] # 修改为 'name' 字段
  168. print("Deleting record with name:", record_name) # 添加调试输出
  169. conn = get_db_connection()
  170. cursor = conn.cursor()
  171. delete_query = f"DELETE FROM {database}.{table} WHERE Name = %s" # 使用 'Name' 字段作为唯一标识
  172. try:
  173. cursor.execute(delete_query, (record_name,))
  174. conn.commit()
  175. success = True
  176. except Exception as e:
  177. print(e)
  178. success = False
  179. cursor.close()
  180. conn.close()
  181. return jsonify({'success': success})
  182. # 保存新记录
  183. @app.route('/save_new_record', methods=['POST'])
  184. def save_new_record():
  185. if 'username' not in session or 'selected_database' not in session:
  186. return jsonify({'success': False, 'error': 'Unauthorized'}), 403
  187. data = request.get_json()
  188. database = data['database']
  189. table = data['table']
  190. record = data['record']
  191. print("Saving new record:", record) # 添加调试输出
  192. # 构造插入记录的 SQL 查询语句
  193. insert_query = f"INSERT INTO {database}.{table} ({', '.join(record.keys())}) VALUES ({', '.join(['%s']*len(record))})"
  194. params = tuple(record.values()) # 将记录的值转换为元组形式
  195. conn = get_db_connection()
  196. cursor = conn.cursor()
  197. try:
  198. cursor.execute(insert_query, params)
  199. conn.commit()
  200. success = True
  201. except Exception as e:
  202. print(e)
  203. success = False
  204. cursor.close()
  205. conn.close()
  206. return jsonify({'success': success})
  207. # 执行搜索并返回结果
  208. def search_records(database, table, keyword):
  209. conn = get_db_connection()
  210. cursor = conn.cursor(dictionary=True)
  211. # 构造模糊搜索的 SQL 查询语句
  212. search_query = f"SELECT * FROM {database}.{table} WHERE "
  213. search_query += " OR ".join([f"{field} LIKE %s" for field in get_table_fields(database, table)])
  214. params = ['%' + keyword + '%'] * len(get_table_fields(database, table))
  215. cursor.execute(search_query, params)
  216. records = cursor.fetchall()
  217. cursor.close()
  218. conn.close()
  219. return records
  220. # 搜索页面
  221. @app.route('/search_results')
  222. def search_results():
  223. if 'username' not in session or 'selected_database' not in session:
  224. return redirect(url_for('login'))
  225. selected_database = session['selected_database']
  226. selected_table = request.args.get('table')
  227. keyword = request.args.get('keyword')
  228. records = search_records(selected_database, selected_table, keyword)
  229. fields = get_table_fields(selected_database, selected_table)
  230. return render_template('search_results.html',
  231. keyword=keyword,
  232. database=selected_database,
  233. selected_table=selected_table,
  234. fields=fields,
  235. records=records)
  236. if __name__ == '__main__':
  237. app.run(debug=True)

以下是一些示例html

  1. ####################database_home.html#########################
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Database Home</title>
  8. <style>
  9. body {
  10. margin: 0;
  11. padding: 0;
  12. font-family: Arial, sans-serif;
  13. background-image: url('/static/background.jpg');
  14. background-size: cover;
  15. background-position: center;
  16. background-attachment: fixed;
  17. height: 100vh;
  18. overflow: auto;
  19. }
  20. .container {
  21. background-color: rgba(255, 255, 255, 0.8);
  22. padding: 20px;
  23. border-radius: 10px;
  24. box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  25. margin: 20px;
  26. }
  27. h2 {
  28. margin-bottom: 10px;
  29. font-size: 24px;
  30. }
  31. button {
  32. padding: 12px 24px;
  33. cursor: pointer;
  34. border: none;
  35. border-radius: 5px;
  36. font-size: 18px;
  37. outline: none;
  38. transition: background-color 0.3s ease;
  39. }
  40. .go-back-button {
  41. background-color: #dc3545;
  42. color: #fff;
  43. margin-bottom: 20px;
  44. text-align: right;
  45. font-size: 18px;
  46. }
  47. .go-back-button:hover {
  48. background-color: #c82333;
  49. text-align: right;
  50. }
  51. .search-form-container,
  52. .table-select-container {
  53. text-align: left;
  54. margin-bottom: 50px;
  55. }
  56. input[type="text"],
  57. select {
  58. width: calc(100% - 120px);
  59. padding: 10px;
  60. margin-bottom: 10px;
  61. box-sizing: border-box;
  62. border: 1px solid #ccc;
  63. border-radius: 5px;
  64. background-color: #f8f8f8;
  65. font-size: 18px;
  66. outline: none;
  67. }
  68. button[type="submit"] {
  69. padding: 12px 24px;
  70. cursor: pointer;
  71. border: none;
  72. border-radius: 5px;
  73. background-color: #007bff;
  74. color: #fff;
  75. font-size: 18px;
  76. outline: none;
  77. transition: background-color 0.3s ease;
  78. }
  79. button[type="submit"]:hover {
  80. background-color: #0056b3;
  81. }
  82. table {
  83. width: 100%;
  84. border-collapse: collapse;
  85. margin-top: 10px;
  86. }
  87. th,
  88. td {
  89. border: 1px solid black;
  90. padding: 8px;
  91. text-align: left;
  92. }
  93. th {
  94. background-color: #f2f2f2;
  95. }
  96. .editable {
  97. background-color: #e8f0fe;
  98. }
  99. #new-record-table {
  100. display: none;
  101. margin-top: 20px;
  102. }
  103. #new-record-table td {
  104. width: 150px;
  105. padding: 5px;
  106. }
  107. .icon-button {
  108. background: none;
  109. border: none;
  110. cursor: pointer;
  111. padding: 0;
  112. outline: none;
  113. }
  114. .icon-button img {
  115. width: 48px;
  116. /* 调整SVG图标的尺寸 */
  117. height: 48px;
  118. /* 调整SVG图标的尺寸 */
  119. }
  120. .divider {
  121. border-top: 2px solid #ccc;
  122. margin-top: 20px;
  123. margin-bottom: 20px;
  124. }
  125. .footer {
  126. position: fixed;
  127. bottom: 0;
  128. width: 100%;
  129. background-color: #d6dce1;
  130. padding: 10px 0;
  131. text-align: center;
  132. font-size: 14px;
  133. color: #6c757d;
  134. }
  135. </style>
  136. </head>
  137. <body>
  138. <div class="footer">
  139. Version 1.0.0
  140. </div>
  141. <div id="user-info"
  142. style="position: absolute; top: 10px; right: 10px; padding: 10px; background-color: #3ec83e; border: 1px solid #007bff; border-radius: 5px;">
  143. <span style="color: #0b0808; font-weight: bold;">你好!{{ session['username'] }}</span>
  144. </div>
  145. <div class="container">
  146. <h2 style="font-size: 50px; font-weight: bold;">当前数据库:{{ database }}</h2>
  147. <button class="go-back-button" style="float: right; background-color:#d05d63;"
  148. onclick="goBack()">退出当前数据库</button>
  149. <div class="search-form-container">
  150. <form id="search-form" onsubmit="search(event)">
  151. <input type="text" id="keyword" name="keyword" placeholder="搜索..."
  152. style="height=45px; padding: 10px; border: 2px solid #ccc; border-radius: 10px; font-size: 16px;">
  153. <input type="hidden" name="table" value="{{ selected_table }}">
  154. <button type="submit" style="background-color:#a099dd;">搜索</button>
  155. </form>
  156. </div>
  157. <div class="table-select-container" style="display: flex; align-items: center; margin-top: 20px;">
  158. <label for="table-select" style="font-size: 20px; margin-right: 10px;"><strong>当前访问的表:</strong></label>
  159. <select id="table-select" name="table" onchange="updateTable(this.value)"
  160. style="font-size: 20px; width: 200px;">
  161. {% for table in tables %}
  162. <option value="{{ table }}" {% if table==selected_table %}selected{% endif %}>{{ table }}</option>
  163. {% endfor %}
  164. </select>
  165. </div>
  166. <button class="icon-button" onclick="toggleNewRecordForm()" style="text-align: center;">
  167. <img src="/static/svg/档案.svg" alt="添加记录" style="vertical-align: middle;">
  168. <br>
  169. <span id="toggle-text" style="font-size: 20px; font-weight: bold;">{{ '添加记录明细' if button_new_record_activate
  170. else '添加记录' }}</span>
  171. </button>
  172. <div id="new-record-table">
  173. <h3>添加记录</h3>
  174. <table id="new-record-form">
  175. <tbody>
  176. {% for field in field_names %}
  177. <tr>
  178. <td>{{ '*' if field == primary_key else '' }}{{ field }}</td>
  179. <td><input type="text" id="new-{{ field }}" name="{{ field }}"></td>
  180. </tr>
  181. {% endfor %}
  182. <tr>
  183. <td colspan="2" style="text-align: center;"><button class="icon-button"
  184. onclick="saveNewRecord()"><img src="/static/svg/上传.svg" alt="保存"></button></td>
  185. </tr>
  186. </tbody>
  187. </table>
  188. </div>
  189. <div class="divider"></div>
  190. <h3>记录列表</h3>
  191. <table id="record-list">
  192. <thead>
  193. <tr>
  194. {% for field in fields %}
  195. <th>{{ field }}</th>
  196. {% endfor %}
  197. <th>保存修改</th>
  198. <th>删除</th>
  199. </tr>
  200. </thead>
  201. <tbody>
  202. {% for record in records %}
  203. <tr>
  204. {% for field in fields %}
  205. <td contenteditable="true" data-field="{{ field }}">{{ record[field] }}</td>
  206. {% endfor %}
  207. <td><button class="icon-button" onclick="saveRecord(this)"><img src="/static/svg/编辑.svg"
  208. alt="保存"></button></td>
  209. <td><button class="icon-button" onclick="confirmDelete(this)"><img src="/static/svg/删除.svg"
  210. alt="删除"></button></td>
  211. </tr>
  212. {% endfor %}
  213. </tbody>
  214. </table>
  215. </div>
  216. <script>
  217. let button_new_record_activate = false;
  218. function toggleNewRecordForm() {
  219. button_new_record_activate = !button_new_record_activate;
  220. document.getElementById('new-record-table').style.display = button_new_record_activate ? 'block' : 'none';
  221. }
  222. function updateTable(table) {
  223. const urlParams = new URLSearchParams(window.location.search);
  224. urlParams.set('table', table);
  225. window.location.search = urlParams.toString();
  226. }
  227. function saveRecord(button) {
  228. const row = button.closest('tr');
  229. const fields = {};
  230. row.querySelectorAll('td[data-field]').forEach(td => {
  231. const fieldName = td.getAttribute('data-field');
  232. fields[fieldName.toLowerCase()] = td.innerText;
  233. });
  234. fetch('/save_record', {
  235. method: 'POST',
  236. headers: {
  237. 'Content-Type': 'application/json'
  238. },
  239. body: JSON.stringify({
  240. database: '{{ database }}',
  241. table: '{{ selected_table }}',
  242. record: fields
  243. })
  244. })
  245. .then(response => response.json())
  246. .then(data => {
  247. if (data.success) {
  248. alert('记录保存成功');
  249. } else {
  250. alert('记录保存失败');
  251. }
  252. });
  253. }
  254. function confirmDelete(button) {
  255. if (confirm("确定要删除吗?")) {
  256. deleteRecord(button);
  257. } else {
  258. // 用户取消删除操作
  259. }
  260. }
  261. function deleteRecord(button) {
  262. const row = button.closest('tr');
  263. const recordName = row.querySelector('td[data-field="Name"]').innerText;
  264. fetch('/delete_record', {
  265. method: 'POST',
  266. headers: {
  267. 'Content-Type': 'application/json'
  268. },
  269. body: JSON.stringify({
  270. database: '{{ database }}',
  271. table: '{{ selected_table }}',
  272. name: recordName
  273. })
  274. })
  275. .then(response => response.json())
  276. .then(data => {
  277. if (data.success) {
  278. alert('记录删除成功');
  279. row.remove();
  280. } else {
  281. alert('记录删除失败');
  282. }
  283. });
  284. }
  285. function search(event) {
  286. event.preventDefault();
  287. const keyword = document.getElementById('keyword').value.trim();
  288. if (keyword === '') {
  289. alert('请输入搜索关键字');
  290. return;
  291. }
  292. const formData = new FormData(document.getElementById('search-form'));
  293. const searchParams = new URLSearchParams(formData).toString();
  294. window.location.href = `/search_results?${searchParams}`;
  295. }
  296. function showNewRecordForm() {
  297. document.getElementById('new-record-table').style.display = 'block';
  298. }
  299. function saveNewRecord() {
  300. const record = {};
  301. {% for field in field_names %}
  302. record['{{ field }}'] = document.getElementById('new-{{ field }}').value;
  303. {% endfor %}
  304. fetch('/save_new_record', {
  305. method: 'POST',
  306. headers: {
  307. 'Content-Type': 'application/json'
  308. },
  309. body: JSON.stringify({
  310. database: '{{ database }}',
  311. table: '{{ selected_table }}',
  312. record: record
  313. })
  314. })
  315. .then(response => response.json())
  316. .then(data => {
  317. if (data.success) {
  318. alert('数据保存成功');
  319. window.location.href = `/database_home?table={{ selected_table }}`;
  320. } else {
  321. alert('数据保存失败,请检查填写的数据格式或关键字错误');
  322. }
  323. });
  324. }
  325. function goBack() {
  326. window.location.href = '/home';
  327. }
  328. function toggleNewRecordForm() {
  329. button_new_record_activate = !button_new_record_activate;
  330. document.getElementById('new-record-table').style.display = button_new_record_activate ? 'block' : 'none';
  331. document.getElementById('toggle-text').innerText = button_new_record_activate ? '收起添加记录明细' : '添加记录';
  332. }
  333. </script>
  334. </body>
  335. </html>
  1. ##############################index.html#################################
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>数据库选择</title>
  8. <style>
  9. body {
  10. display: flex;
  11. justify-content: center;
  12. align-items: center;
  13. height: 100vh;
  14. margin: 0;
  15. background-image: url('/static/background.jpg');
  16. background-size: cover;
  17. background-position: center;
  18. background-repeat: no-repeat;
  19. }
  20. .container {
  21. background-color: rgba(255, 255, 255, 0.8);
  22. padding: 20px;
  23. border-radius: 10px;
  24. box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  25. margin: 20px;
  26. width: 50%;
  27. /* 设置容器的宽度为页面宽度的 80% */
  28. }
  29. form {
  30. display: inline-block;
  31. text-align: left;
  32. width: 100%;
  33. }
  34. label {
  35. display: block;
  36. margin-bottom: 5px;
  37. font-weight: bold;
  38. }
  39. input[type="text"],
  40. input[type="password"],
  41. select {
  42. width: 100%;
  43. padding: 10px;
  44. margin-bottom: 20px;
  45. box-sizing: border-box;
  46. border: 1px solid #ccc;
  47. border-radius: 5px;
  48. background-color: #f8f8f8;
  49. font-size: 16px;
  50. outline: none;
  51. }
  52. .button-container {
  53. display: flex;
  54. justify-content: space-between;
  55. }
  56. button[type="submit"],
  57. .logout-button {
  58. padding: 10px 40px;
  59. cursor: pointer;
  60. border: none;
  61. border-radius: 5px;
  62. font-size: 16px;
  63. outline: none;
  64. transition: background-color 0.3s ease;
  65. width: 48%;
  66. /* 设置按钮宽度为48% */
  67. text-align: center;
  68. }
  69. button[type="submit"] {
  70. background-color: #007bff;
  71. color: #fff;
  72. }
  73. button[type="submit"]:hover {
  74. background-color: #0056b3;
  75. }
  76. .logout-button {
  77. background-color: #dc3545;
  78. color: #fff;
  79. text-decoration: none;
  80. display: inline-block;
  81. line-height: 1.5;
  82. }
  83. .logout-button:hover {
  84. background-color: #c82333;
  85. }
  86. h2 {
  87. margin-bottom: 10px;
  88. color: white;
  89. }
  90. h4 {
  91. margin-bottom: 20px;
  92. font-size: 14px;
  93. text-align: right;
  94. color: white;
  95. }
  96. .footer {
  97. position: fixed;
  98. bottom: 0;
  99. width: 100%;
  100. background-color: #d5dee7;
  101. padding: 10px 0;
  102. text-align: center;
  103. font-size: 14px;
  104. color: #6c757d;
  105. }
  106. </style>
  107. </head>
  108. <body>
  109. <div id="user-info"
  110. style="position: absolute; top: 10px; right: 10px; padding: 10px; background-color: #3ec83e; border: 1px solid #007bff; border-radius: 5px;">
  111. <span style="color: #0b0808; font-weight: bold;">你好!{{ session['username'] }}</span>
  112. </div>
  113. <div class="container">
  114. <h2>数据库信息管理系统</h2>
  115. <h4>——buid by
    声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/828860
    推荐阅读
    相关标签