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'),