| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- {% extends 'base.html' %}
- {% block title %}{{ title }}{% endblock %}
- {% block content %}
- <div class="container mt-5">
- <h1 class="mb-4">应用管理</h1>
- <!-- 重启应用服务 -->
- <div class="card mb-4">
- <div class="card-header">
- <h2>重启应用服务</h2>
- </div>
- <div class="card-body">
- <p>点击下方按钮重启应用服务。注意:重启过程中服务会暂时不可用。</p>
- <button id="restart-btn" class="btn btn-danger" style="width:100px">重启应用</button>
- <div id="restart-result" class="mt-3"></div>
- </div>
- </div>
- <!-- 更新应用服务 -->
- <div class="card mb-4">
- <div class="card-header">
- <h2>更新应用服务</h2>
- </div>
- <div class="card-body">
- <form id="update-form" enctype="multipart/form-data">
- <div class="form-group">
- <label for="app-file">选择应用服务文件</label>
- <input type="file" class="form-control-file" id="app-file" name="app_file" required>
- <small class="form-text text-muted">请上传只包含Python文件(.py)、HTML文件(.html)或压缩包(.zip)的文件</small>
- </div>
- <button type="submit" class="btn btn-primary">上传更新</button>
- </form>
- <div id="update-result" class="mt-3"></div>
- </div>
- </div>
- <!-- 应用日志查看 -->
- <div class="card">
- <div class="card-header">
- <h2>应用日志查看</h2>
- </div>
- <div class="card-body">
- <div class="form-group log-controls">
- <button id="refresh-logs" class="btn btn-primary" style="width: 120px;">刷新日志</button>
-
- <div class="form-check form-check-inline">
- <input type="checkbox" id="auto-refresh" class="form-check-input">
- <label for="auto-refresh" class="form-check-label">自动刷新</label>
- </div>
-
- <div class="form-group form-inline">
- <label for="log-lines" class="mr-2">显示行数</label>
- <select id="log-lines" class="form-control" style="width:100px;">
- <option value="10">10行</option>
- <option value="50" selected>50行</option>
- <option value="100">100行</option>
- <option value="all">全部</option>
- </select>
- </div>
- </div>
- <div class="mt-3">
- <pre id="app-logs" class="bg-dark text-white p-3 overflow-auto log-container">加载中...</pre>
- </div>
- </div>
- </div>
- </div>
- <style>
- .log-controls {
- display: flex;
- align-items: center;
- gap: 15px;
- flex-wrap: wrap;
- }
- .form-check {
- display: flex;
- align-items: center;
- }
- .form-check-input {
- height: 20px;
- width: 20px;
- margin-right: 5px;
- }
- .form-check-label {
- margin: 0;
- white-space: nowrap;
- }
- .form-inline {
- display: flex;
- align-items: center;
- }
- </style>
- {% endblock %}
- {% block scripts %}
- <script>
- // 重启应用服务
- document.getElementById('restart-btn').addEventListener('click', function() {
- if (confirm('确定要重启应用服务吗?')) {
- const resultDiv = document.getElementById('restart-result');
- resultDiv.innerHTML = '<div class="alert alert-info">正在发送重启请求...</div>';
-
- fetch('/api/restart_app', {
- method: 'POST'
- })
- .then(response => {
- if (!response.ok) {
- throw new Error('网络响应错误');
- }
- return response.json();
- })
- .then(data => {
- resultDiv.innerHTML = '<div class="alert alert-info">' + data.message + '</div>';
-
- // 开始轮询检查服务器是否重启完成
- let pollCount = 0;
- const maxPollCount = 30; // 最多检查30次
- const pollInterval = 2000; // 每2秒检查一次
-
- const pollServer = () => {
- if (pollCount >= maxPollCount) {
- resultDiv.innerHTML = '<div class="alert alert-warning">重启超时,请手动检查服务状态。</div>';
- return;
- }
-
- pollCount++;
-
- // 尝试连接服务器
- fetch('/api/ping', {
- method: 'GET',
- timeout: 1000
- })
- .then(response => {
- if (response.ok) {
- return response.json();
- }
- throw new Error('服务器未就绪');
- })
- .then(pingData => {
- if (pingData.status === 'ok') {
- resultDiv.innerHTML = '<div class="alert alert-success">应用重启成功!</div>';
- // 可选:刷新页面
- /*
- setTimeout(() => {
- location.reload();
- }, 2000);
- */
- return response.json();
- } else {
- setTimeout(pollServer, pollInterval);
- }
- })
- .catch(error => {
- setTimeout(pollServer, pollInterval);
- });
- };
-
- // 启动轮询
- setTimeout(pollServer, 3000); // 延迟3秒后开始轮询,给服务器重启时间
- })
- .catch(error => {
- resultDiv.innerHTML = '<div class="alert alert-danger">重启请求发送失败: ' + error.message + '</div>';
- });
- }
- });
- // 更新应用服务
- document.getElementById('update-form').addEventListener('submit', function(e) {
- e.preventDefault();
- const formData = new FormData(this);
- fetch('/api/update_app', {
- method: 'POST',
- body: formData
- })
- .then(response => response.json())
- .then(data => {
- const resultDiv = document.getElementById('update-result');
- if (data.success) {
- resultDiv.innerHTML = '<div class="alert alert-success">' + data.message + '</div>';
- } else {
- resultDiv.innerHTML = '<div class="alert alert-danger">' + data.message + '</div>';
- }
- })
- .catch(error => {
- document.getElementById('update-result').innerHTML = '<div class="alert alert-danger">更新失败: ' + error + '</div>';
- });
- });
- // 查看应用日志
- function loadLogs() {
- const lines = document.getElementById('log-lines').value;
- fetch(`/api/get_logs?lines=${lines}`)
- .then(response => response.text())
- .then(data => {
- document.getElementById('app-logs').textContent = data;
- })
- .catch(error => {
- document.getElementById('app-logs').textContent = '加载日志失败: ' + error;
- });
- }
- document.getElementById('refresh-logs').addEventListener('click', loadLogs);
- // 页面加载时加载日志
- window.addEventListener('load', loadLogs);
- // 自动刷新相关代码
- let refreshInterval;
- const autoRefreshCheckbox = document.getElementById('auto-refresh');
- // 检查复选框状态并设置定时器
- function updateAutoRefresh() {
- if (autoRefreshCheckbox.checked) {
- if (!refreshInterval) {
- refreshInterval = setInterval(loadLogs, 1000);
- }
- } else {
- if (refreshInterval) {
- clearInterval(refreshInterval);
- refreshInterval = null;
- }
- }
- }
- // 监听复选框状态变化
- autoRefreshCheckbox.addEventListener('change', updateAutoRefresh);
- // 初始检查状态
- updateAutoRefresh();
- </script>
- {% endblock %}
|