feat: 更新项目服务、工具函数和模板

This commit is contained in:
2026-06-25 12:11:16 +08:00
parent 0c54af8d26
commit a155e8fcd9
13 changed files with 446601 additions and 100 deletions

View File

@@ -68,9 +68,11 @@ def register_project_routes(app):
if project.get('start_cmds'):
for name, info in project['start_cmds'].items():
log_message(f"[API-START] 项目={project_id} 命令={info['cmd']} 目录={cwd}")
run_command(info['cmd'], cwd, project_id, f'start-{name}')
else:
cmd = project.get('start_cmd', 'python3 app.py')
log_message(f"[API-START] 项目={project_id} 命令={cmd} 目录={cwd}")
run_command(cmd, cwd, project_id, 'start')
return jsonify({'message': '服务启动中...'})
@@ -128,7 +130,9 @@ def register_project_routes(app):
'directory': data.get('directory', ''),
'start_cmd': data.get('start_cmd', ''),
'stop_cmd': data.get('stop_cmd', ''),
'log_file': data.get('log_file', ''),
'health_url': data.get('health_url', ''),
'admin_url': data.get('admin_url', ''),
'description': data.get('description', ''),
'git_repo': data.get('git_repo', ''),
'version': data.get('version', 'v1.0.0')
@@ -152,7 +156,7 @@ def register_project_routes(app):
return jsonify({'error': '项目不存在'}), 404
# 更新字段
for key in ['name', 'ports', 'directory', 'start_cmd', 'stop_cmd', 'health_url', 'description', 'git_repo', 'version']:
for key in ['name', 'ports', 'directory', 'log_file', 'start_cmd', 'stop_cmd', 'health_url', 'admin_url', 'description', 'git_repo', 'version']:
if key in data:
project[key] = data[key]
@@ -162,6 +166,55 @@ def register_project_routes(app):
return jsonify({'message': '项目更新成功'})
@app.route('/api/projects/<project_id>/log')
def api_project_log(project_id):
"""获取项目日志"""
projects = load_projects()
project = next((p for p in projects if p['id'] == project_id), None)
if not project:
return jsonify({'error': '项目不存在'}), 404
lines = request.args.get('lines', 200, type=int)
lines = max(1, min(lines, 5000)) # 限制 1-5000 行
log_file = project.get('log_file', '')
if not log_file:
# 默认:项目目录下的 logs/app.log
cwd = project.get('directory', '')
if cwd:
from config import WORKSPACE_DIR
import os
abs_dir = cwd if cwd.startswith('/') else os.path.join(WORKSPACE_DIR, cwd)
log_file = os.path.join(abs_dir, 'logs', 'app.log')
# 支持相对路径和绝对路径
import os
if not log_file.startswith('/'):
cwd = project.get('directory', '')
if cwd:
from config import WORKSPACE_DIR
abs_dir = cwd if cwd.startswith('/') else os.path.join(WORKSPACE_DIR, cwd)
log_file = os.path.join(abs_dir, log_file)
if not os.path.exists(log_file):
return jsonify({'log': f'日志文件不存在: {log_file}'})
try:
# 读取最后 N 行(高效方式)
with open(log_file, 'r', encoding='utf-8', errors='replace') as f:
all_lines = f.readlines()
tail_lines = all_lines[-lines:] if len(all_lines) > lines else all_lines
content = ''.join(tail_lines)
return jsonify({
'log': content if content else '(日志为空)',
'file': log_file,
'total_lines': len(all_lines),
'shown_lines': len(tail_lines)
})
except Exception as e:
return jsonify({'error': f'读取日志失败: {str(e)}'}), 500
@app.route('/api/projects/<project_id>', methods=['DELETE'])
def api_delete_project(project_id):
"""删除项目"""