diff --git a/apps/jingrow/frontend/src/app/router/index.ts b/apps/jingrow/frontend/src/app/router/index.ts index 34463b0..1b2ab60 100644 --- a/apps/jingrow/frontend/src/app/router/index.ts +++ b/apps/jingrow/frontend/src/app/router/index.ts @@ -151,6 +151,18 @@ const router = createRouter({ name: 'MyPublishedApps', component: () => import('../../views/dev/MyPublishedApps.vue'), meta: { requiresAuth: true } + }, + { + path: 'my-published-nodes', + name: 'MyPublishedNodes', + component: () => import('../../views/dev/MyPublishedNodes.vue'), + meta: { requiresAuth: true } + }, + { + path: 'my-published-agents', + name: 'MyPublishedAgents', + component: () => import('../../views/dev/MyPublishedAgents.vue'), + meta: { requiresAuth: true } } ] } diff --git a/apps/jingrow/frontend/src/shared/stores/menu.ts b/apps/jingrow/frontend/src/shared/stores/menu.ts index 9df0803..10e08cb 100644 --- a/apps/jingrow/frontend/src/shared/stores/menu.ts +++ b/apps/jingrow/frontend/src/shared/stores/menu.ts @@ -61,6 +61,8 @@ 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: 'my-published-apps', key: 'MyPublishedApps', label: 'My Published Apps', icon: 'tabler:cloud-upload', type: 'route', routeName: 'MyPublishedApps', parentId: 'dev-group', order: 7 }, + { id: 'my-published-nodes', key: 'MyPublishedNodes', label: '已发布节点', icon: 'carbon:add-child-node', type: 'route', routeName: 'MyPublishedNodes', parentId: 'dev-group', order: 7.1 }, + { id: 'my-published-agents', key: 'MyPublishedAgents', label: '已发布智能体', icon: 'hugeicons:robotic', type: 'route', routeName: 'MyPublishedAgents', parentId: 'dev-group', order: 7.2 }, { id: 'app-marketplace', key: 'AppMarketplace', label: 'App Marketplace', icon: 'tabler:shopping-cart', type: 'route', routeName: 'AppMarketplace', 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: 'agent-marketplace', key: 'AgentMarketplace', label: 'Agent Marketplace', icon: 'hugeicons:robotic', type: 'route', routeName: 'AgentMarketplace', parentId: 'dev-group', order: 8.5 }, diff --git a/apps/jingrow/frontend/src/views/dev/MyPublishedAgents.vue b/apps/jingrow/frontend/src/views/dev/MyPublishedAgents.vue new file mode 100644 index 0000000..bf7a23e --- /dev/null +++ b/apps/jingrow/frontend/src/views/dev/MyPublishedAgents.vue @@ -0,0 +1,644 @@ + + + + + + diff --git a/apps/jingrow/frontend/src/views/dev/MyPublishedNodes.vue b/apps/jingrow/frontend/src/views/dev/MyPublishedNodes.vue new file mode 100644 index 0000000..1451335 --- /dev/null +++ b/apps/jingrow/frontend/src/views/dev/MyPublishedNodes.vue @@ -0,0 +1,654 @@ + + + + + + diff --git a/apps/jingrow/jingrow/api/local_app_installer.py b/apps/jingrow/jingrow/api/local_app_installer.py index 1262895..0b3790f 100644 --- a/apps/jingrow/jingrow/api/local_app_installer.py +++ b/apps/jingrow/jingrow/api/local_app_installer.py @@ -1090,6 +1090,166 @@ async def delete_published_app(request: Request, payload: Dict[str, Any]): raise HTTPException(status_code=400, detail=result.get('message', '删除失败')) +@router.get("/jingrow/my-published-nodes") +async def get_my_published_nodes( + request: Request, + search: Optional[str] = None, + page: int = 1, + page_size: int = 20, + sort_by: Optional[str] = None +): + """获取当前用户已发布的节点列表,支持搜索、分页和排序""" + session_cookie = request.cookies.get('sid') + if not session_cookie: + raise HTTPException(status_code=401, detail="未提供认证信息") + + url = f"{get_jingrow_cloud_url()}/api/action/jcloud.api.jlocal.get_my_local_node_list" + + # 构建参数 + params = { + 'order_by': sort_by or "name asc", + 'limit_start': (page - 1) * page_size, + 'limit_page_length': page_size + } + + if search: + params['filters'] = json.dumps({"title": ["like", f"%{search}%"]}, ensure_ascii=False) + + # 获取总数 + total_params = params.copy() + total_params['limit_start'] = 0 + total_params['limit_page_length'] = 0 + + headers = get_jingrow_cloud_api_headers() + headers['Cookie'] = f'sid={session_cookie}' + + total_response = requests.get(url, params=total_params, headers=headers, timeout=20) + total_response.raise_for_status() + total_count = len(total_response.json().get('message', [])) + + # 获取分页数据 + response = requests.get(url, params=params, headers=headers, timeout=20) + response.raise_for_status() + nodes = response.json().get('message', []) + + return { + "items": nodes, + "total": total_count, + "page": page, + "page_size": page_size + } + + +@router.get("/jingrow/my-published-agents") +async def get_my_published_agents( + request: Request, + search: Optional[str] = None, + page: int = 1, + page_size: int = 20, + sort_by: Optional[str] = None +): + """获取当前用户已发布的智能体列表,支持搜索、分页和排序""" + session_cookie = request.cookies.get('sid') + if not session_cookie: + raise HTTPException(status_code=401, detail="未提供认证信息") + + url = f"{get_jingrow_cloud_url()}/api/action/jcloud.api.jlocal.get_my_local_agent_list" + + # 构建参数 + params = { + 'order_by': sort_by or "name asc", + 'limit_start': (page - 1) * page_size, + 'limit_page_length': page_size + } + + if search: + params['filters'] = json.dumps({"title": ["like", f"%{search}%"]}, ensure_ascii=False) + + # 获取总数 + total_params = params.copy() + total_params['limit_start'] = 0 + total_params['limit_page_length'] = 0 + + headers = get_jingrow_cloud_api_headers() + headers['Cookie'] = f'sid={session_cookie}' + + total_response = requests.get(url, params=total_params, headers=headers, timeout=20) + total_response.raise_for_status() + total_count = len(total_response.json().get('message', [])) + + # 获取分页数据 + response = requests.get(url, params=params, headers=headers, timeout=20) + response.raise_for_status() + agents = response.json().get('message', []) + + return { + "items": agents, + "total": total_count, + "page": page, + "page_size": page_size + } + + +@router.post("/jingrow/delete-published-node") +async def delete_published_node(request: Request, payload: Dict[str, Any]): + """删除已发布的节点,根据记录的name字段删除""" + session_cookie = request.cookies.get('sid') + if not session_cookie: + raise HTTPException(status_code=401, detail="未提供认证信息") + + # 使用记录的name字段 + record_name = payload.get('name') + if not record_name: + raise HTTPException(status_code=400, detail="记录名称不能为空") + + url = f"{get_jingrow_cloud_url()}/api/action/jcloud.api.jlocal.delete_local_node" + + headers = get_jingrow_cloud_api_headers() + headers['Cookie'] = f'sid={session_cookie}' + + # 传递记录的name字段到云端API + response = requests.post(url, json={'name': record_name}, headers=headers, timeout=20) + response.raise_for_status() + + data = response.json() + result = data.get('message', data) + + if result.get('success'): + return {"success": True, "message": result.get('message', '节点删除成功')} + else: + raise HTTPException(status_code=400, detail=result.get('message', '删除失败')) + + +@router.post("/jingrow/delete-published-agent") +async def delete_published_agent(request: Request, payload: Dict[str, Any]): + """删除已发布的智能体,根据记录的name字段删除""" + session_cookie = request.cookies.get('sid') + if not session_cookie: + raise HTTPException(status_code=401, detail="未提供认证信息") + + # 使用记录的name字段 + record_name = payload.get('name') + if not record_name: + raise HTTPException(status_code=400, detail="记录名称不能为空") + + url = f"{get_jingrow_cloud_url()}/api/action/jcloud.api.jlocal.delete_local_agent" + + headers = get_jingrow_cloud_api_headers() + headers['Cookie'] = f'sid={session_cookie}' + + # 传递记录的name字段到云端API + response = requests.post(url, json={'name': record_name}, headers=headers, timeout=20) + response.raise_for_status() + + data = response.json() + result = data.get('message', data) + + if result.get('success'): + return {"success": True, "message": result.get('message', '智能体删除成功')} + else: + raise HTTPException(status_code=400, detail=result.get('message', '删除失败')) + + @router.post("/jingrow/upload-image") async def upload_image(file: UploadFile = File(...)): """上传应用图片"""