From 149d811164fb533ae1aabfa4732fe9d5e3817c82 Mon Sep 17 00:00:00 2001 From: jingrow Date: Tue, 28 Oct 2025 22:45:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=89=E8=A3=85app=E6=97=B6=E5=90=8C?= =?UTF-8?q?=E6=97=B6=E5=88=9B=E5=BB=BA=E5=90=8C=E5=90=8D=E7=9A=84package?= =?UTF-8?q?=E5=92=8Cmodule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jingrow/api/local_app_installer.py | 18 ++++- apps/jingrow/jingrow/utils/app_installer.py | 65 +++++++++++++++++++ 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/apps/jingrow/jingrow/api/local_app_installer.py b/apps/jingrow/jingrow/api/local_app_installer.py index 9bd1f7f..bf80a67 100644 --- a/apps/jingrow/jingrow/api/local_app_installer.py +++ b/apps/jingrow/jingrow/api/local_app_installer.py @@ -15,7 +15,7 @@ import json import shutil import re -from jingrow.utils.app_installer import install_app, get_installed_apps as get_apps, get_app_directories +from jingrow.utils.app_installer import install_app, get_installed_apps as get_apps, get_app_directories, ensure_package_and_module from jingrow.utils.jingrow_api import get_jingrow_api_headers from jingrow.utils.auth import get_jingrow_cloud_url, get_jingrow_cloud_api_headers, get_jingrow_cloud_api_url, get_jingrow_api_headers from jingrow.config import Config @@ -148,7 +148,10 @@ async def install_app_from_upload( # 更新数据库 await _update_local_installed_apps(apps_list) - + + # 额外:确保创建 Package 与 Module Def(custom)记录(上传安装) + ensure_package_and_module(app_name_result) + # 2. 调用 sync_app_files 同步文件到数据库 if app_dir: current = Path(__file__).resolve() @@ -391,6 +394,9 @@ async def install_local_app(request: Request, app_name: str): apps_list.append(new_app) if await _update_local_installed_apps(apps_list): + # 确保创建 Package 与 Module Def(custom)记录(本地扫描安装) + ensure_package_and_module(app_name) + try: api_url = f"{Config.jingrow_server_url}/api/action/jingrow.ai.utils.jlocal.sync_app_files" requests.post( @@ -599,6 +605,9 @@ async def install_from_git(repo_url: str = Form(...)): # 同步文件到数据库 _import_app_package_and_pagetypes(app_name, {'app_name': app_name, 'backend_result': backend_result, 'frontend_result': frontend_result}) + + # 确保创建 Package 与 Module Def(custom)记录 + ensure_package_and_module(app_name) except Exception as e: logger.error(f"Failed to register app: {e}") @@ -688,7 +697,10 @@ async def install_from_url(url: str = Form(...)): # 更新数据库 await _update_local_installed_apps(apps_list) - + + # 额外:确保创建 Package 与 Module Def(custom)记录(URL安装) + ensure_package_and_module(app_name_result) + # 2. 调用 sync_app_files 同步文件到数据库 if app_dir: current = Path(__file__).resolve() diff --git a/apps/jingrow/jingrow/utils/app_installer.py b/apps/jingrow/jingrow/utils/app_installer.py index 5d64d35..f6b9285 100644 --- a/apps/jingrow/jingrow/utils/app_installer.py +++ b/apps/jingrow/jingrow/utils/app_installer.py @@ -17,6 +17,7 @@ import logging from jingrow.config import Config from jingrow.utils.jingrow_api import get_jingrow_api_headers +from jingrow.utils.jingrow_api import get_record_id, create_record logger = logging.getLogger(__name__) @@ -377,6 +378,13 @@ def install_app(uploaded_file_path: str, app_name: str = None) -> Dict[str, Any] # 记录安装信息 record_installation(app_name, package_info, uploaded_file_path) + + # 确保创建 Package 与 Module Def(custom)记录 + try: + create_package_and_module(app_name, package_info) + except Exception: + # 忽略该步骤错误,不影响安装完成 + pass # 清理临时文件 cleanup_temp_dir(temp_dir) @@ -444,3 +452,60 @@ def install_package(temp_dir: str, package_info: Dict[str, Any]) -> Dict[str, An shutil.copy2(src, dst) return {'success': True, 'message': '扩展包已安装到 jingrow 应用', 'app_name': app_name} + + +def _safe_bool(value: Any, default: int = 1) -> int: + try: + if isinstance(value, bool): + return 1 if value else 0 + if isinstance(value, (int, float)): + return 1 if value else 0 + if isinstance(value, str): + return 1 if value.strip().lower() in ("1", "true", "yes") else 0 + except Exception: + pass + return default + + +def _sanitize_package_name(name: str) -> str: + """将任意app名称规范化为仅包含小写字母/数字/连字符的package_name。""" + try: + s = str(name or "").lower() + s = s.replace(" ", "-").replace("_", "-") + import re + s = re.sub(r"[^a-z0-9-]", "", s) + s = re.sub(r"-+", "-", s).strip("-") + return s or "package" + except Exception: + return "package" + + +def ensure_package_and_module(app_name: str) -> None: + """ + 创建与 app_name 同名的 Package 记录和 Module Def 记录(custom 类型)。 + 已存在时不会中断安装流程。 + """ + if not app_name: + return + + # 创建 Package 记录(先检查是否已存在) + safe_pkg_name = _sanitize_package_name(app_name) + try: + exists = get_record_id("Package", field="name", value=app_name) + if not exists.get("success"): + create_record("Package", {"name": app_name, "package_name": safe_pkg_name}) + except Exception: + pass + + # 创建 Module Def 记录(custom 类型,先检查是否已存在) + try: + exists = get_record_id("Module Def", field="module_name", value=app_name) + if not exists.get("success"): + create_record("Module Def", { + "module_name": app_name, + "custom": 1, + "package": app_name, + "app_name": "jingrow" + }) + except Exception: + pass