Compare commits

...

8 Commits

Author SHA1 Message Date
bb19141edc fix: 修复Web服务监控区域状态显示问题
后端 status 字段从字符串改为结构化对象 {status, ports: {port: {running}}}
前端期望的是 p.status.status 和 p.status.ports[port].running,之前的字符串格式导致:
- 所有服务状态始终显示「未知」
- 所有端口始终显示红色(已停止)
2026-06-01 17:08:09 +08:00
c960048042 fix: 重写routes_system.py修复API错误
完整重写系统监控API,确保:
- 正确的数据结构匹配JavaScript期待
- system.uptime/system.boot_time/system.process_count
- cpu.count/cpu.logical
- disk.free_gb
- network.sent_mb/recv_mb/sent_speed/recv_speed
- 所有异常处理和日志记录

修复500错误,现在系统监控应该正常显示
2026-06-01 16:19:59 +08:00
51f7ee9ad0 fix: 修正系统监控API返回数据结构
匹配JavaScript期待的数据结构:
- system.uptime(系统运行时间)
- system.boot_time(启动时间)
- system.process_count(进程数)
- cpu.count/cpu.logical(CPU核心数)
- disk.free_gb(磁盘剩余空间)
- network.sent_mb/recv_mb(累计流量)
- network.sent_speed/recv_speed(实时网速)

确保前端能正确显示所有系统资源信息
2026-06-01 16:17:47 +08:00
ea904fb2b2 fix: 清理templates_full.txt开头的Python代码
移除模板文件开头的Python代码片段:
- '# ==================== HTML 模板 ===================='
- 'HTML_TEMPLATE = '''

确保templates_full.txt是纯粹的HTML模板,从<!DOCTYPE html>开始

这是导致浏览器console报错的根本原因:
- Python代码片段会被浏览器当作JavaScript解析
- 导致JavaScript执行失败,函数未定义
- closeEmailRuleModal等函数无法正常工作
2026-06-01 16:12:37 +08:00
21240dc108 fix: 替换模板中的默认IP地址为121.40.164.32
修复JavaScript代码中的默认IP值:
- localStorage.getItem('externalIp') || '192.168.2.17'
- 改为:|| '121.40.164.32'

