-
有时在无界面linux环境上需要进行界面性操作,通常需要借助qt之类的,但需要涉及到x11协议,需要安装很多库,很繁琐,只需要在机器上提供服务端,使用浏览器进行访问服务端
-
浏览器访问url:http://192.168.174.198:5000
-
templates/index.html
<!DOCTYPE html> <html> <head> <title>配置管理系统</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Segoe UI', Arial, sans-serif; background: #1a1a1a; color: #e0e0e0; padding: 20px; min-height: 100vh; } h1 { color: #ffffff; margin-bottom: 20px; font-size: 24px; border-bottom: 1px solid #333; padding-bottom: 10px; } .container { display: flex; gap: 20px; height: 75vh; } /* 左侧面板 */ .left-panel { width: 30%; background: #2d2d2d; border-radius: 8px; padding: 15px; display: flex; flex-direction: column; } #search { width: 100%; padding: 10px; background: #3a3a3a; border: 1px solid #555; border-radius: 4px; color: white; margin-bottom: 15px; } #search::placeholder { color: #888; } #config-list { list-style: none; overflow-y: auto; flex-grow: 1; } #config-list li { padding: 12px; margin: 5px 0; background: #3a3a3a; border-radius: 4px; cursor: pointer; transition: background 0.3s; } #config-list li:hover { background: #4a4a4a; } /* 右侧面板 */ .right-panel { width: 70%; display: flex; flex-direction: column; gap: 15px; } .editor-section, .response-section { background: #2d2d2d; border-radius: 8px; padding: 15px; flex: 1; display: flex; flex-direction: column; } .section-title { color: #ccc; margin-bottom: 10px; font-size: 14px; } #json-editor, #response-content { flex-grow: 1; background: #3a3a3a; border: 1px solid #555; border-radius: 4px; padding: 12px; color: #e0e0e0; font-family: 'Consolas', monospace; font-size: 14px; resize: none; min-height: 200px; } .button-group { margin-top: 10px; } button { padding: 10px 20px; background: #007acc; border: none; border-radius: 4px; color: white; cursor: pointer; margin-right: 10px; transition: background 0.3s; } button:hover { background: #005a9e; } button:last-child { background: #555; } button:last-child:hover { background: #666; } </style> </head> <body> <h1>配置管理系统</h1> <div class="container"> <!-- 左侧:搜索和配置列表 --> <div class="left-panel"> <input type="text" id="search" placeholder="搜索配置..." onkeyup="filterConfigs()"> <ul id="config-list"> {% for config in configs %} <li onclick="loadConfig('{{ config }}')">{{ config }}</li> {% endfor %} </ul> </div> <!-- 右侧:编辑器和应答区域 --> <div class="right-panel"> <div class="editor-section"> <div class="section-title">配置编辑器</div> <textarea id="json-editor" placeholder='{"example": "value"}'>{ "name": "默认配置", "timeout": 30, "retries": 3 }</textarea> <div class="button-group"> <button onclick="sendConfig()">Send</button> <button onclick="formatJSON()">格式化</button> </div> </div> <div class="response-section"> <div class="section-title">应答结果</div> <div id="response-content">应答结果将显示在这里...</div> </div> </div> </div> <script> // 加载配置到编辑器 function loadConfig(configName) { fetch(`/get_config/${configName}`) .then(response => response.json()) .then(data => { document.getElementById('json-editor').value = JSON.stringify(data, null, 2); }) .catch(error => { console.error('Error loading config:', error); }); } // 发送配置到服务器 function sendConfig() { const jsonText = document.getElementById('json-editor').value; try { const jsonData = JSON.parse(jsonText); fetch('/send_config', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(jsonData) }) .then(response => response.json()) .then(data => { document.getElementById('response-content').textContent = JSON.stringify(data, null, 2); }) .catch(error => { document.getElementById('response-content').textContent = '错误: ' + error.message; }); } catch (error) { alert('JSON格式错误: ' + error.message); } } // 格式化JSON function formatJSON() { const textarea = document.getElementById('json-editor'); try { const jsonObj = JSON.parse(textarea.value); textarea.value = JSON.stringify(jsonObj, null, 2); } catch (error) { alert('无效的JSON格式: ' + error.message); } } // 搜索过滤配置 function filterConfigs() { const searchTerm = document.getElementById('search').value.toLowerCase(); const configItems = document.getElementById('config-list').getElementsByTagName('li'); for (let item of configItems) { const text = item.textContent.toLowerCase(); item.style.display = text.includes(searchTerm) ? 'block' : 'none'; } } // 页面加载时默认加载第一个配置 window.addEventListener('load', function() { const firstConfig = document.querySelector('#config-list li'); if (firstConfig) { loadConfig(firstConfig.textContent); } }); </script> </body> </html> -
flask 服务端代码
from flask import Flask, render_template, request, jsonify import json app = Flask(__name__) # 模拟配置数据 CONFIGS = { "default_config": {"name": "默认配置", "timeout": 30, "retries": 3}, "high_performance": {"name": "高性能配置", "threads": 8, "cache_size": "2GB"}, "debug_mode": {"name": "调试模式", "log_level": "verbose", "trace_enabled": True}, "production": {"name": "生产环境", "security": "high", "backup": True} } @app.route('/') def index(): return render_template('index.html', configs=CONFIGS.keys()) @app.route('/get_config/<name>') def get_config(name): return jsonify(CONFIGS.get(name, {})) @app.route('/send_config', methods=['POST']) def send_config(): data = request.json # 模拟处理逻辑 return jsonify({ "status": "success", "message": "配置已提交", "received_data": data }) if __name__ == '__main__': app.run(host="192.168.174.198", port=5000, debug=True)

被折叠的 条评论
为什么被折叠?



