From 792b76fb46b6a8287cac2a2f33ff91cad392d79c Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 29 Sep 2026 18:50:10 +0800 Subject: [PATCH] =?UTF-8?q?feat(gerp):=20=E6=96=B0=E5=A2=9E=E6=8C=89?= =?UTF-8?q?=E5=85=AC=E5=8F=B8=E6=9F=A5=E8=AF=A2=E5=B7=B2=E5=90=AF=E7=94=A8?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E6=8E=A5=E5=8F=A3=20/API/App/CompanyApps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 公司详情页需要展示该公司启用的应用并支持卸载/配置,原 /API/App/ManageCompanies 是反向(按应用查公司安装状态),故补正查接口:AppManager.ListCompanyEnabledApps 按公司列出 InstallStatus=1 的应用,AppCompanyAppsView 按可管理范围校验(super=全部 / tenant=本租户 / company=被授权公司)。 --- gvsds/apps/gerp/app_manager.py | 24 ++++++++++++++++++++++++ gvsds/apps/gerp/views/__init__.py | 1 + gvsds/apps/gerp/views/app.py | 31 +++++++++++++++++++++++++++++++ gvsds/urls.py | 1 + 4 files changed, 57 insertions(+) diff --git a/gvsds/apps/gerp/app_manager.py b/gvsds/apps/gerp/app_manager.py index a327aa61..eb0f4029 100644 --- a/gvsds/apps/gerp/app_manager.py +++ b/gvsds/apps/gerp/app_manager.py @@ -793,6 +793,30 @@ class AppManager: } return result + @staticmethod + def ListCompanyEnabledApps(CompanyUUID): + """列出指定公司已启用(InstallStatus=1)的应用(公司详情页用) + + 与 ListAppCompanyInstalls 互补:后者按应用反查公司安装状态, + 本方法按公司列出已装应用,供公司详情页展示 + 卸载/配置入口。 + + Returns: + list[dict]:_AppFlat 结构 + InstallStatus,按 AppSort/AppName 排序 + """ + company_bytes = _ToBytes(CompanyUUID) + if not company_bytes: + return [] + rows = [] + for ca in SdkAppManager.ListCompanyApps(company_bytes, InstallStatus=1): + app = AppManager.GetApp(ca.AppUUID) + if app is None: + continue + row = _AppFlat(app) + row['InstallStatus'] = ca.InstallStatus + rows.append(row) + rows.sort(key=lambda r: (r.get('AppSort') or 0, r.get('AppName') or '')) + return rows + @staticmethod def ListAppCompanyInstalls(AppUUID, CompanyUUIDs): """查询指定应用在若干公司的安装状态(管理弹窗用) diff --git a/gvsds/apps/gerp/views/__init__.py b/gvsds/apps/gerp/views/__init__.py index ad1e01b8..f4b20fae 100644 --- a/gvsds/apps/gerp/views/__init__.py +++ b/gvsds/apps/gerp/views/__init__.py @@ -149,6 +149,7 @@ from .app import ( AppMarketView, AppMyAppsView, AppManageCompaniesView, + AppCompanyAppsView, AppInstallView, AppUninstallView, AppUserEnableView, diff --git a/gvsds/apps/gerp/views/app.py b/gvsds/apps/gerp/views/app.py index 4403d18e..dd103612 100644 --- a/gvsds/apps/gerp/views/app.py +++ b/gvsds/apps/gerp/views/app.py @@ -295,6 +295,37 @@ class AppManageCompaniesView(ELTAuthenticatedAPIView): return Response({'code': 0, 'data': {'Scope': scope, 'Companies': rows, 'Roles': roles}}) +class AppCompanyAppsView(ELTAuthenticatedAPIView): + """指定公司已启用的应用列表(公司详情页用) + + GET /API/App/CompanyApps?CompanyUUID=xxx + - 返回该公司 InstallStatus=1 的应用(含图标/名称/编码/描述/前端入口) + - 权限:管理员 + 该公司在可管理范围内 + (admin:super=全部 / admin:tenant=本租户 / admin:company=被授权公司) + + 与 /API/App/ManageCompanies 互补:后者按应用反查各公司安装状态, + 本接口按公司列出已装应用,供公司详情页展示"已启用应用"并做卸载/配置。 + """ + + permission_classes = [IsAuthenticated, IsAdminUser] + + def get(self, request): + company_str = (request.query_params.get('CompanyUUID') or '').strip() + if not company_str: + return Response({'code': 1, 'msg': '缺少公司 UUID'}, status=400) + try: + company_bytes = UUIDObj(company_str).bytes + except Exception: + return Response({'code': 1, 'msg': '无效的公司 UUID'}, status=400) + manageable, scope = AppManager.GetManageableCompanies(request) + if not scope: + return Response({'code': 403, 'msg': '无权查看该公司应用:您不是管理员'}, status=403) + if scope != 'all' and company_bytes.hex() not in {c.hex() for c in manageable}: + return Response({'code': 403, 'msg': '无权查看该公司应用(不在您的管理范围)'}, status=403) + rows = AppManager.ListCompanyEnabledApps(company_bytes) + return Response({'code': 0, 'data': {'list': rows, 'total': len(rows)}}) + + class AppInstallView(ELTAuthenticatedAPIView): """管理员:安装企业功能。 diff --git a/gvsds/urls.py b/gvsds/urls.py index f609c378..89a8c46e 100644 --- a/gvsds/urls.py +++ b/gvsds/urls.py @@ -155,6 +155,7 @@ urlpatterns = [ path('API/App/Market', gerp_views.AppMarketView.as_view(), name='app_market'), path('API/App/MyApps', gerp_views.AppMyAppsView.as_view(), name='app_my_apps'), path('API/App/ManageCompanies', gerp_views.AppManageCompaniesView.as_view(), name='app_manage_companies'), + path('API/App/CompanyApps', gerp_views.AppCompanyAppsView.as_view(), name='app_company_apps'), path('API/App/Install', gerp_views.AppInstallView.as_view(), name='app_install'), path('API/App/Uninstall', gerp_views.AppUninstallView.as_view(), name='app_uninstall'), path('API/App/Enable', gerp_views.AppUserEnableView.as_view(), name='app_enable'),