确保所有默认值统一为正确的对外IP地址
2026-06-01 16:11:19 +08:00
1d7f4c2bed fix: 清理模板文件末尾的多余代码
移除 templates_full.txt 末尾不应该存在的Python代码片段:
- 移除 ''' 字符串结束标记
- 移除 if __name__ == '__main__' 部分
- 确保HTML模板在 </html> 处正确结束

这个问题可能导致页面加载异常
2026-06-01 16:02:59 +08:00
88c11277cf fix: 修正版本号为 v3.4.1 2026-06-01 15:56:47 +08:00
e5ae822ed2 docs: 更新版本号为 v3.4.1 2026-06-01 15:55:19 +08:00
10 changed files with 85 additions and 33 deletions

View File

@@ -4,7 +4,7 @@
## 版本信息
- **当前版本**: v3.4.0
- **当前版本**: v3.4.1
- **端口**: 16022
- **更新日期**: 2026-06-01
@@ -158,7 +158,13 @@ python3 app_main.py
## 更新日志
### v3.4.0 (2026-06-01)
### v3.4.1 (2026-06-01)
- 🎯 **模块化重构**: 将 3700+ 行单文件拆分为多个模块
- 📁 **清晰结构**: config、database、utils、routes、templates 分离
- 🔧 **易于维护**: 每个模块职责明确,便于扩展和维护
-**功能完整**: 保留所有原有网页功能
### v3.4.0 (2026-06-01) [已废弃]
- 🎯 **模块化重构**: 将 3700+ 行单文件拆分为多个模块
- 📁 **清晰结构**: config、database、utils、routes、templates 分离
- 🔧 **易于维护**: 每个模块职责明确,便于扩展和维护

Binary file not shown.

Binary file not shown.

View File

@@ -20,7 +20,7 @@ ALERT_CONFIG_FILE = 'alert_config.json'
# 应用配置
APP_NAME = "项目服务管理面板"
APP_VERSION = "v3.4.0"
APP_VERSION = "v3.4.1"
APP_PORT = 16022
# 监控配置

View File

@@ -30317,3 +30317,17 @@ Press CTRL+C to quit
[2026-06-01 12:30:38] ⚠️ 进程收到 SIGTERM 信号,即将退出!
[2026-06-01 12:31:16] 项目服务管理面板 v3.4.0 初始化完成
[2026-06-01 12:31:16] 启动 项目服务管理面板,端口: 16022
[2026-06-01 15:53:53] 项目服务管理面板 v3.4.0 初始化完成
[2026-06-01 15:53:53] 启动 项目服务管理面板,端口: 16022
[2026-06-01 15:55:35] 项目服务管理面板 v3.4.0 初始化完成
[2026-06-01 15:55:35] 启动 项目服务管理面板,端口: 16022
[2026-06-01 15:56:16] 项目服务管理面板 v3.4.0 初始化完成
[2026-06-01 15:56:16] 启动 项目服务管理面板,端口: 16022
[2026-06-01 15:57:03] 项目服务管理面板 v3.4.1 初始化完成
[2026-06-01 15:57:03] 启动 项目服务管理面板,端口: 16022
[2026-06-01 16:02:13] 项目服务管理面板 v3.4.1 初始化完成
[2026-06-01 16:02:13] 启动 项目服务管理面板,端口: 16022
[2026-06-01 16:02:39] 项目服务管理面板 v3.4.1 初始化完成
[2026-06-01 16:02:39] 启动 项目服务管理面板,端口: 16022
[2026-06-01 16:10:23] 项目服务管理面板 v3.4.1 初始化完成
[2026-06-01 16:10:23] 启动 项目服务管理面板,端口: 16022

View File

@@ -20,10 +20,25 @@ def register_project_routes(app):
"""获取项目列表"""
projects = load_projects()
# 添加状态信息
# 添加状态信息(结构化对象,前端期望 status.status 和 status.ports
for project in projects:
ports = project.get('ports', [])
project['status'] = 'running' if all(check_port(p) for p in ports) else 'stopped'
port_statuses = {}
for p in ports:
port_statuses[str(p)] = {'running': check_port(p)}
running_count = sum(1 for ps in port_statuses.values() if ps['running'])
if running_count == len(ports) and len(ports) > 0:
overall = 'running'
elif running_count > 0:
overall = 'partial'
else:
overall = 'stopped'
project['status'] = {
'status': overall,
'ports': port_statuses
}
return jsonify({
'projects': projects,
@@ -169,10 +184,25 @@ def register_project_routes(app):
data = load_projects_full()
services = data.get('external_services', [])
# 添加状态
# 添加状态(结构化对象,前端期望 status.status 和 status.ports
for service in services:
ports = service.get('ports', [])
service['status'] = 'running' if all(check_port(p) for p in ports) else 'stopped'
port_statuses = {}
for p in ports:
port_statuses[str(p)] = {'running': check_port(p)}
running_count = sum(1 for ps in port_statuses.values() if ps['running'])
if running_count == len(ports) and len(ports) > 0:
overall = 'running'
elif running_count > 0:
overall = 'partial'
else:
overall = 'stopped'
service['status'] = {
'status': overall,
'ports': port_statuses
}
return jsonify({'services': services})

View File

@@ -6,7 +6,8 @@
import os
import subprocess
import time
from flask import jsonify
from datetime import datetime
from flask import jsonify, request
from utils import log_message, get_cpu_temperatures, load_alert_config
try:
@@ -46,6 +47,7 @@ def register_system_routes(app):
disk = psutil.disk_usage('/')
disk_total_gb = round(disk.total / (1024**3), 2)
disk_used_gb = round(disk.used / (1024**3), 2)
disk_free_gb = round(disk.free / (1024**3), 2)
disk_percent = disk.percent
# 网速(需要计算差值)
@@ -82,10 +84,15 @@ def register_system_routes(app):
return jsonify({
'available': True,
'system': {
'uptime': uptime_str,
'boot_time': datetime.fromtimestamp(boot_time).strftime('%Y-%m-%d %H:%M:%S'),
'process_count': process_count
},
'cpu': {
'percent': cpu_percent,
'count_physical': cpu_count,
'count_logical': cpu_count_logical,
'count': cpu_count,
'logical': cpu_count_logical,
'temp_package_0': cpu_temps.get('package_0'),
'temp_package_1': cpu_temps.get('package_1')
},
@@ -98,17 +105,19 @@ def register_system_routes(app):
'disk': {
'total_gb': disk_total_gb,
'used_gb': disk_used_gb,
'free_gb': disk_free_gb,
'percent': disk_percent
},
'network': {
'upload_speed_kb': round(upload_speed, 2),
'download_speed_kb': round(download_speed, 2)
},
'process_count': process_count,
'uptime': uptime_str
'sent_mb': round(net.bytes_sent / (1024**2), 2),
'recv_mb': round(net.bytes_recv / (1024**2), 2),
'sent_speed': round(upload_speed, 2),
'recv_speed': round(download_speed, 2)
}
})
except Exception as e:
return jsonify({'error': str(e)}), 500
log_message(f"系统监控API错误: {e}")
return jsonify({'error': str(e), 'available': False}), 500
@app.route('/api/system/processes')
def api_system_processes():
@@ -117,6 +126,9 @@ def register_system_routes(app):
return jsonify({'error': 'psutil未安装'}), 500
try:
limit = int(request.args.get('limit', 10))
limit = max(1, min(50, limit))
processes = []
for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent', 'status']):
try:
@@ -132,7 +144,7 @@ def register_system_routes(app):
# 按CPU排序
processes.sort(key=lambda x: x['cpu'], reverse=True)
processes = processes[:50] # 只返回前50个
processes = processes[:limit]
return jsonify({'processes': processes})
except Exception as e:
@@ -167,7 +179,6 @@ def register_system_routes(app):
@app.route('/api/alerts', methods=['POST'])
def api_save_alerts():
"""保存预警配置"""
from flask import request
import json
from config import ALERT_CONFIG_FILE

View File

@@ -16,9 +16,12 @@ def get_html_template():
with open(template_file, 'r', encoding='utf-8') as f:
template_content = f.read()
# 替换版本号
# 替换版本号(支持多种格式)
template_content = template_content.replace('v2.1', APP_VERSION)
template_content = template_content.replace('v3.3.1', APP_VERSION)
template_content = template_content.replace('v3.3.5', APP_VERSION)
template_content = template_content.replace('v3.4.0', APP_VERSION)
template_content = template_content.replace('v3.4.1', APP_VERSION) # 预留未来版本
return template_content
except:

View File

@@ -1,6 +1,4 @@
# ==================== HTML 模板 ====================
HTML_TEMPLATE = '''<!DOCTYPE html>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
@@ -2353,14 +2351,4 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
}, 10000);
</script>
</body>
</html>
'''
if __name__ == '__main__':
os.makedirs(os.path.join(BASE_DIR, 'logs'), exist_ok=True)
os.makedirs(CRON_BACKUP_DIR, exist_ok=True)
init_db()
log_message("=" * 50)
log_message("项目服务管理面板 v2.0.0 启动")
</html>