diff --git a/src/dashboard-front/src/common/menu.ts b/src/dashboard-front/src/common/menu.ts index eeff16b79..4487fbe9e 100644 --- a/src/dashboard-front/src/common/menu.ts +++ b/src/dashboard-front/src/common/menu.ts @@ -30,18 +30,18 @@ export const createMenuData = (): IMenu[] => { { name: 'apigwStageManage', enabled: true, - title: '环境管理', + title: t('环境管理'), icon: 'resource', children: [ { name: 'apigwStageOverview', enabled: true, - title: '环境概览', + title: t('环境概览'), }, { name: 'apigwReleaseHistory', enabled: true, - title: '发布记录', + title: t('发布记录'), }, ], }, diff --git a/src/dashboard-front/src/language/lang.ts b/src/dashboard-front/src/language/lang.ts index 5ed61826e..96aaf39ad 100644 --- a/src/dashboard-front/src/language/lang.ts +++ b/src/dashboard-front/src/language/lang.ts @@ -1438,7 +1438,7 @@ const lang: ILANG = { '确认回滚 {version} 版本至 {stage} 环境?': ['Are you sure you want to roll back {version} to {stage}?'], '确认发布 {version} 版本至 {stage} 环境?': ['Are you sure to release {version} to the {stage} environment?'], '发布后,将会覆盖原来的资源版本,请谨慎操作!': ['After the release, the original resource version will be overwritten, please exercise caution!'], - + '立即生成版本': ['Generate Version'], // 变量的使用 $t('test', { vari1: 1, vari2: 2 }) // // 变量的使用 $t('test', { vari1: 1, vari2: 2 }) diff --git a/src/dashboard-front/src/views/components/plugin-manage/index.vue b/src/dashboard-front/src/views/components/plugin-manage/index.vue index 0a6b18dfc..b23e0854a 100644 --- a/src/dashboard-front/src/views/components/plugin-manage/index.vue +++ b/src/dashboard-front/src/views/components/plugin-manage/index.vue @@ -376,7 +376,7 @@ const handleClearFilterKey = () => { const handleEditePlugin = async (item: any) => { curType.value = 'edit'; const { code, config_id } = item; - const curEditItem = pluginListDate.value.find((pluginItem: { code: string; }) => pluginItem.code === code); + const curEditItem = curBindingPlugins.value.find((pluginItem: { code: string; }) => pluginItem.code === code); curChoosePlugin.value = curEditItem; try { const res = await getPluginConfig(apigwId, scopeType.value, scopeId.value, code, config_id); diff --git a/src/dashboard-front/src/views/resource/setting/comps/base-info.vue b/src/dashboard-front/src/views/resource/setting/comps/base-info.vue index 41fab58ba..022455673 100644 --- a/src/dashboard-front/src/views/resource/setting/comps/base-info.vue +++ b/src/dashboard-front/src/views/resource/setting/comps/base-info.vue @@ -70,7 +70,7 @@ v-model="formData.allow_apply_permission"> + v-bk-tooltips="{ content: t('允许,则任何蓝鲸应用可在蓝鲸开发者中心申请资源的访问权限;否则,只能通过网关管理员主动授权为某应用添加权限') }"> {{ t('允许申请权限') }} diff --git a/src/dashboard-front/src/views/resource/setting/index.vue b/src/dashboard-front/src/views/resource/setting/index.vue index 9446f172d..ac4a1c94d 100644 --- a/src/dashboard-front/src/views/resource/setting/index.vue +++ b/src/dashboard-front/src/views/resource/setting/index.vue @@ -26,7 +26,7 @@ theme="primary" v-if="versionConfigs.needNewVersion" @click="handleCreateResourceVersion"> - 立即生成版本 + {{ t('立即生成版本') }} @@ -514,9 +514,9 @@ const common = useCommon(); const resourceVersionStore = useResourceVersion(); const { t } = useI18n(); // 批量下拉的item -const batchDropData = ref([{ value: 'edit', label: '编辑资源' }, { value: 'delete', label: '删除资源' }]); +const batchDropData = ref([{ value: 'edit', label: t('编辑资源') }, { value: 'delete', label: t('删除资源') }]); // 导入下拉 -const importDropData = ref([{ value: 'config', label: '资源配置' }, { value: 'doc', label: '资源文档' }]); +const importDropData = ref([{ value: 'config', label: t('资源配置') }, { value: 'doc', label: t('资源文档') }]); interface ApigwIDropList extends IDropList { tooltips?: string; } diff --git a/src/dashboard/apigateway/apigateway/apis/web/plugin/serializers.py b/src/dashboard/apigateway/apigateway/apis/web/plugin/serializers.py index 32ec482ac..35f5a82a9 100644 --- a/src/dashboard/apigateway/apigateway/apis/web/plugin/serializers.py +++ b/src/dashboard/apigateway/apigateway/apis/web/plugin/serializers.py @@ -176,3 +176,9 @@ class ScopePluginConfigListOutputSLZ(serializers.Serializer): name = serializers.CharField(help_text="插件类型名称") config = serializers.DictField(help_text="插件配置") config_id = serializers.IntegerField(help_text="插件配置 id") + related_scope_count = serializers.SerializerMethodField(help_text="插件类型绑定的环境及资源数量") + + def get_related_scope_count(self, obj): + related_scope_count = self.context.get("type_related_scope_count", {}) + print("the related_scope_count:", related_scope_count) + return related_scope_count.get(obj["code"], {"stage": 0, "resource": 0}) diff --git a/src/dashboard/apigateway/apigateway/apis/web/plugin/views.py b/src/dashboard/apigateway/apigateway/apis/web/plugin/views.py index 6deba172e..36a3afdf6 100644 --- a/src/dashboard/apigateway/apigateway/apis/web/plugin/views.py +++ b/src/dashboard/apigateway/apigateway/apis/web/plugin/views.py @@ -426,6 +426,27 @@ def get(self, request, *args, **kwargs): class ScopePluginConfigListApi(generics.ListAPIView, ScopeValidationMixin): + def get_serializer_context(self): + # 需要返回每个 pluginType 对应绑定的环境数量/资源数量 + type_related_scope_count = {} + gateway = self.request.gateway + for binding in PluginBinding.objects.filter(gateway=gateway).prefetch_related("config", "config__type").all(): + key = binding.config.type.code + if key not in type_related_scope_count: + type_related_scope_count[key] = { + "stage": 0, + "resource": 0, + } + + # all + scope_type = binding.scope_type + count = type_related_scope_count[key].get(scope_type, 0) + type_related_scope_count[key][scope_type] = count + 1 + + return { + "type_related_scope_count": type_related_scope_count, + } + @swagger_auto_schema( responses={status.HTTP_200_OK: ScopePluginConfigListOutputSLZ(many=True)}, operation_description="获取某个环境或资源绑定的插件列表 (插件类型 + 插件配置)", @@ -453,5 +474,5 @@ def get(self, request, *args, **kwargs): for binding in bindings ] - serializer = ScopePluginConfigListOutputSLZ(data, many=True) + serializer = ScopePluginConfigListOutputSLZ(data, many=True, context=self.get_serializer_context()) return OKJsonResponse(data=serializer.data) diff --git a/src/dashboard/apigateway/apigateway/apis/web/resource_version/serializers.py b/src/dashboard/apigateway/apigateway/apis/web/resource_version/serializers.py index 8763d2fe6..1ae0615d9 100644 --- a/src/dashboard/apigateway/apigateway/apis/web/resource_version/serializers.py +++ b/src/dashboard/apigateway/apigateway/apis/web/resource_version/serializers.py @@ -78,18 +78,12 @@ def get_proxy(self, obj): return proxy def get_plugins(self, obj): - plugins = {} + plugins = self.context.get("stage_plugins", {}) # v2 才有plugin数据 if not self.context["is_schema_v2"]: return list(plugins.values()) - # 列表需要展示资源生效插件,此时需要返回环境绑定的插件信息 - for plugin_type, plugin_binding in self.context.get("stage_plugin_bindings", {}).items(): - plugin_config = plugin_binding.snapshot() - plugin_config["binding_type"] = PluginBindingScopeEnum.STAGE.value - plugins[plugin_type] = plugin_config - # 资源绑定插件覆盖环境绑定插件 for plugin in obj.get("plugins", []): plugin["binding_type"] = PluginBindingScopeEnum.RESOURCE.value diff --git a/src/dashboard/apigateway/apigateway/apis/web/resource_version/views.py b/src/dashboard/apigateway/apigateway/apis/web/resource_version/views.py index 1c9e23750..07ae7358b 100644 --- a/src/dashboard/apigateway/apigateway/apis/web/resource_version/views.py +++ b/src/dashboard/apigateway/apigateway/apis/web/resource_version/views.py @@ -24,6 +24,7 @@ from drf_yasg.utils import swagger_auto_schema from rest_framework import generics, serializers, status +from apigateway.apps.plugin.constants import PluginBindingScopeEnum from apigateway.apps.support.models import ResourceDoc, ResourceDocVersion from apigateway.biz.backend import BackendHandler from apigateway.biz.plugin_binding import PluginBindingHandler @@ -155,8 +156,15 @@ def get(self, request, *args, **kwargs): if stage_id: backend_configs = BackendHandler.get_backend_configs_by_stage(request.gateway.id, stage_id) context["resource_backend_configs"] = backend_configs + + stage_plugins = {} stage_plugin_bindings = PluginBindingHandler.get_stage_plugin_bindings(request.gateway.id, stage_id) - context["stage_plugin_bindings"] = stage_plugin_bindings + # 列表需要展示资源生效插件,此时需要返回环境绑定的插件信息 + for plugin_type, plugin_binding in stage_plugin_bindings.items(): + plugin_config = plugin_binding.snapshot() + plugin_config["binding_type"] = PluginBindingScopeEnum.STAGE.value + stage_plugins[plugin_type] = plugin_config + context["stage_plugins"] = stage_plugins slz = ResourceVersionRetrieveOutputSLZ(instance, context=context) diff --git a/src/dashboard/apigateway/apigateway/data/version_log/CHANGELOG.md b/src/dashboard/apigateway/apigateway/data/version_log/CHANGELOG.md index 88198dfc0..1c1f155df 100644 --- a/src/dashboard/apigateway/apigateway/data/version_log/CHANGELOG.md +++ b/src/dashboard/apigateway/apigateway/data/version_log/CHANGELOG.md @@ -1,4 +1,18 @@ - + +# V1.13.1 版本更新日志 + +### 缺陷修复 + +- 修复环境绑定插件无法编辑问题 +- 修复菜单国际化问题 + +### 功能优化 + +- 环境下资源列表过大无法展示问题 + +--- + + # V1.13.0 版本更新日志 ### 缺陷修复 diff --git a/src/dashboard/apigateway/apigateway/data/version_log/CHANGELOG_en.md b/src/dashboard/apigateway/apigateway/data/version_log/CHANGELOG_en.md index 9a172d15b..7f50e8441 100644 --- a/src/dashboard/apigateway/apigateway/data/version_log/CHANGELOG_en.md +++ b/src/dashboard/apigateway/apigateway/data/version_log/CHANGELOG_en.md @@ -1,4 +1,18 @@ - + +# V1.13.1 Version Update Log + +### Bug Fixes + +- fix: stage plugins can't be edited +- fix: menu i18n issue + +### Feature Enhancements + +- Stage resource list is too large to display + +--- + + # V1.13.0 Version Update Log ### Bug Fixes diff --git a/src/dashboard/apigateway/apigateway/tests/apis/web/resource_version/test_serializers.py b/src/dashboard/apigateway/apigateway/tests/apis/web/resource_version/test_serializers.py index 68042afa3..7108e5c19 100644 --- a/src/dashboard/apigateway/apigateway/tests/apis/web/resource_version/test_serializers.py +++ b/src/dashboard/apigateway/apigateway/tests/apis/web/resource_version/test_serializers.py @@ -21,6 +21,7 @@ from django_dynamic_fixture import G from apigateway.apis.web.resource_version import serializers +from apigateway.apps.plugin.constants import PluginBindingScopeEnum from apigateway.biz.backend import BackendHandler from apigateway.biz.plugin_binding import PluginBindingHandler from apigateway.core.models import Gateway, ResourceVersion @@ -105,7 +106,7 @@ def test_to_representation_v1( fake_gateway.id, fake_stage.id ), "is_schema_v2": fake_resource_version_v1.is_schema_v2, - "stage_plugin_binding": PluginBindingHandler.get_stage_plugin_bindings(fake_gateway.id, fake_stage.id), + "stage_plugins": {}, "resource_doc_updated_time": {}, }, ) @@ -151,6 +152,12 @@ def test_to_representation_v1( def test_to_representation_v2( self, fake_backend, fake_stage, fake_gateway, fake_resource_version_v2, echo_plugin_stage_binding ): + stage_plugin_bindings = PluginBindingHandler.get_stage_plugin_bindings(fake_gateway.id, fake_stage.id) + stage_plugins = {} + for plugin_type, plugin_binding in stage_plugin_bindings.items(): + plugin_config = plugin_binding.snapshot() + plugin_config["binding_type"] = PluginBindingScopeEnum.STAGE.value + stage_plugins[plugin_type] = plugin_config slz = serializers.ResourceVersionRetrieveOutputSLZ( instance=fake_resource_version_v2, context={ @@ -159,9 +166,7 @@ def test_to_representation_v2( fake_gateway.id, fake_stage.id ), "is_schema_v2": fake_resource_version_v2.is_schema_v2, - "stage_plugin_bindings": PluginBindingHandler.get_stage_plugin_bindings( - fake_gateway.id, fake_stage.id - ), + "stage_plugins": stage_plugins, "resource_doc_updated_time": {}, }, )