diff --git a/apps/jingrow/frontend/src/views/dev/AppDetail.vue b/apps/jingrow/frontend/src/views/dev/AppDetail.vue index 63e1713..95ae16d 100644 --- a/apps/jingrow/frontend/src/views/dev/AppDetail.vue +++ b/apps/jingrow/frontend/src/views/dev/AppDetail.vue @@ -278,8 +278,7 @@ async function performInstall() { installMessage.value = t('正在安装应用...') const params = new URLSearchParams({ - repo_url: app.value.repository_url, - branch: app.value.branch || 'main' + repo_url: app.value.repository_url }) response = await axios.post('/jingrow/install-from-git', params, { diff --git a/apps/jingrow/frontend/src/views/dev/AppMarketplace.vue b/apps/jingrow/frontend/src/views/dev/AppMarketplace.vue index 9409901..5bca2c9 100644 --- a/apps/jingrow/frontend/src/views/dev/AppMarketplace.vue +++ b/apps/jingrow/frontend/src/views/dev/AppMarketplace.vue @@ -316,8 +316,7 @@ async function performInstall(app: any) { installMessage.value = t('正在安装应用...') const params = new URLSearchParams({ - repo_url: app.repository_url, - branch: app.branch || 'main' + repo_url: app.repository_url }) response = await axios.post('/jingrow/install-from-git', params, { diff --git a/apps/jingrow/jingrow/api/local_app_installer.py b/apps/jingrow/jingrow/api/local_app_installer.py index b488c93..154ef6e 100644 --- a/apps/jingrow/jingrow/api/local_app_installer.py +++ b/apps/jingrow/jingrow/api/local_app_installer.py @@ -503,7 +503,7 @@ async def get_installed_apps(request: Request): @router.post("/jingrow/install-from-git") -async def install_from_git(repo_url: str = Form(...), branch: str = Form('main')): +async def install_from_git(repo_url: str = Form(...)): """从 git 仓库克隆并安装应用或扩展包""" import subprocess @@ -516,9 +516,9 @@ async def install_from_git(repo_url: str = Form(...), branch: str = Form('main') clone_dir = tmp_dir / f"git_clone_{uuid.uuid4().hex[:8]}" try: - # 使用 git clone 克隆仓库 + # 使用 git clone 克隆仓库(使用仓库默认分支) result = subprocess.run( - ['git', 'clone', '-b', branch, repo_url, str(clone_dir)], + ['git', 'clone', repo_url, str(clone_dir)], capture_output=True, text=True, timeout=300 @@ -529,75 +529,85 @@ async def install_from_git(repo_url: str = Form(...), branch: str = Form('main') raise HTTPException(status_code=400, detail=f"Git 克隆失败: {result.stderr}") # 直接使用克隆的目录进行分析和安装 - from jingrow.utils.app_installer import analyze_package, install_files, is_app_installed + from jingrow.utils.app_installer import analyze_package, install_files, is_app_installed, install_package # 分析包结构 package_info = analyze_package(str(clone_dir)) if not package_info.get('success'): raise HTTPException(status_code=400, detail=package_info.get('error', '无法识别应用')) + has_hooks = package_info['data'].get('has_hooks', False) app_name = package_info['data'].get('app_name') + if not app_name: raise HTTPException(status_code=400, detail='无法识别应用名称') - # 如果应用已安装,先删除旧版本 - if is_app_installed(app_name): - apps_dir, _ = get_app_directories() - app_dir = apps_dir / app_name - if app_dir.exists(): - shutil.rmtree(app_dir) - - # 安装后端文件 - backend_result = None - if package_info['data'].get('has_backend'): - backend_result = install_files(str(clone_dir), app_name, package_info['data'], is_backend=True) - if not backend_result.get('success'): - raise HTTPException(status_code=400, detail=backend_result.get('error')) - - # 安装前端文件 - frontend_result = None - if package_info['data'].get('has_frontend'): - frontend_result = install_files(str(clone_dir), app_name, package_info['data'], is_backend=False) - if not frontend_result.get('success'): - raise HTTPException(status_code=400, detail=frontend_result.get('error')) - - # 清理临时文件 - shutil.rmtree(clone_dir, ignore_errors=True) - - # 只有独立应用才需要注册到 Local Installed Apps - app_dir = backend_result.get('app_dir') if backend_result else None - - if app_dir: - try: - from jingrow.utils.jingrow_api import get_single_pagetype - pagetype_result = get_single_pagetype("Local Installed Apps") - apps_list = pagetype_result.get('config', {}).get('local_installed_apps', []) if pagetype_result.get('success') else [] - - app_exists = False - for app in apps_list: - if app.get('app_name', '') == app_name: - app.update({'app_version': '1.0.0', 'git_branch': branch, 'git_repo': repo_url}) - app_exists = True - break - - if not app_exists: - apps_list.append({'app_name': app_name, 'app_version': '1.0.0', 'git_branch': branch, 'git_repo': repo_url}) - - await _update_local_installed_apps(apps_list) - - # 同步文件到数据库 - _import_app_package_and_pagetypes(app_name, {'app_name': app_name, 'backend_result': backend_result, 'frontend_result': frontend_result}) - except Exception as e: - logger.error(f"Failed to register app: {e}") - - return { - 'success': True, - 'message': f'应用 {app_name} 安装成功', - 'app_name': app_name, - 'package_info': package_info['data'], - 'backend_result': backend_result, - 'frontend_result': frontend_result - } + # 判断是扩展包还是独立应用 + if not has_hooks: + # 作为扩展包安装到 jingrow 应用内部 + result = install_package(str(clone_dir), package_info['data']) + shutil.rmtree(clone_dir, ignore_errors=True) + return result + else: + # 独立应用安装 + # 如果应用已安装,先删除旧版本 + if is_app_installed(app_name): + apps_dir, _ = get_app_directories() + app_dir = apps_dir / app_name + if app_dir.exists(): + shutil.rmtree(app_dir) + + # 安装后端文件 + backend_result = None + if package_info['data'].get('has_backend'): + backend_result = install_files(str(clone_dir), app_name, package_info['data'], is_backend=True) + if not backend_result.get('success'): + raise HTTPException(status_code=400, detail=backend_result.get('error')) + + # 安装前端文件 + frontend_result = None + if package_info['data'].get('has_frontend'): + frontend_result = install_files(str(clone_dir), app_name, package_info['data'], is_backend=False) + if not frontend_result.get('success'): + raise HTTPException(status_code=400, detail=frontend_result.get('error')) + + # 清理临时文件 + shutil.rmtree(clone_dir, ignore_errors=True) + + # 只有独立应用才需要注册到 Local Installed Apps + app_dir = backend_result.get('app_dir') if backend_result else None + + if app_dir: + try: + from jingrow.utils.jingrow_api import get_single_pagetype + pagetype_result = get_single_pagetype("Local Installed Apps") + apps_list = pagetype_result.get('config', {}).get('local_installed_apps', []) if pagetype_result.get('success') else [] + + app_exists = False + for app in apps_list: + if app.get('app_name', '') == app_name: + app.update({'app_version': '1.0.0', 'git_repo': repo_url}) + app_exists = True + break + + if not app_exists: + apps_list.append({'app_name': app_name, 'app_version': '1.0.0', 'git_repo': repo_url}) + + await _update_local_installed_apps(apps_list) + + # 同步文件到数据库 + _import_app_package_and_pagetypes(app_name, {'app_name': app_name, 'backend_result': backend_result, 'frontend_result': frontend_result}) + except Exception as e: + logger.error(f"Failed to register app: {e}") + + return { + 'success': True, + 'message': f'应用 {app_name} 安装成功', + 'app_name': app_name, + 'package_info': package_info['data'], + 'backend_result': backend_result, + 'frontend_result': frontend_result + } except subprocess.TimeoutExpired: if clone_dir.exists():