From 96adb215e09f057920ebaf20eb3d25c6987a96c8 Mon Sep 17 00:00:00 2001 From: jingrow Date: Sun, 2 Nov 2025 22:21:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=B7=B2=E5=8F=91=E5=B8=83?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E8=8F=9C=E5=8D=95=E6=98=BE=E7=A4=BA=E6=88=91?= =?UTF-8?q?=E5=8F=91=E5=B8=83=E5=88=B0=E5=B8=82=E5=9C=BA=E7=9A=84=E5=BA=94?= =?UTF-8?q?=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jingrow/frontend/src/app/router/index.ts | 6 + apps/jingrow/frontend/src/locales/zh-CN.json | 4 + .../frontend/src/shared/stores/menu.ts | 1 + .../src/views/dev/MyPublishedApps.vue | 578 ++++++++++++++++++ .../jingrow/api/local_app_installer.py | 82 ++- 5 files changed, 670 insertions(+), 1 deletion(-) create mode 100644 apps/jingrow/frontend/src/views/dev/MyPublishedApps.vue diff --git a/apps/jingrow/frontend/src/app/router/index.ts b/apps/jingrow/frontend/src/app/router/index.ts index 814120c..3d43beb 100644 --- a/apps/jingrow/frontend/src/app/router/index.ts +++ b/apps/jingrow/frontend/src/app/router/index.ts @@ -150,6 +150,12 @@ const router = createRouter({ name: 'PublishApp', component: () => import('../../views/dev/PublishApp.vue'), meta: { requiresAuth: true } + }, + { + path: 'my-published-apps', + name: 'MyPublishedApps', + component: () => import('../../views/dev/MyPublishedApps.vue'), + meta: { requiresAuth: true } } ] } diff --git a/apps/jingrow/frontend/src/locales/zh-CN.json b/apps/jingrow/frontend/src/locales/zh-CN.json index a72558e..7b55a02 100644 --- a/apps/jingrow/frontend/src/locales/zh-CN.json +++ b/apps/jingrow/frontend/src/locales/zh-CN.json @@ -946,6 +946,10 @@ "Environment restart request submitted. The system will restart shortly.": "环境重启请求已提交,系统将在稍后重启。", "Failed to restart environment": "重启环境失败", "Publish App": "发布应用", + "My Published Apps": "已发布应用", + "Manage your published applications in the marketplace": "管理您在应用市场中发布的应用", + "View in Marketplace": "在市场查看", + "Publish Your First App": "发布您的第一个应用", "Active": "活跃", "View detailed information about the application": "查看应用的详细信息", "Loading application details...": "正在加载应用详情...", diff --git a/apps/jingrow/frontend/src/shared/stores/menu.ts b/apps/jingrow/frontend/src/shared/stores/menu.ts index fc9ae3c..9dd0869 100644 --- a/apps/jingrow/frontend/src/shared/stores/menu.ts +++ b/apps/jingrow/frontend/src/shared/stores/menu.ts @@ -62,6 +62,7 @@ function getDefaultMenus(): AppMenuItem[] { { id: 'app-installer', key: 'AppInstaller', label: 'App Installer', icon: 'tabler:upload', type: 'route', routeName: 'AppInstaller', parentId: 'dev-group', order: 5 }, { id: 'installed-apps', key: 'InstalledApps', label: 'Installed Apps', icon: 'tabler:apps', type: 'route', routeName: 'InstalledApps', parentId: 'dev-group', order: 6 }, { id: 'app-marketplace', key: 'AppMarketplace', label: 'App Marketplace', icon: 'tabler:shopping-cart', type: 'route', routeName: 'AppMarketplace', parentId: 'dev-group', order: 7 }, + { id: 'my-published-apps', key: 'MyPublishedApps', label: 'My Published Apps', icon: 'tabler:cloud-upload', type: 'route', routeName: 'MyPublishedApps', parentId: 'dev-group', order: 7.5 }, { id: 'node-marketplace', key: 'NodeMarketplace', label: 'Node Marketplace', icon: 'carbon:add-child-node', type: 'route', routeName: 'NodeMarketplace', parentId: 'dev-group', order: 8 }, { id: 'menuManager', key: 'MenuManager', label: 'Menu Management', icon: 'tabler:menu-2', type: 'route', routeName: 'MenuManager', order: 10 }, { id: 'settings', key: 'Settings', label: 'Settings', icon: 'tabler:settings', routeName: 'Settings', order: 11, type: 'route' } diff --git a/apps/jingrow/frontend/src/views/dev/MyPublishedApps.vue b/apps/jingrow/frontend/src/views/dev/MyPublishedApps.vue new file mode 100644 index 0000000..b6ff5a1 --- /dev/null +++ b/apps/jingrow/frontend/src/views/dev/MyPublishedApps.vue @@ -0,0 +1,578 @@ + + + + + + diff --git a/apps/jingrow/jingrow/api/local_app_installer.py b/apps/jingrow/jingrow/api/local_app_installer.py index 6602910..ebeba7e 100644 --- a/apps/jingrow/jingrow/api/local_app_installer.py +++ b/apps/jingrow/jingrow/api/local_app_installer.py @@ -20,7 +20,7 @@ from datetime import datetime import requests 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.jingrow_api import get_jingrow_api_headers, get_logged_user 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.utils.export_app_package import export_app_package_from_local from jingrow.config import Config @@ -1027,6 +1027,86 @@ async def get_app_meta(): raise HTTPException(status_code=500, detail=f"获取元数据失败: {str(e)}") +@router.get("/jingrow/my-published-apps") +async def get_my_published_apps( + request: Request, + search: Optional[str] = None, + page: int = 1, + page_size: int = 20, + sort_by: Optional[str] = None +): + """获取当前用户已发布的应用列表,支持搜索、分页和排序""" + try: + # 获取当前登录用户 + session_cookie = request.cookies.get('sid') + if not session_cookie: + raise HTTPException(status_code=401, detail="未提供认证信息") + + user = get_logged_user(session_cookie) + if not user: + raise HTTPException(status_code=401, detail="认证失败") + + url = f"{get_jingrow_cloud_url()}/api/action/jcloud.api.local_app.get_local_apps" + + # 构建过滤条件:过滤当前用户发布的应用 + filters = {"owner": user} + if search: + filters["title"] = ["like", f"%{search}%"] + + # 1. 先获取总数(不分页) + total_params = { + 'filters': json.dumps(filters, ensure_ascii=False), + 'limit_start': 0, + 'limit_page_length': 0 # 不限制数量,获取所有数据来计算总数 + } + + headers = get_jingrow_cloud_api_headers() + # 添加session cookie以获取用户的应用 + headers['Cookie'] = f'sid={session_cookie}' + + total_response = requests.get(url, params=total_params, headers=headers, timeout=20) + + total_count = 0 + if total_response.status_code == 200: + total_data = total_response.json() + total_count = len(total_data.get('message', [])) + + # 2. 获取分页数据 + params = { + 'filters': json.dumps(filters, ensure_ascii=False) + } + + # 排序参数 + if sort_by: + params['order_by'] = sort_by + + # 分页参数 + limit_start = (page - 1) * page_size + params['limit_start'] = limit_start + params['limit_page_length'] = page_size + + response = requests.get(url, params=params, headers=headers, timeout=20) + + if response.status_code == 200: + data = response.json() + apps = data.get('message', []) + + # 返回分页格式的数据 + return { + "items": apps, + "total": total_count, + "page": page, + "page_size": page_size + } + else: + raise HTTPException(status_code=response.status_code, detail="获取已发布应用数据失败") + + except HTTPException: + raise + except Exception as e: + raise HTTPException(status_code=500, detail=f"获取已发布应用数据失败: {str(e)}") + + @router.post("/jingrow/upload-image") async def upload_image(file: UploadFile = File(...)): """上传应用图片"""