feat: 优化服务管理脚本 - 修复硬编码路径、中文乱码和依赖等待逻辑

- 修复 Windows 控制台中文编码乱码
- 新增 ExecutableFinder 动态查找 Node/Maven/npm 可执行文件路径
- 重构 ProcessManager.start 使用动态路径替代硬编码
- 修复 _start_all 依赖等待逻辑,避免误判未就绪服务
- restart 命令支持 all 参数(默认重启所有服务)
- clean 命令增强:Node 清理 node_modules/dist/.vite,Java 清理 target
- PID 严格验证:检查进程 cwd 是否匹配服务目录
- 进度条显示稳定:百分比变化 >= 10% 才刷新
- mini-program 补充 log_file 配置

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-26 12:52:58 +08:00
parent 646ab3d300
commit 86af064ca3
4 changed files with 1121 additions and 0 deletions
+121
View File
@@ -0,0 +1,121 @@
"""
情绪博物馆 - 服务管理器 CLI 入口
Emotion Museum - Service Manager CLI Entry Point
用法:
python manage.py start [service|all] # 启动服务
python manage.py stop [service|all] # 停止服务
python manage.py restart service # 重启服务
python manage.py status # 查看状态
python manage.py logs service [--follow] [--lines N] # 查看日志
python manage.py info # 显示访问地址
python manage.py clean service # 清理构建产物
python manage.py setup service # 安装依赖
"""
import sys
import io
import argparse
from pathlib import Path
# Fix Windows console Chinese character encoding
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
from tools.service_manager import ServiceManager, PROJECT_ROOT
def main():
parser = argparse.ArgumentParser(
description="情绪博物馆 - 服务管理器",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
示例:
python manage.py start 启动所有服务
python manage.py start backend 启动后端服务
python manage.py stop 停止所有服务
python manage.py stop web 停止用户前端
python manage.py restart web 重启用户前端
python manage.py status 查看所有服务状态
python manage.py logs backend --follow 实时查看后端日志
python manage.py logs web --lines 100 查看前端最近 100 行日志
python manage.py info 显示所有服务访问地址
python manage.py clean web 清理前端 node_modules
python manage.py setup web 安装前端依赖
""",
)
subparsers = parser.add_subparsers(dest="command", help="可用命令")
# start 命令
start_parser = subparsers.add_parser("start", help="启动服务")
start_parser.add_argument(
"service", nargs="?", default="all", help="服务名称 (默认: all)"
)
start_parser.add_argument(
"--skip-deps", action="store_true", help="跳过依赖检查和安装"
)
# stop 命令
stop_parser = subparsers.add_parser("stop", help="停止服务")
stop_parser.add_argument(
"service", nargs="?", default="all", help="服务名称 (默认: all)"
)
# restart 命令
restart_parser = subparsers.add_parser("restart", help="重启服务")
restart_parser.add_argument("service", nargs="?", default=None, help="服务名称 (不填则重启所有服务)")
# status 命令
subparsers.add_parser("status", help="查看所有服务状态")
# logs 命令
logs_parser = subparsers.add_parser("logs", help="查看服务日志")
logs_parser.add_argument("service", help="服务名称 (必填)")
logs_parser.add_argument("--follow", "-f", action="store_true", help="实时跟踪日志")
logs_parser.add_argument(
"--lines", "-n", type=int, default=50, help="显示行数 (默认: 50)"
)
# info 命令
subparsers.add_parser("info", help="显示服务访问地址")
# clean 命令
clean_parser = subparsers.add_parser("clean", help="清理构建产物")
clean_parser.add_argument("service", help="服务名称 (必填)")
# setup 命令
setup_parser = subparsers.add_parser("setup", help="安装依赖")
setup_parser.add_argument("service", help="服务名称 (必填)")
args = parser.parse_args()
if not args.command:
parser.print_help()
sys.exit(0)
# 加载配置
config_path = PROJECT_ROOT / "manage.conf.yaml"
manager = ServiceManager(config_path)
# 执行命令
if args.command == "start":
manager.start(args.service, skip_deps=getattr(args, "skip_deps", False))
elif args.command == "stop":
manager.stop(args.service)
elif args.command == "restart":
manager.restart(args.service or "all")
elif args.command == "status":
manager.status()
elif args.command == "logs":
manager.logs(args.service, lines=args.lines, follow=args.follow)
elif args.command == "info":
manager.info()
elif args.command == "clean":
manager.clean(args.service)
elif args.command == "setup":
manager.setup(args.service)
if __name__ == "__main__":
main()