#
tokens: 49649/50000 80/349 files (page 2/9)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 2 of 9. Use http://codebase.md/higress-group/himarket?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .cursor
│   └── rules
│       ├── api-style.mdc
│       └── project-architecture.mdc
├── .gitignore
├── build.sh
├── deploy
│   ├── docker
│   │   ├── docker-compose.yml
│   │   └── Docker部署说明.md
│   └── helm
│       ├── Chart.yaml
│       ├── Helm部署说明.md
│       ├── templates
│       │   ├── _helpers.tpl
│       │   ├── himarket-admin-cm.yaml
│       │   ├── himarket-admin-deployment.yaml
│       │   ├── himarket-admin-service.yaml
│       │   ├── himarket-frontend-cm.yaml
│       │   ├── himarket-frontend-deployment.yaml
│       │   ├── himarket-frontend-service.yaml
│       │   ├── himarket-server-cm.yaml
│       │   ├── himarket-server-deployment.yaml
│       │   ├── himarket-server-service.yaml
│       │   ├── mysql.yaml
│       │   └── serviceaccount.yaml
│       └── values.yaml
├── LICENSE
├── NOTICE
├── pom.xml
├── portal-bootstrap
│   ├── Dockerfile
│   ├── pom.xml
│   └── src
│       ├── main
│       │   ├── java
│       │   │   └── com
│       │   │       └── alibaba
│       │   │           └── apiopenplatform
│       │   │               ├── config
│       │   │               │   ├── AsyncConfig.java
│       │   │               │   ├── FilterConfig.java
│       │   │               │   ├── PageConfig.java
│       │   │               │   ├── RestTemplateConfig.java
│       │   │               │   ├── SecurityConfig.java
│       │   │               │   └── SwaggerConfig.java
│       │   │               ├── filter
│       │   │               │   └── PortalResolvingFilter.java
│       │   │               └── PortalApplication.java
│       │   └── resources
│       │       └── application.yaml
│       └── test
│           └── java
│               └── com
│                   └── alibaba
│                       └── apiopenplatform
│                           └── integration
│                               └── AdministratorAuthIntegrationTest.java
├── portal-dal
│   ├── pom.xml
│   └── src
│       └── main
│           └── java
│               └── com
│                   └── alibaba
│                       └── apiopenplatform
│                           ├── converter
│                           │   ├── AdpAIGatewayConfigConverter.java
│                           │   ├── APIGConfigConverter.java
│                           │   ├── APIGRefConfigConverter.java
│                           │   ├── ApiKeyConfigConverter.java
│                           │   ├── ConsumerAuthConfigConverter.java
│                           │   ├── GatewayConfigConverter.java
│                           │   ├── HigressConfigConverter.java
│                           │   ├── HigressRefConfigConverter.java
│                           │   ├── HmacConfigConverter.java
│                           │   ├── JsonConverter.java
│                           │   ├── JwtConfigConverter.java
│                           │   ├── NacosRefConfigConverter.java
│                           │   ├── PortalSettingConfigConverter.java
│                           │   ├── PortalUiConfigConverter.java
│                           │   └── ProductIconConverter.java
│                           ├── entity
│                           │   ├── Administrator.java
│                           │   ├── BaseEntity.java
│                           │   ├── Consumer.java
│                           │   ├── ConsumerCredential.java
│                           │   ├── ConsumerRef.java
│                           │   ├── Developer.java
│                           │   ├── DeveloperExternalIdentity.java
│                           │   ├── Gateway.java
│                           │   ├── NacosInstance.java
│                           │   ├── Portal.java
│                           │   ├── PortalDomain.java
│                           │   ├── Product.java
│                           │   ├── ProductPublication.java
│                           │   ├── ProductRef.java
│                           │   └── ProductSubscription.java
│                           ├── repository
│                           │   ├── AdministratorRepository.java
│                           │   ├── BaseRepository.java
│                           │   ├── ConsumerCredentialRepository.java
│                           │   ├── ConsumerRefRepository.java
│                           │   ├── ConsumerRepository.java
│                           │   ├── DeveloperExternalIdentityRepository.java
│                           │   ├── DeveloperRepository.java
│                           │   ├── GatewayRepository.java
│                           │   ├── NacosInstanceRepository.java
│                           │   ├── PortalDomainRepository.java
│                           │   ├── PortalRepository.java
│                           │   ├── ProductPublicationRepository.java
│                           │   ├── ProductRefRepository.java
│                           │   ├── ProductRepository.java
│                           │   └── SubscriptionRepository.java
│                           └── support
│                               ├── common
│                               │   ├── Encrypted.java
│                               │   ├── Encryptor.java
│                               │   └── User.java
│                               ├── consumer
│                               │   ├── AdpAIAuthConfig.java
│                               │   ├── APIGAuthConfig.java
│                               │   ├── ApiKeyConfig.java
│                               │   ├── ConsumerAuthConfig.java
│                               │   ├── HigressAuthConfig.java
│                               │   ├── HmacConfig.java
│                               │   └── JwtConfig.java
│                               ├── enums
│                               │   ├── APIGAPIType.java
│                               │   ├── ConsumerAuthType.java
│                               │   ├── ConsumerStatus.java
│                               │   ├── CredentialMode.java
│                               │   ├── DeveloperAuthType.java
│                               │   ├── DeveloperStatus.java
│                               │   ├── DomainType.java
│                               │   ├── GatewayType.java
│                               │   ├── GrantType.java
│                               │   ├── HigressAPIType.java
│                               │   ├── JwtAlgorithm.java
│                               │   ├── ProductIconType.java
│                               │   ├── ProductStatus.java
│                               │   ├── ProductType.java
│                               │   ├── ProtocolType.java
│                               │   ├── PublicKeyFormat.java
│                               │   ├── SourceType.java
│                               │   ├── SubscriptionStatus.java
│                               │   └── UserType.java
│                               ├── gateway
│                               │   ├── AdpAIGatewayConfig.java
│                               │   ├── APIGConfig.java
│                               │   ├── GatewayConfig.java
│                               │   └── HigressConfig.java
│                               ├── portal
│                               │   ├── AuthCodeConfig.java
│                               │   ├── IdentityMapping.java
│                               │   ├── JwtBearerConfig.java
│                               │   ├── OAuth2Config.java
│                               │   ├── OidcConfig.java
│                               │   ├── PortalSettingConfig.java
│                               │   ├── PortalUiConfig.java
│                               │   └── PublicKeyConfig.java
│                               └── product
│                                   ├── APIGRefConfig.java
│                                   ├── HigressRefConfig.java
│                                   ├── NacosRefConfig.java
│                                   └── ProductIcon.java
├── portal-server
│   ├── pom.xml
│   └── src
│       └── main
│           └── java
│               └── com
│                   └── alibaba
│                       └── apiopenplatform
│                           ├── controller
│                           │   ├── AdministratorController.java
│                           │   ├── ConsumerController.java
│                           │   ├── DeveloperController.java
│                           │   ├── GatewayController.java
│                           │   ├── NacosController.java
│                           │   ├── OAuth2Controller.java
│                           │   ├── OidcController.java
│                           │   ├── PortalController.java
│                           │   └── ProductController.java
│                           ├── core
│                           │   ├── advice
│                           │   │   ├── ExceptionAdvice.java
│                           │   │   └── ResponseAdvice.java
│                           │   ├── annotation
│                           │   │   ├── AdminAuth.java
│                           │   │   ├── AdminOrDeveloperAuth.java
│                           │   │   └── DeveloperAuth.java
│                           │   ├── constant
│                           │   │   ├── CommonConstants.java
│                           │   │   ├── IdpConstants.java
│                           │   │   ├── JwtConstants.java
│                           │   │   └── Resources.java
│                           │   ├── event
│                           │   │   ├── DeveloperDeletingEvent.java
│                           │   │   ├── PortalDeletingEvent.java
│                           │   │   └── ProductDeletingEvent.java
│                           │   ├── exception
│                           │   │   ├── BusinessException.java
│                           │   │   └── ErrorCode.java
│                           │   ├── response
│                           │   │   └── Response.java
│                           │   ├── security
│                           │   │   ├── ContextHolder.java
│                           │   │   ├── DeveloperAuthenticationProvider.java
│                           │   │   └── JwtAuthenticationFilter.java
│                           │   └── utils
│                           │       ├── IdGenerator.java
│                           │       ├── PasswordHasher.java
│                           │       └── TokenUtil.java
│                           ├── dto
│                           │   ├── converter
│                           │   │   ├── InputConverter.java
│                           │   │   ├── NacosToGatewayToolsConverter.java
│                           │   │   └── OutputConverter.java
│                           │   ├── params
│                           │   │   ├── admin
│                           │   │   │   ├── AdminCreateParam.java
│                           │   │   │   ├── AdminLoginParam.java
│                           │   │   │   └── ResetPasswordParam.java
│                           │   │   ├── consumer
│                           │   │   │   ├── CreateConsumerParam.java
│                           │   │   │   ├── CreateCredentialParam.java
│                           │   │   │   ├── CreateSubscriptionParam.java
│                           │   │   │   ├── QueryConsumerParam.java
│                           │   │   │   ├── QuerySubscriptionParam.java
│                           │   │   │   └── UpdateCredentialParam.java
│                           │   │   ├── developer
│                           │   │   │   ├── CreateDeveloperParam.java
│                           │   │   │   ├── CreateExternalDeveloperParam.java
│                           │   │   │   ├── DeveloperLoginParam.java
│                           │   │   │   ├── QueryDeveloperParam.java
│                           │   │   │   ├── UnbindExternalIdentityParam.java
│                           │   │   │   ├── UpdateDeveloperParam.java
│                           │   │   │   └── UpdateDeveloperStatusParam.java
│                           │   │   ├── gateway
│                           │   │   │   ├── ImportGatewayParam.java
│                           │   │   │   ├── QueryAdpAIGatewayParam.java
│                           │   │   │   ├── QueryAPIGParam.java
│                           │   │   │   └── QueryGatewayParam.java
│                           │   │   ├── nacos
│                           │   │   │   ├── CreateNacosParam.java
│                           │   │   │   ├── QueryNacosNamespaceParam.java
│                           │   │   │   ├── QueryNacosParam.java
│                           │   │   │   └── UpdateNacosParam.java
│                           │   │   ├── portal
│                           │   │   │   ├── BindDomainParam.java
│                           │   │   │   ├── CreatePortalParam.java
│                           │   │   │   └── UpdatePortalParam.java
│                           │   │   └── product
│                           │   │       ├── CreateProductParam.java
│                           │   │       ├── CreateProductRefParam.java
│                           │   │       ├── PublishProductParam.java
│                           │   │       ├── QueryProductParam.java
│                           │   │       ├── QueryProductSubscriptionParam.java
│                           │   │       ├── UnPublishProductParam.java
│                           │   │       └── UpdateProductParam.java
│                           │   └── result
│                           │       ├── AdminResult.java
│                           │       ├── AdpGatewayInstanceResult.java
│                           │       ├── AdpMcpServerListResult.java
│                           │       ├── AdpMCPServerResult.java
│                           │       ├── APIConfigResult.java
│                           │       ├── APIGMCPServerResult.java
│                           │       ├── APIResult.java
│                           │       ├── AuthResult.java
│                           │       ├── ConsumerCredentialResult.java
│                           │       ├── ConsumerResult.java
│                           │       ├── DeveloperResult.java
│                           │       ├── GatewayMCPServerResult.java
│                           │       ├── GatewayResult.java
│                           │       ├── HigressMCPServerResult.java
│                           │       ├── IdpResult.java
│                           │       ├── IdpState.java
│                           │       ├── IdpTokenResult.java
│                           │       ├── MCPConfigResult.java
│                           │       ├── MCPServerResult.java
│                           │       ├── MseNacosResult.java
│                           │       ├── NacosMCPServerResult.java
│                           │       ├── NacosNamespaceResult.java
│                           │       ├── NacosResult.java
│                           │       ├── PageResult.java
│                           │       ├── PortalResult.java
│                           │       ├── ProductPublicationResult.java
│                           │       ├── ProductRefResult.java
│                           │       ├── ProductResult.java
│                           │       └── SubscriptionResult.java
│                           └── service
│                               ├── AdministratorService.java
│                               ├── AdpAIGatewayService.java
│                               ├── ConsumerService.java
│                               ├── DeveloperService.java
│                               ├── gateway
│                               │   ├── AdpAIGatewayOperator.java
│                               │   ├── AIGatewayOperator.java
│                               │   ├── APIGOperator.java
│                               │   ├── client
│                               │   │   ├── AdpAIGatewayClient.java
│                               │   │   ├── APIGClient.java
│                               │   │   ├── GatewayClient.java
│                               │   │   ├── HigressClient.java
│                               │   │   ├── PopGatewayClient.java
│                               │   │   └── SLSClient.java
│                               │   ├── factory
│                               │   │   └── HTTPClientFactory.java
│                               │   ├── GatewayOperator.java
│                               │   └── HigressOperator.java
│                               ├── GatewayService.java
│                               ├── IdpService.java
│                               ├── impl
│                               │   ├── AdministratorServiceImpl.java
│                               │   ├── ConsumerServiceImpl.java
│                               │   ├── DeveloperServiceImpl.java
│                               │   ├── GatewayServiceImpl.java
│                               │   ├── IdpServiceImpl.java
│                               │   ├── NacosServiceImpl.java
│                               │   ├── OAuth2ServiceImpl.java
│                               │   ├── OidcServiceImpl.java
│                               │   ├── PortalServiceImpl.java
│                               │   └── ProductServiceImpl.java
│                               ├── NacosService.java
│                               ├── OAuth2Service.java
│                               ├── OidcService.java
│                               ├── PortalService.java
│                               └── ProductService.java
├── portal-web
│   ├── api-portal-admin
│   │   ├── .env
│   │   ├── .gitignore
│   │   ├── bin
│   │   │   ├── replace_var.py
│   │   │   └── start.sh
│   │   ├── Dockerfile
│   │   ├── eslint.config.js
│   │   ├── index.html
│   │   ├── nginx.conf
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── proxy.conf
│   │   ├── public
│   │   │   ├── logo.png
│   │   │   └── vite.svg
│   │   ├── README.md
│   │   ├── src
│   │   │   ├── aliyunThemeToken.ts
│   │   │   ├── App.css
│   │   │   ├── App.tsx
│   │   │   ├── assets
│   │   │   │   └── react.svg
│   │   │   ├── components
│   │   │   │   ├── api-product
│   │   │   │   │   ├── ApiProductApiDocs.tsx
│   │   │   │   │   ├── ApiProductDashboard.tsx
│   │   │   │   │   ├── ApiProductFormModal.tsx
│   │   │   │   │   ├── ApiProductLinkApi.tsx
│   │   │   │   │   ├── ApiProductOverview.tsx
│   │   │   │   │   ├── ApiProductPolicy.tsx
│   │   │   │   │   ├── ApiProductPortal.tsx
│   │   │   │   │   ├── ApiProductUsageGuide.tsx
│   │   │   │   │   ├── SwaggerUIWrapper.css
│   │   │   │   │   └── SwaggerUIWrapper.tsx
│   │   │   │   ├── common
│   │   │   │   │   ├── AdvancedSearch.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── console
│   │   │   │   │   ├── GatewayTypeSelector.tsx
│   │   │   │   │   ├── ImportGatewayModal.tsx
│   │   │   │   │   ├── ImportHigressModal.tsx
│   │   │   │   │   ├── ImportMseNacosModal.tsx
│   │   │   │   │   └── NacosTypeSelector.tsx
│   │   │   │   ├── icons
│   │   │   │   │   └── McpServerIcon.tsx
│   │   │   │   ├── Layout.tsx
│   │   │   │   ├── LayoutWrapper.tsx
│   │   │   │   ├── portal
│   │   │   │   │   ├── PortalConsumers.tsx
│   │   │   │   │   ├── PortalDashboard.tsx
│   │   │   │   │   ├── PortalDevelopers.tsx
│   │   │   │   │   ├── PortalDomain.tsx
│   │   │   │   │   ├── PortalFormModal.tsx
│   │   │   │   │   ├── PortalOverview.tsx
│   │   │   │   │   ├── PortalPublishedApis.tsx
│   │   │   │   │   ├── PortalSecurity.tsx
│   │   │   │   │   ├── PortalSettings.tsx
│   │   │   │   │   ├── PublicKeyManager.tsx
│   │   │   │   │   └── ThirdPartyAuthManager.tsx
│   │   │   │   └── subscription
│   │   │   │       └── SubscriptionListModal.tsx
│   │   │   ├── contexts
│   │   │   │   └── LoadingContext.tsx
│   │   │   ├── index.css
│   │   │   ├── lib
│   │   │   │   ├── api.ts
│   │   │   │   ├── constant.ts
│   │   │   │   └── utils.ts
│   │   │   ├── main.tsx
│   │   │   ├── pages
│   │   │   │   ├── ApiProductDetail.tsx
│   │   │   │   ├── ApiProducts.tsx
│   │   │   │   ├── Dashboard.tsx
│   │   │   │   ├── GatewayConsoles.tsx
│   │   │   │   ├── Login.tsx
│   │   │   │   ├── NacosConsoles.tsx
│   │   │   │   ├── PortalDetail.tsx
│   │   │   │   ├── Portals.tsx
│   │   │   │   └── Register.tsx
│   │   │   ├── routes
│   │   │   │   └── index.tsx
│   │   │   ├── types
│   │   │   │   ├── api-product.ts
│   │   │   │   ├── consumer.ts
│   │   │   │   ├── gateway.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── portal.ts
│   │   │   │   ├── shims-js-yaml.d.ts
│   │   │   │   └── subscription.ts
│   │   │   └── vite-env.d.ts
│   │   ├── tailwind.config.js
│   │   ├── tsconfig.json
│   │   ├── tsconfig.node.json
│   │   └── vite.config.ts
│   └── api-portal-frontend
│       ├── .env
│       ├── .gitignore
│       ├── .husky
│       │   └── pre-commit
│       ├── bin
│       │   ├── replace_var.py
│       │   └── start.sh
│       ├── Dockerfile
│       ├── eslint.config.js
│       ├── index.html
│       ├── nginx.conf
│       ├── package.json
│       ├── postcss.config.js
│       ├── proxy.conf
│       ├── public
│       │   ├── favicon.ico
│       │   ├── logo.png
│       │   ├── logo.svg
│       │   ├── MCP.png
│       │   ├── MCP.svg
│       │   └── vite.svg
│       ├── README.md
│       ├── src
│       │   ├── aliyunThemeToken.ts
│       │   ├── App.css
│       │   ├── App.tsx
│       │   ├── assets
│       │   │   ├── aliyun.png
│       │   │   ├── github.png
│       │   │   ├── google.png
│       │   │   └── react.svg
│       │   ├── components
│       │   │   ├── consumer
│       │   │   │   ├── ConsumerBasicInfo.tsx
│       │   │   │   ├── CredentialManager.tsx
│       │   │   │   ├── index.ts
│       │   │   │   └── SubscriptionManager.tsx
│       │   │   ├── Layout.tsx
│       │   │   ├── Navigation.tsx
│       │   │   ├── ProductHeader.tsx
│       │   │   ├── SwaggerUIWrapper.css
│       │   │   ├── SwaggerUIWrapper.tsx
│       │   │   └── UserInfo.tsx
│       │   ├── index.css
│       │   ├── lib
│       │   │   ├── api.ts
│       │   │   ├── statusUtils.ts
│       │   │   └── utils.ts
│       │   ├── main.tsx
│       │   ├── pages
│       │   │   ├── ApiDetail.tsx
│       │   │   ├── Apis.tsx
│       │   │   ├── Callback.tsx
│       │   │   ├── ConsumerDetail.tsx
│       │   │   ├── Consumers.tsx
│       │   │   ├── GettingStarted.tsx
│       │   │   ├── Home.tsx
│       │   │   ├── Login.tsx
│       │   │   ├── Mcp.tsx
│       │   │   ├── McpDetail.tsx
│       │   │   ├── OidcCallback.tsx
│       │   │   ├── Profile.tsx
│       │   │   ├── Register.tsx
│       │   │   └── Test.css
│       │   ├── router.tsx
│       │   ├── types
│       │   │   ├── consumer.ts
│       │   │   └── index.ts
│       │   └── vite-env.d.ts
│       ├── tailwind.config.js
│       ├── tsconfig.app.json
│       ├── tsconfig.json
│       ├── tsconfig.node.json
│       └── vite.config.ts
└── README.md
```

# Files

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/PortalDomainRepository.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.repository;
21 | 
22 | import com.alibaba.apiopenplatform.entity.PortalDomain;
23 | 
24 | import java.util.List;
25 | import java.util.Optional;
26 | 
27 | public interface PortalDomainRepository extends BaseRepository<PortalDomain, Long> {
28 | 
29 |     Optional<PortalDomain> findByDomain(String domain);
30 | 
31 |     Optional<PortalDomain> findByPortalIdAndDomain(String portalId, String domain);
32 | 
33 |     List<PortalDomain> findAllByPortalId(String portalId);
34 | 
35 |     List<PortalDomain> findAllByPortalIdIn(List<String> portalIds);
36 | 
37 |     void deleteAllByPortalId(String portalId);
38 | }
39 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/NacosResult.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.result;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
23 | import com.alibaba.apiopenplatform.entity.NacosInstance;
24 | import lombok.Data;
25 | import java.time.LocalDateTime;
26 | 
27 | @Data
28 | public class NacosResult implements OutputConverter<NacosResult, NacosInstance> {
29 | 
30 |     private String nacosId;
31 | 
32 |     private String nacosName;
33 | 
34 |     private String serverUrl;
35 | 
36 | 
37 |     private String username;
38 | 
39 |     private String accessKey;
40 | 
41 |     private String description;
42 | 
43 |     private String adminId;
44 |     
45 |     private LocalDateTime createAt;
46 | } 
```

--------------------------------------------------------------------------------
/portal-bootstrap/src/main/java/com/alibaba/apiopenplatform/PortalApplication.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform;
21 | 
22 | import org.springframework.boot.SpringApplication;
23 | import org.springframework.boot.autoconfigure.SpringBootApplication;
24 | import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
25 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
26 | import org.springframework.context.annotation.ComponentScan;
27 | 
28 | @SpringBootApplication
29 | @EnableJpaAuditing
30 | public class PortalApplication {
31 | 
32 |     public static void main(String[] args) {
33 |         SpringApplication.run(PortalApplication.class, args);
34 |     }
35 | }
36 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/consumer/CreateConsumerParam.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.params.consumer;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.InputConverter;
23 | import com.alibaba.apiopenplatform.entity.Consumer;
24 | import lombok.Data;
25 | 
26 | import javax.validation.constraints.NotBlank;
27 | import javax.validation.constraints.Size;
28 | 
29 | @Data
30 | public class CreateConsumerParam implements InputConverter<Consumer> {
31 | 
32 |     @NotBlank(message = "Consumer名称不能为空")
33 |     @Size(max = 50, message = "Consumer名称长度不能超过50个字符")
34 |     private String name;
35 | 
36 |     @Size(max = 256, message = "Consumer描述长度不能超过256个字符")
37 |     private String description;
38 | }
39 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/APIResult.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.result;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
23 | import com.alibaba.apiopenplatform.support.enums.GatewayType;
24 | import com.aliyun.sdk.service.apig20240327.models.HttpApiApiInfo;
25 | import lombok.Data;
26 | 
27 | @Data
28 | public class APIResult implements OutputConverter<APIResult, HttpApiApiInfo> {
29 | 
30 |     private String apiId;
31 | 
32 |     private String apiName;
33 | 
34 |     @Override
35 |     public APIResult convertFrom(HttpApiApiInfo apiInfo) {
36 |         setApiId(apiInfo.getHttpApiId());
37 |         setApiName(apiInfo.getName());
38 |         return this;
39 |     }
40 | }
41 | 
```

--------------------------------------------------------------------------------
/deploy/docker/docker-compose.yml:
--------------------------------------------------------------------------------

```yaml
 1 | version: '3'
 2 | services:
 3 |   mysql:
 4 |     image: opensource-registry.cn-hangzhou.cr.aliyuncs.com/higress-group/mysql:1.0.0
 5 |     container_name: mysql
 6 |     environment:
 7 |       - MYSQL_ROOT_PASSWORD=123456
 8 |       - MYSQL_DATABASE=portal_db
 9 |       - MYSQL_USER=portal_user
10 |       - MYSQL_PASSWORD=portal_pass
11 |     ports:
12 |       - "3306:3306"
13 |     volumes:
14 |       - ./mysql/data:/var/lib/mysql
15 |     restart: always
16 | 
17 |   himarket-server:
18 |     image: opensource-registry.cn-hangzhou.cr.aliyuncs.com/higress-group/himarket-server:1.0.0
19 |     container_name: himarket-server
20 |     environment:
21 |       - DB_HOST=mysql
22 |       - DB_PORT=3306
23 |       - DB_NAME=portal_db
24 |       - DB_USERNAME=portal_user
25 |       - DB_PASSWORD=portal_pass
26 |     ports:
27 |       - "8080:8080"
28 |     depends_on:
29 |       - mysql
30 |     restart: always
31 | 
32 |   himarket-admin:
33 |     image: opensource-registry.cn-hangzhou.cr.aliyuncs.com/higress-group/himarket-admin:1.0.0
34 |     container_name: himarket-admin
35 |     environment:
36 |       - HIMARKET_SERVER=http://himarket-server:8080
37 |     ports:
38 |       - "5174:8000"
39 |     depends_on:
40 |       - himarket-server
41 |     restart: always
42 | 
43 |   himarket-frontend:
44 |     image: opensource-registry.cn-hangzhou.cr.aliyuncs.com/higress-group/himarket-frontend:1.0.0
45 |     container_name: himarket-frontend
46 |     environment:
47 |       - HIMARKET_SERVER=http://himarket-server:8080
48 |     ports:
49 |       - "5173:8000"
50 |     depends_on:
51 |       - himarket-server
52 |     restart: always
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/core/constant/CommonConstants.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.core.constant;
21 | 
22 | public class CommonConstants {
23 | 
24 |     // Token相关
25 |     public static final String AUTHORIZATION_HEADER = "Authorization";
26 |     public static final String BEARER_PREFIX = "Bearer ";
27 | 
28 |     // 角色前缀
29 |     public static final String ROLE_PREFIX = "ROLE_";
30 |     public static final String USER_TYPE = "userType";
31 |     public static final String USER_ID = "userId";
32 | 
33 |     // Cookie相关
34 |     public static final String AUTH_TOKEN_COOKIE = "auth_token";
35 | 
36 |     // HTTP
37 |     public static final Integer HTTP_PORT = 80;
38 |     public static final Integer HTTPS_PORT = 443;
39 | 
40 | }
41 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/consumer/UpdateCredentialParam.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.params.consumer;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.InputConverter;
23 | import com.alibaba.apiopenplatform.entity.ConsumerCredential;
24 | import com.alibaba.apiopenplatform.support.consumer.ApiKeyConfig;
25 | import com.alibaba.apiopenplatform.support.consumer.HmacConfig;
26 | import com.alibaba.apiopenplatform.support.consumer.JwtConfig;
27 | import lombok.Data;
28 | 
29 | @Data
30 | public class UpdateCredentialParam implements InputConverter<ConsumerCredential> {
31 | 
32 |     private ApiKeyConfig apiKeyConfig;
33 | 
34 |     private HmacConfig hmacConfig;
35 | 
36 |     private JwtConfig jwtConfig;
37 | }
38 | 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/src/router.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { Routes, Route } from "react-router-dom";
 2 | import Home from "./pages/Home";
 3 | import Apis from "./pages/Apis";
 4 | import ApiDetail from "./pages/ApiDetail";
 5 | import Consumers from "./pages/Consumers";
 6 | import ConsumerDetail from "./pages/ConsumerDetail";
 7 | import GettingStarted from "./pages/GettingStarted";
 8 | import Mcp from "./pages/Mcp";
 9 | import Login from "./pages/Login";
10 | import Register from "./pages/Register";
11 | import Profile from './pages/Profile'
12 | import McpDetail from "./pages/McpDetail";
13 | import Callback from "./pages/Callback";
14 | import OidcCallback from "./pages/OidcCallback";
15 | 
16 | export function Router() {
17 |   return (
18 |     <Routes>
19 |       <Route path="/" element={<Home />} />
20 |       <Route path="/getting-started" element={<GettingStarted />} />
21 |       <Route path="/apis" element={<Apis />} />
22 |       <Route path="/apis/:id" element={<ApiDetail />} />
23 |       <Route path="/consumers/:consumerId" element={<ConsumerDetail />} />
24 |       <Route path="/consumers" element={<Consumers />} />
25 |       <Route path="/mcp" element={<Mcp />} />
26 |       <Route path="/mcp/:mcpName" element={<McpDetail />} />
27 |       <Route path="/login" element={<Login />} />
28 |       <Route path="/register" element={<Register />} />
29 |       <Route path="/profile" element={<Profile />} />
30 |       <Route path="/callback" element={<Callback />} />
31 |       <Route path="/oidc/callback" element={<OidcCallback />} />
32 | 
33 |       {/* 其他页面可继续添加 */}
34 |     </Routes>
35 |   );
36 | } 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/converter/OutputConverter.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.converter;
21 | 
22 | import cn.hutool.core.bean.BeanUtil;
23 | import cn.hutool.core.bean.copier.CopyOptions;
24 | 
25 | public interface OutputConverter<Target extends OutputConverter<Target, Source>, Source> {
26 | 
27 |     /**
28 |      * 以Source更新Target
29 |      *
30 |      * @param source
31 |      * @return
32 |      */
33 |     @SuppressWarnings("unchecked")
34 |     default Target convertFrom(Source source) {
35 |         BeanUtil.copyProperties(source, this, configOptions());
36 |         return (Target) this;
37 |     }
38 | 
39 |     default CopyOptions configOptions() {
40 |         return CopyOptions.create().ignoreNullValue().ignoreError();
41 |     }
42 | }
43 | 
44 | 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/src/routes/index.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { createBrowserRouter, Navigate } from 'react-router-dom';
 2 | import LayoutWrapper from '@/components/LayoutWrapper';
 3 | import Portals from '@/pages/Portals';
 4 | import ApiProducts from '@/pages/ApiProducts';
 5 | import GatewayConsoles from '@/pages/GatewayConsoles';
 6 | import NacosConsoles from '@/pages/NacosConsoles';
 7 | import PortalDetail from '@/pages/PortalDetail';
 8 | import ApiProductDetail from '@/pages/ApiProductDetail';
 9 | import Login from '@/pages/Login';
10 | 
11 | export const router = createBrowserRouter([
12 |   {
13 |     path: '/login',
14 |     element: <Login />,
15 |   },
16 |   {
17 |     path: '/',
18 |     element: <LayoutWrapper />,
19 |     children: [
20 |       {
21 |         index: true,
22 |         element: <Navigate to="/portals" replace />,
23 |       },
24 |       {
25 |         path: 'portals',
26 |         element: <Portals />,
27 |       },
28 |       {
29 |         path: 'portals/detail',
30 |         element: <PortalDetail />,
31 |       },
32 |       {
33 |         path: 'api-products',
34 |         element: <ApiProducts />,
35 |       },
36 |       {
37 |         path: 'api-products/detail',
38 |         element: <ApiProductDetail />,
39 |       },
40 |       {
41 |         path: 'consoles',
42 |         element: <Navigate to="/consoles/gateway" replace />,
43 |       },
44 |       {
45 |         path: 'consoles/gateway',
46 |         element: <GatewayConsoles />,
47 |       },
48 |       {
49 |         path: 'consoles/nacos',
50 |         element: <NacosConsoles />,
51 |       },
52 |       {
53 |         path: '*',
54 |         element: <Navigate to="/portals" replace />,
55 |       },
56 |     ],
57 |   },
58 | ]);
59 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/ConsumerCredentialResult.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.result;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
23 | import com.alibaba.apiopenplatform.entity.ConsumerCredential;
24 | import com.alibaba.apiopenplatform.support.consumer.ApiKeyConfig;
25 | import com.alibaba.apiopenplatform.support.consumer.HmacConfig;
26 | import com.alibaba.apiopenplatform.support.consumer.JwtConfig;
27 | import lombok.Data;
28 | 
29 | @Data
30 | public class ConsumerCredentialResult implements OutputConverter<ConsumerCredentialResult, ConsumerCredential> {
31 | 
32 |     private JwtConfig jwtConfig;
33 | 
34 |     private HmacConfig hmacConfig;
35 | 
36 |     private ApiKeyConfig apiKeyConfig;
37 | }
38 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/portal/CreatePortalParam.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.params.portal;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.InputConverter;
23 | import com.alibaba.apiopenplatform.entity.Portal;
24 | import io.swagger.v3.oas.annotations.media.Schema;
25 | import lombok.Data;
26 | 
27 | import javax.validation.constraints.NotBlank;
28 | import javax.validation.constraints.Size;
29 | 
30 | @Schema(description = "创建门户参数")
31 | @Data
32 | public class CreatePortalParam implements InputConverter<Portal> {
33 | 
34 |     @NotBlank(message = "门户名称不能为空")
35 |     @Size(max = 50, message = "门户名称长度不能超过50个字符")
36 |     private String name;
37 | 
38 |     @Size(max = 1024, message = "门户描述长度不能超过1024个字符")
39 |     private String description;
40 | }
41 | 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/src/types/consumer.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import type { Product } from "./index";
 2 | 
 3 | export interface Consumer {
 4 |   consumerId: string;
 5 |   name: string;
 6 |   description?: string;
 7 |   status?: string;
 8 |   createAt?: string;
 9 |   enabled?: boolean;
10 | }
11 | 
12 | export type ConsumerCredential = HMACCredential | APIKeyCredential;
13 | 
14 | export interface HMACCredential {
15 |   ak?: string;
16 |   sk?: string;
17 |   mode?: 'SYSTEM' | 'CUSTOM';
18 | }
19 | 
20 | export interface APIKeyCredential {
21 |   apiKey?: string;
22 |   mode?: 'SYSTEM' | 'CUSTOM';
23 | }
24 | 
25 | export interface ConsumerCredentialResult {
26 |   apiKeyConfig?: {
27 |     credentials?: Array<{
28 |       apiKey?: string;
29 |       mode?: 'SYSTEM' | 'CUSTOM';
30 |     }>;
31 |     source?: string;
32 |     key?: string;
33 |   };
34 |   hmacConfig?: {
35 |     credentials?: Array<{
36 |       ak?: string;
37 |       sk?: string;
38 |       mode?: 'SYSTEM' | 'CUSTOM';
39 |     }>;
40 |   };
41 |   jwtConfig?: Record<string, unknown>;
42 | }
43 | 
44 | export interface Subscription {
45 |   productId: string;
46 |   consumerId: string;
47 |   status: 'PENDING' | 'APPROVED';
48 |   createAt: string;
49 |   updatedAt: string;
50 |   productName: string;
51 |   productType: 'REST_API' | 'MCP_SERVER';
52 |   consumerName?: string;
53 |   product?: Product;
54 | }
55 | 
56 | export interface CreateCredentialParam {
57 |   apiKeyConfig?: {
58 |     credentials?: Array<{
59 |       apiKey?: string;
60 |       mode?: 'SYSTEM' | 'CUSTOM';
61 |     }>;
62 |     source?: string;
63 |     key?: string;
64 |   };
65 |   hmacConfig?: {
66 |     credentials?: Array<{
67 |       ak?: string;
68 |       sk?: string;
69 |       mode?: 'SYSTEM' | 'CUSTOM';
70 |     }>;
71 |   };
72 |   jwtConfig?: Record<string, unknown>;
73 | } 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "portal-frontend",
 3 |   "private": true,
 4 |   "version": "0.0.0",
 5 |   "type": "module",
 6 |   "scripts": {
 7 |     "dev": "vite",
 8 |     "build": "tsc -b && vite build",
 9 |     "lint": "eslint .",
10 |     "preview": "vite preview",
11 |     "prepare": "husky",
12 |     "serve": "npm run build && npm start",
13 |     "type-check": "tsc -b"
14 |   },
15 |   "dependencies": {
16 |     "@ant-design/icons": "^5.2.7",
17 |     "antd": "^5.15.8",
18 |     "axios": "^1.10.0",
19 |     "clsx": "^2.1.1",
20 |     "js-yaml": "^4.1.0",
21 |     "monaco-editor": "^0.52.2",
22 |     "postcss": "^8.5.6",
23 |     "react": "^18.0.0",
24 |     "react-dom": "^18.0.0",
25 |     "react-markdown": "^10.1.0",
26 |     "react-markdown-editor-lite": "^1.3.4",
27 |     "react-monaco-editor": "^0.59.0",
28 |     "react-router-dom": "^6.23.1",
29 |     "remark-gfm": "^4.0.1",
30 |     "swagger-ui-react": "^5.29.0",
31 |     "terser": "^5.43.1"
32 |   },
33 |   "devDependencies": {
34 |     "@eslint/js": "^9.30.1",
35 |     "@types/js-yaml": "^4.0.9",
36 |     "@types/node": "^24.3.0",
37 |     "@types/react": "^18.3.3",
38 |     "@types/react-dom": "^18.3.3",
39 |     "@types/swagger-ui-react": "^5.18.0",
40 |     "@vitejs/plugin-react": "^4.6.0",
41 |     "autoprefixer": "^10.4.19",
42 |     "compression": "^1.8.1",
43 |     "eslint": "^9.30.1",
44 |     "eslint-plugin-react-hooks": "^5.2.0",
45 |     "eslint-plugin-react-refresh": "^0.4.20",
46 |     "globals": "^16.3.0",
47 |     "husky": "^9.1.7",
48 |     "postcss": "^8.5.6",
49 |     "tailwindcss": "^3.4.3",
50 |     "typescript": "~5.8.3",
51 |     "typescript-eslint": "^8.35.1",
52 |     "vite": "^4.5.14"
53 |   }
54 | }
55 | 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/src/index.css:
--------------------------------------------------------------------------------

```css
 1 | @tailwind base;
 2 | @tailwind components;
 3 | @tailwind utilities;
 4 | 
 5 | :root {
 6 |   --radius: 0.625rem;
 7 |   --background: oklch(1 0 0);
 8 |   --foreground: oklch(0.145 0 0);
 9 |   --card: oklch(1 0 0);
10 |   --card-foreground: oklch(0.145 0 0);
11 |   --popover: oklch(1 0 0);
12 |   --popover-foreground: oklch(0.145 0 0);
13 |   --primary: oklch(0.205 0 0);
14 |   --primary-foreground: oklch(0.985 0 0);
15 |   --secondary: oklch(0.97 0 0);
16 |   --secondary-foreground: oklch(0.205 0 0);
17 |   --muted: oklch(0.97 0 0);
18 |   --muted-foreground: oklch(0.556 0 0);
19 |   --accent: oklch(0.97 0 0);
20 |   --accent-foreground: oklch(0.205 0 0);
21 |   --destructive: oklch(0.577 0.245 27.325);
22 |   --border: oklch(0.922 0 0);
23 |   --input: oklch(0.922 0 0);
24 |   --ring: oklch(0.708 0 0);
25 | }
26 | 
27 | .dark {
28 |   --background: oklch(0.145 0 0);
29 |   --foreground: oklch(0.985 0 0);
30 |   --card: oklch(0.205 0 0);
31 |   --card-foreground: oklch(0.985 0 0);
32 |   --popover: oklch(0.205 0 0);
33 |   --popover-foreground: oklch(0.985 0 0);
34 |   --primary: oklch(0.922 0 0);
35 |   --primary-foreground: oklch(0.205 0 0);
36 |   --secondary: oklch(0.269 0 0);
37 |   --secondary-foreground: oklch(0.985 0 0);
38 |   --muted: oklch(0.269 0 0);
39 |   --muted-foreground: oklch(0.708 0 0);
40 |   --accent: oklch(0.269 0 0);
41 |   --accent-foreground: oklch(0.985 0 0);
42 |   --destructive: oklch(0.704 0.191 22.216);
43 |   --border: oklch(1 0 0 / 10%);
44 |   --input: oklch(1 0 0 / 15%);
45 |   --ring: oklch(0.556 0 0);
46 | }
47 | 
48 | @layer base {
49 |   * {
50 |     @apply border-gray-200;
51 |   }
52 |   body {
53 |     @apply bg-white text-gray-900;
54 |   }
55 | }
56 | 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/src/index.css:
--------------------------------------------------------------------------------

```css
 1 | @tailwind base;
 2 | @tailwind components;
 3 | @tailwind utilities;
 4 | 
 5 | :root {
 6 |   --radius: 0.625rem;
 7 |   --background: oklch(1 0 0);
 8 |   --foreground: oklch(0.145 0 0);
 9 |   --card: oklch(1 0 0);
10 |   --card-foreground: oklch(0.145 0 0);
11 |   --popover: oklch(1 0 0);
12 |   --popover-foreground: oklch(0.145 0 0);
13 |   --primary: oklch(0.205 0 0);
14 |   --primary-foreground: oklch(0.985 0 0);
15 |   --secondary: oklch(0.97 0 0);
16 |   --secondary-foreground: oklch(0.205 0 0);
17 |   --muted: oklch(0.97 0 0);
18 |   --muted-foreground: oklch(0.556 0 0);
19 |   --accent: oklch(0.97 0 0);
20 |   --accent-foreground: oklch(0.205 0 0);
21 |   --destructive: oklch(0.577 0.245 27.325);
22 |   --border: oklch(0.922 0 0);
23 |   --input: oklch(0.922 0 0);
24 |   --ring: oklch(0.708 0 0);
25 | }
26 | 
27 | .dark {
28 |   --background: oklch(0.145 0 0);
29 |   --foreground: oklch(0.985 0 0);
30 |   --card: oklch(0.205 0 0);
31 |   --card-foreground: oklch(0.985 0 0);
32 |   --popover: oklch(0.205 0 0);
33 |   --popover-foreground: oklch(0.985 0 0);
34 |   --primary: oklch(0.922 0 0);
35 |   --primary-foreground: oklch(0.205 0 0);
36 |   --secondary: oklch(0.269 0 0);
37 |   --secondary-foreground: oklch(0.985 0 0);
38 |   --muted: oklch(0.269 0 0);
39 |   --muted-foreground: oklch(0.708 0 0);
40 |   --accent: oklch(0.269 0 0);
41 |   --accent-foreground: oklch(0.985 0 0);
42 |   --destructive: oklch(0.704 0.191 22.216);
43 |   --border: oklch(1 0 0 / 10%);
44 |   --input: oklch(1 0 0 / 15%);
45 |   --ring: oklch(0.556 0 0);
46 | }
47 | 
48 | @layer base {
49 |   * {
50 |     @apply border-gray-200;
51 |   }
52 |   body {
53 |     @apply bg-white text-gray-900;
54 |   }
55 | }
56 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/HigressMCPServerResult.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.result;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
23 | import com.alibaba.apiopenplatform.service.gateway.HigressOperator.HigressMCPConfig;
24 | import lombok.Data;
25 | import lombok.EqualsAndHashCode;
26 | 
27 | @EqualsAndHashCode(callSuper = true)
28 | @Data
29 | public class HigressMCPServerResult extends GatewayMCPServerResult implements OutputConverter<HigressMCPServerResult, HigressMCPConfig> {
30 | 
31 |     @Override
32 |     public HigressMCPServerResult convertFrom(HigressMCPConfig mcp) {
33 |         HigressMCPServerResult r = OutputConverter.super.convertFrom(mcp);
34 |         r.setMcpServerName(mcp.getName());
35 |         return r;
36 |     }
37 | }
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/PortalRepository.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.repository;
21 | 
22 | import com.alibaba.apiopenplatform.entity.Portal;
23 | import org.springframework.data.domain.Page;
24 | import org.springframework.data.domain.Pageable;
25 | 
26 | import java.util.Optional;
27 | 
28 | public interface PortalRepository extends BaseRepository<Portal, Long> {
29 | 
30 |     Optional<Portal> findFirstByOrderByIdAsc();
31 | 
32 |     Optional<Portal> findByPortalIdAndAdminId(String portalId, String adminId);
33 | 
34 |     Optional<Portal> findByPortalId(String portalId);
35 | 
36 |     Optional<Portal> findByNameAndAdminId(String name, String adminId);
37 | 
38 |     Optional<Portal> findByName(String name);
39 | 
40 |     Page<Portal> findByAdminId(String adminId, Pageable pageable);
41 | }
42 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/SubscriptionResult.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.result;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
23 | import com.alibaba.apiopenplatform.entity.ProductSubscription;
24 | import com.alibaba.apiopenplatform.support.enums.ProductType;
25 | import lombok.Data;
26 | 
27 | import java.time.LocalDateTime;
28 | 
29 | @Data
30 | public class SubscriptionResult implements OutputConverter<SubscriptionResult, ProductSubscription> {
31 | 
32 |     private String productId;
33 | 
34 |     private String consumerId;
35 | 
36 |     private String status;
37 | 
38 |     private ProductType productType;
39 | 
40 |     private String productName;
41 | 
42 |     private String consumerName;
43 | 
44 |     private LocalDateTime createAt;
45 | 
46 |     private LocalDateTime updatedAt;
47 | }
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/support/portal/OidcConfig.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.support.portal;
21 | 
22 | import com.alibaba.apiopenplatform.support.enums.GrantType;
23 | import lombok.Data;
24 | 
25 | @Data
26 | public class OidcConfig {
27 |     /**
28 |      * 提供商
29 |      */
30 |     private String provider;
31 | 
32 |     /**
33 |      * 对外的名称
34 |      */
35 |     private String name;
36 | 
37 |     /**
38 |      * 登录按钮logo
39 |      */
40 |     private String logoUrl;
41 | 
42 |     /**
43 |      * 是否启用
44 |      */
45 |     private boolean enabled = true;
46 | 
47 |     /**
48 |      * 授权类型,默认授权码
49 |      */
50 |     private GrantType grantType = GrantType.AUTHORIZATION_CODE;
51 | 
52 |     /**
53 |      * 授权码模式配置
54 |      */
55 |     private AuthCodeConfig authCodeConfig;
56 | 
57 |     /**
58 |      * 身份映射
59 |      */
60 |     private IdentityMapping identityMapping = new IdentityMapping();
61 | }
62 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/portal/BindDomainParam.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.params.portal;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.InputConverter;
23 | import com.alibaba.apiopenplatform.entity.PortalDomain;
24 | import com.alibaba.apiopenplatform.support.enums.DomainType;
25 | import com.alibaba.apiopenplatform.support.enums.ProtocolType;
26 | import lombok.Data;
27 | 
28 | import javax.validation.constraints.NotBlank;
29 | import javax.validation.constraints.NotNull;
30 | 
31 | @Data
32 | public class BindDomainParam implements InputConverter<PortalDomain> {
33 | 
34 |     @NotBlank(message = "门户域名不能为空")
35 |     private String domain;
36 | 
37 |     @NotNull(message = "域名协议不能为空")
38 |     private ProtocolType protocol;
39 | 
40 |     private DomainType type = DomainType.CUSTOM;
41 | }
42 | 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/SubscriptionRepository.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.repository;
21 | 
22 | import com.alibaba.apiopenplatform.entity.ProductSubscription;
23 | 
24 | import java.util.List;
25 | import java.util.Optional;
26 | 
27 | public interface SubscriptionRepository extends BaseRepository<ProductSubscription, Long> {
28 | 
29 |     Optional<ProductSubscription> findByConsumerIdAndProductId(String consumerId, String productId);
30 | 
31 |     List<ProductSubscription> findALlByConsumerId(String consumerId);
32 | 
33 |     List<ProductSubscription> findAllByProductId(String productId);
34 | 
35 |     void deleteAllByConsumerId(String consumerId);
36 | 
37 |     void deleteAllByProductId(String productId);
38 | 
39 |     void deleteByConsumerIdAndProductId(String consumerId, String productId);
40 | }
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/core/response/Response.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.core.response;
21 | 
22 | import lombok.Data;
23 | import lombok.experimental.Accessors;
24 | import lombok.NoArgsConstructor;
25 | import lombok.AllArgsConstructor;
26 | 
27 | @Data
28 | @Accessors(chain = true)
29 | @NoArgsConstructor
30 | @AllArgsConstructor
31 | public class Response<T> {
32 |     private String code;
33 |     private String message;
34 |     private T data;
35 | 
36 |     public static <T> Response<T> ok(T data) {
37 |         return new Response<T>()
38 |                 .setCode("SUCCESS")
39 |                 .setData(data);
40 |     }
41 | 
42 |     public static <T> Response<T> fail(String code, String message) {
43 |         return new Response<T>()
44 |                 .setCode(code)
45 |                 .setMessage(message);
46 |     }
47 | }
48 | 
49 | 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/public/vite.svg:
--------------------------------------------------------------------------------

```
1 | <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/public/vite.svg:
--------------------------------------------------------------------------------

```
1 | <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/nacos/QueryNacosParam.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.params.nacos;
21 | 
22 | import lombok.Data;
23 | 
24 | import javax.validation.constraints.NotBlank;
25 | 
26 | import com.aliyun.teaopenapi.models.Config;
27 | 
28 | /**
29 |  * 查询Nacos集群参数
30 |  *
31 |  */
32 | @Data
33 | public class QueryNacosParam {
34 | 
35 |     @NotBlank(message = "地域不能为空")
36 |     private String regionId;
37 | 
38 |     @NotBlank(message = "accessKey不能为空")
39 |     private String accessKey;
40 | 
41 |     @NotBlank(message = "secretKey不能为空")
42 |     private String secretKey;
43 | 
44 |     public Config toClientConfig() {
45 |         Config config = new Config()
46 |                 .setAccessKeyId(this.accessKey)
47 |                 .setAccessKeySecret(this.secretKey)
48 |                 .setRegionId(this.regionId);
49 |         return config;
50 |     }
51 | }
52 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/service/gateway/client/GatewayClient.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.service.gateway.client;
21 | 
22 | import java.net.InetSocketAddress;
23 | import java.net.Socket;
24 | 
25 | public abstract class GatewayClient {
26 | 
27 |     public void close() {
28 | 
29 |     }
30 | 
31 |     protected String getAPIGEndpoint(String region) {
32 |         String internalEndpoint = String.format("apig-vpc.%s.aliyuncs.com", region);
33 |         String publicEndpoint = String.format("apig.%s.aliyuncs.com", region);
34 | 
35 |         // 优先尝试内网endpoint
36 |         try (Socket socket = new Socket()) {
37 |             socket.connect(new InetSocketAddress(internalEndpoint, 443), 1000); // 1秒超时
38 |             return internalEndpoint;
39 |         } catch (Exception e) {
40 |             return publicEndpoint;
41 |         }
42 |     }
43 | }
44 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/NacosMCPServerResult.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.result;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
23 | import com.alibaba.nacos.api.ai.model.mcp.McpServerBasicInfo;
24 | import lombok.Data;
25 | import lombok.EqualsAndHashCode;
26 | 
27 | @Data
28 | @EqualsAndHashCode(callSuper = true)
29 | public class NacosMCPServerResult extends MCPServerResult implements OutputConverter<NacosMCPServerResult, McpServerBasicInfo> {
30 | 
31 |     private String version;
32 | 
33 |     @Override
34 |     public NacosMCPServerResult convertFrom(McpServerBasicInfo basicInfo) {
35 |         OutputConverter.super.convertFrom(basicInfo);
36 |         setMcpServerName(basicInfo.getName());
37 |         setVersion(basicInfo.getVersion());
38 |         return this;
39 |     }
40 | } 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/DeveloperExternalIdentityRepository.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.repository;
21 | 
22 | import com.alibaba.apiopenplatform.entity.DeveloperExternalIdentity;
23 | import org.springframework.data.jpa.repository.JpaRepository;
24 | import java.util.List;
25 | import java.util.Optional;
26 | 
27 | public interface DeveloperExternalIdentityRepository extends JpaRepository<DeveloperExternalIdentity, Long> {
28 | 
29 |     List<DeveloperExternalIdentity> findByDeveloper_DeveloperId(String developerId);
30 | 
31 |     Optional<DeveloperExternalIdentity> findByProviderAndSubject(String provider, String subject);
32 | 
33 |     void deleteByProviderAndSubjectAndDeveloper_DeveloperId(String provider, String subject, String developerId);
34 | 
35 |     void deleteByDeveloper_DeveloperId(String developerId);
36 | }
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/portal/UpdatePortalParam.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.params.portal;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.InputConverter;
23 | import com.alibaba.apiopenplatform.entity.Portal;
24 | import com.alibaba.apiopenplatform.support.portal.PortalSettingConfig;
25 | import com.alibaba.apiopenplatform.support.portal.PortalUiConfig;
26 | import lombok.Data;
27 | 
28 | import javax.validation.constraints.Size;
29 | 
30 | @Data
31 | public class UpdatePortalParam implements InputConverter<Portal> {
32 | 
33 |     @Size(max = 50, message = "门户名称长度不能超过50个字符")
34 |     private String name;
35 | 
36 |     @Size(max = 1024, message = "门户描述长度不能超过1024个字符")
37 |     private String description;
38 | 
39 |     private PortalSettingConfig portalSettingConfig;
40 | 
41 |     private PortalUiConfig portalUiConfig;
42 | }
43 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/gateway/QueryAPIGParam.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.params.gateway;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.InputConverter;
23 | import com.alibaba.apiopenplatform.support.enums.GatewayType;
24 | import com.alibaba.apiopenplatform.support.gateway.APIGConfig;
25 | import lombok.Data;
26 | 
27 | import javax.validation.constraints.NotBlank;
28 | import javax.validation.constraints.NotNull;
29 | 
30 | @Data
31 | public class QueryAPIGParam implements InputConverter<APIGConfig> {
32 | 
33 |     @NotBlank(message = "网关region不能为空")
34 |     private String region;
35 | 
36 |     @NotNull(message = "网关类型不能为空")
37 |     private GatewayType gatewayType;
38 | 
39 |     @NotBlank(message = "accessKey不能为空")
40 |     private String accessKey;
41 | 
42 |     @NotBlank(message = "secretKey不能为空")
43 |     private String secretKey;
44 | }
45 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/developer/CreateDeveloperParam.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.params.developer;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.InputConverter;
23 | import com.alibaba.apiopenplatform.entity.Developer;
24 | import lombok.Data;
25 | import lombok.NoArgsConstructor;
26 | 
27 | import javax.validation.constraints.NotBlank;
28 | import javax.validation.constraints.Size;
29 | 
30 | @Data
31 | @NoArgsConstructor
32 | public class CreateDeveloperParam implements InputConverter<Developer> {
33 | 
34 |     @NotBlank(message = "用户名不能为空")
35 |     @Size(max = 64, message = "用户名长度不能超过64个字符")
36 |     private String username;
37 | 
38 |     @NotBlank(message = "密码不能为空")
39 |     @Size(min = 6, max = 32, message = "密码长度应为6-32位")
40 |     private String password;
41 | 
42 |     @Size(max = 256, message = "头像url长度不能超过256个字符")
43 |     private String avatarUrl;
44 | } 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/entity/BaseEntity.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.entity;
21 | 
22 | import lombok.Data;
23 | import org.springframework.data.annotation.CreatedDate;
24 | import org.springframework.data.annotation.LastModifiedDate;
25 | import org.springframework.data.jpa.domain.support.AuditingEntityListener;
26 | 
27 | import javax.persistence.*;
28 | import java.io.Serializable;
29 | import java.time.LocalDateTime;
30 | 
31 | @MappedSuperclass
32 | @EntityListeners(AuditingEntityListener.class)
33 | @Data
34 | public class BaseEntity implements Serializable {
35 | 
36 |     @CreatedDate
37 |     @Column(name = "created_at", updatable = false, columnDefinition = "datetime(3)")
38 |     private LocalDateTime createAt;
39 | 
40 |     @LastModifiedDate
41 |     @Column(name = "updated_at", columnDefinition = "datetime(3)")
42 |     private LocalDateTime updatedAt;
43 | }
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/ProductPublicationRepository.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.repository;
21 | 
22 | import com.alibaba.apiopenplatform.entity.ProductPublication;
23 | import org.springframework.data.domain.Page;
24 | import org.springframework.data.domain.Pageable;
25 | 
26 | import java.util.Optional;
27 | 
28 | public interface ProductPublicationRepository extends BaseRepository<ProductPublication, Long> {
29 | 
30 |     Page<ProductPublication> findByPortalId(String portalId, Pageable pageable);
31 | 
32 |     Optional<ProductPublication> findByPortalIdAndProductId(String portalId, String productId);
33 | 
34 |     Page<ProductPublication> findByProductId(String productId, Pageable pageable);
35 | 
36 |     void deleteByProductId(String productId);
37 | 
38 |     void deleteAllByPortalId(String portalId);
39 | 
40 |     boolean existsByProductId(String productId);
41 | }
42 | 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/ProductRefRepository.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.repository;
21 | 
22 | import com.alibaba.apiopenplatform.entity.ProductRef;
23 | import com.alibaba.apiopenplatform.support.enums.SourceType;
24 | import org.springframework.data.jpa.repository.JpaRepository;
25 | import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
26 | import org.springframework.stereotype.Repository;
27 | 
28 | import java.util.List;
29 | import java.util.Optional;
30 | 
31 | /**
32 |  * API Reference Repository
33 |  */
34 | @Repository
35 | public interface ProductRefRepository extends JpaRepository<ProductRef, Long>, JpaSpecificationExecutor<ProductRef> {
36 | 
37 |     Optional<ProductRef> findByProductId(String productId);
38 | 
39 |     Optional<ProductRef> findFirstByProductId(String productId);
40 | 
41 |     boolean existsByGatewayId(String gatewayId);
42 | }
43 | 
```

--------------------------------------------------------------------------------
/portal-dal/pom.xml:
--------------------------------------------------------------------------------

```
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <project xmlns="http://maven.apache.org/POM/4.0.0"
 3 |          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4 |          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5 |     <modelVersion>4.0.0</modelVersion>
 6 |     <parent>
 7 |         <groupId>com.alibaba.himarket</groupId>
 8 |         <artifactId>himarket</artifactId>
 9 |         <version>1.0-SNAPSHOT</version>
10 |     </parent>
11 | 
12 |     <artifactId>portal-dal</artifactId>
13 | 
14 |     <properties>
15 |         <maven.compiler.source>8</maven.compiler.source>
16 |         <maven.compiler.target>8</maven.compiler.target>
17 |         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
18 |     </properties>
19 | 
20 |     <dependencies>
21 |         <dependency>
22 |             <groupId>org.springframework.boot</groupId>
23 |             <artifactId>spring-boot-starter-data-jpa</artifactId>
24 |         </dependency>
25 | 
26 |         <dependency>
27 |             <groupId>org.mariadb.jdbc</groupId>
28 |             <artifactId>mariadb-java-client</artifactId>
29 |         </dependency>
30 | 
31 |         <dependency>
32 |             <groupId>org.projectlombok</groupId>
33 |             <artifactId>lombok</artifactId>
34 |         </dependency>
35 | 
36 |         <dependency>
37 |             <groupId>cn.hutool</groupId>
38 |             <artifactId>hutool-all</artifactId>
39 |         </dependency>
40 | 
41 |         <dependency>
42 |             <groupId>com.fasterxml.jackson.core</groupId>
43 |             <artifactId>jackson-databind</artifactId>
44 |             <version>2.14.0-rc1</version>
45 |         </dependency>
46 |     </dependencies>
47 | 
48 | </project>
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/AuthResult.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.result;
21 | 
22 | import cn.hutool.core.annotation.Alias;
23 | import com.fasterxml.jackson.annotation.JsonProperty;
24 | import lombok.Builder;
25 | import lombok.Data;
26 | 
27 | @Data
28 | @Builder
29 | public class AuthResult {
30 | 
31 |     @Alias("access_token")
32 |     @JsonProperty("access_token")
33 |     private String accessToken;
34 | 
35 |     @Alias("token_type")
36 |     @JsonProperty("token_type")
37 |     @Builder.Default
38 |     private String tokenType = "Bearer";
39 | 
40 |     @Alias("expires_in")
41 |     @JsonProperty("expires_in")
42 |     private Long expiresIn;
43 | 
44 |     public static AuthResult of(String accessToken, Long expiresIn) {
45 |         return AuthResult.builder()
46 |                 .accessToken(accessToken)
47 |                 .expiresIn(expiresIn)
48 |                 .build();
49 |     }
50 | } 
```

--------------------------------------------------------------------------------
/deploy/helm/templates/himarket-admin-deployment.yaml:
--------------------------------------------------------------------------------

```yaml
 1 | apiVersion: apps/v1
 2 | kind: Deployment
 3 | metadata:
 4 |   name: himarket-admin
 5 |   labels:
 6 |     app: himarket-admin
 7 | spec:
 8 |   replicas: {{ .Values.admin.replicaCount }}
 9 |   selector:
10 |     matchLabels:
11 |       app: himarket-admin
12 |   template:
13 |     metadata:
14 |       labels:
15 |         app: himarket-admin
16 |     spec:
17 |       {{- with .Values.imagePullSecrets }}
18 |       imagePullSecrets:
19 |         {{- toYaml . | nindent 8 }}
20 |       {{- end }}
21 |       serviceAccountName: {{ include "himarket.serviceAccountName" . }}
22 |       containers:
23 |         - name: admin
24 |           image: "{{ .Values.hub }}/{{ .Values.admin.image.repository }}:{{ .Values.admin.image.tag}}"
25 |           imagePullPolicy: {{ .Values.admin.image.pullPolicy }}
26 |           ports:
27 |             - name: http
28 |               containerPort: {{ .Values.admin.serverPort }}
29 |               protocol: TCP
30 |           envFrom:
31 |             - configMapRef:
32 |                 name: himarket-admin
33 |           {{- with .Values.resources }}
34 |           resources:
35 |             {{- toYaml . | nindent 12 }}
36 |           {{- end }}
37 |           {{- with .Values.volumeMounts }}
38 |           volumeMounts:
39 |             {{- toYaml . | nindent 12 }}
40 |           {{- end }}
41 |       {{- with .Values.volumes }}
42 |       volumes:
43 |         {{- toYaml . | nindent 8 }}
44 |       {{- end }}
45 |       {{- with .Values.nodeSelector }}
46 |       nodeSelector:
47 |         {{- toYaml . | nindent 8 }}
48 |       {{- end }}
49 |       {{- with .Values.affinity }}
50 |       affinity:
51 |         {{- toYaml . | nindent 8 }}
52 |       {{- end }}
53 |       {{- with .Values.tolerations }}
54 |       tolerations:
55 |         {{- toYaml . | nindent 8 }}
56 |       {{- end }}
57 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/APIGMCPServerResult.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.result;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
23 | import com.aliyun.sdk.service.apig20240327.models.HttpRoute;
24 | import lombok.Data;
25 | import lombok.EqualsAndHashCode;
26 | 
27 | @EqualsAndHashCode(callSuper = true)
28 | @Data
29 | public class APIGMCPServerResult extends GatewayMCPServerResult implements OutputConverter<APIGMCPServerResult, HttpRoute> {
30 | 
31 |     private String apiId;
32 | 
33 |     private String mcpServerId;
34 | 
35 |     private String mcpRouteId;
36 | 
37 |     @Override
38 |     public APIGMCPServerResult convertFrom(HttpRoute httpRoute) {
39 |         APIGMCPServerResult r = OutputConverter.super.convertFrom(httpRoute);
40 |         r.setMcpServerName(httpRoute.getName());
41 |         r.setMcpRouteId(httpRoute.getRouteId());
42 |         return r;
43 |     }
44 | }
45 | 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "portal-admin",
 3 |   "private": true,
 4 |   "version": "0.0.0",
 5 |   "type": "module",
 6 |   "scripts": {
 7 |     "dev": "vite",
 8 |     "build": "vite build",
 9 |     "lint": "eslint .",
10 |     "preview": "vite preview",
11 |     "start": "node server.js",
12 |     "serve": "npm run build && npm start",
13 |     "serve-live": "npx live-server dist --port=3000 --entry-file=index.html"
14 |   },
15 |   "dependencies": {
16 |     "@babel/runtime": "^8.0.0-alpha.17",
17 |     "antd": "^5.15.7",
18 |     "axios": "^1.7.9",
19 |     "clsx": "^2.1.1",
20 |     "helmet": "^7.1.0",
21 |     "js-yaml": "^4.1.0",
22 |     "monaco-editor": "^0.52.2",
23 |     "postcss": "^8.5.6",
24 |     "react": "^18.0.0",
25 |     "react-dom": "^18.0.0",
26 |     "react-markdown": "^10.1.0",
27 |     "react-markdown-editor-lite": "^1.3.4",
28 |     "react-monaco-editor": "^0.59.0",
29 |     "react-router-dom": "^6.28.0",
30 |     "remark-gfm": "^4.0.1",
31 |     "swagger-ui-react": "^5.29.0",
32 |     "tailwind-merge": "^3.3.1",
33 |     "terser": "^5.43.1"
34 |   },
35 |   "resolutions": {
36 |     "@babel/runtime": "^8.0.0-alpha.17"
37 |   },
38 |   "devDependencies": {
39 |     "@eslint/js": "^9.30.1",
40 |     "@types/js-yaml": "^4.0.9",
41 |     "@types/node": "^24.3.0",
42 |     "@types/react": "^18.3.3",
43 |     "@types/react-dom": "^18.3.3",
44 |     "@vitejs/plugin-react": "^4.7.0",
45 |     "autoprefixer": "^10.4.21",
46 |     "compression": "^1.8.0",
47 |     "cors": "^2.8.5",
48 |     "eslint": "^9.30.1",
49 |     "eslint-plugin-react-hooks": "^5.2.0",
50 |     "eslint-plugin-react-refresh": "^0.4.20",
51 |     "express": "^4.21.2",
52 |     "globals": "^16.3.0",
53 |     "path": "^0.12.7",
54 |     "postcss": "^8.5.6",
55 |     "tailwindcss": "^3.4.17",
56 |     "typescript": "^5.6.3",
57 |     "url": "^0.11.4",
58 |     "vite": "^4.5.14"
59 |   }
60 | }
61 | 
```

--------------------------------------------------------------------------------
/deploy/helm/templates/himarket-frontend-deployment.yaml:
--------------------------------------------------------------------------------

```yaml
 1 | apiVersion: apps/v1
 2 | kind: Deployment
 3 | metadata:
 4 |   name: himarket-frontend
 5 |   labels:
 6 |     app: himarket-frontend
 7 | spec:
 8 |   replicas: {{ .Values.frontend.replicaCount }}
 9 |   selector:
10 |     matchLabels:
11 |       app: himarket-frontend
12 |   template:
13 |     metadata:
14 |       labels:
15 |         app: himarket-frontend
16 |     spec:
17 |       {{- with .Values.imagePullSecrets }}
18 |       imagePullSecrets:
19 |         {{- toYaml . | nindent 8 }}
20 |       {{- end }}
21 |       serviceAccountName: {{ include "himarket.serviceAccountName" . }}
22 |       containers:
23 |         - name: frontend
24 |           image: "{{ .Values.hub }}/{{ .Values.frontend.image.repository }}:{{ .Values.frontend.image.tag}}"
25 |           imagePullPolicy: {{ .Values.frontend.image.pullPolicy }}
26 |           ports:
27 |             - name: http
28 |               containerPort: {{ .Values.frontend.serverPort }}
29 |               protocol: TCP
30 |           envFrom:
31 |             - configMapRef:
32 |                 name: himarket-frontend
33 |           {{- with .Values.resources }}
34 |           resources:
35 |             {{- toYaml . | nindent 12 }}
36 |           {{- end }}
37 |           {{- with .Values.volumeMounts }}
38 |           volumeMounts:
39 |             {{- toYaml . | nindent 12 }}
40 |           {{- end }}
41 |       {{- with .Values.volumes }}
42 |       volumes:
43 |         {{- toYaml . | nindent 8 }}
44 |       {{- end }}
45 |       {{- with .Values.nodeSelector }}
46 |       nodeSelector:
47 |         {{- toYaml . | nindent 8 }}
48 |       {{- end }}
49 |       {{- with .Values.affinity }}
50 |       affinity:
51 |         {{- toYaml . | nindent 8 }}
52 |       {{- end }}
53 |       {{- with .Values.tolerations }}
54 |       tolerations:
55 |         {{- toYaml . | nindent 8 }}
56 |       {{- end }}
57 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/consumer/CreateCredentialParam.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.params.consumer;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.InputConverter;
23 | import com.alibaba.apiopenplatform.entity.ConsumerCredential;
24 | import com.alibaba.apiopenplatform.support.consumer.ApiKeyConfig;
25 | import com.alibaba.apiopenplatform.support.consumer.HmacConfig;
26 | import com.alibaba.apiopenplatform.support.consumer.JwtConfig;
27 | import lombok.Data;
28 | 
29 | import javax.validation.constraints.AssertTrue;
30 | 
31 | @Data
32 | public class CreateCredentialParam implements InputConverter<ConsumerCredential> {
33 | 
34 |     private ApiKeyConfig apiKeyConfig;
35 | 
36 |     private HmacConfig hmacConfig;
37 | 
38 |     private JwtConfig jwtConfig;
39 | 
40 |     @AssertTrue(message = "凭证信息不能为空")
41 |     private boolean isValid() {
42 |         return apiKeyConfig != null || hmacConfig != null || jwtConfig != null;
43 |     }
44 | }
45 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/nacos/CreateNacosParam.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.params.nacos;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.InputConverter;
23 | import com.alibaba.apiopenplatform.entity.NacosInstance;
24 | 
25 | import lombok.Data;
26 | 
27 | import javax.validation.constraints.NotBlank;
28 | 
29 | /**
30 |  * 创建Nacos实例参数
31 |  *
32 |  */
33 | @Data
34 | public class CreateNacosParam implements InputConverter<NacosInstance> {
35 | 
36 |     @NotBlank(message = "Nacos名称不能为空")
37 |     private String nacosName;
38 | 
39 |     @NotBlank(message = "服务器地址不能为空")
40 |     private String serverUrl;
41 | 
42 |     /**
43 |      * 可选:客户端指定的 nacosId,若为空则由服务端生成
44 |      */
45 |     private String nacosId;
46 | 
47 |     // namespace removed from create param as it's no longer stored on instance
48 | 
49 |     private String username;
50 | 
51 |     private String password;
52 | 
53 |     private String accessKey;
54 | 
55 |     private String secretKey;
56 | 
57 |     private String description;
58 | }
59 | 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/support/enums/GatewayType.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.support.enums;
21 | 
22 | import lombok.Getter;
23 | import lombok.RequiredArgsConstructor;
24 | 
25 | @RequiredArgsConstructor
26 | @Getter
27 | public enum GatewayType {
28 | 
29 |     /**
30 |      * 云原生API网关
31 |      */
32 |     APIG_API("API"),
33 | 
34 |     /**
35 |      * AI网关
36 |      */
37 |     APIG_AI("AI"),
38 | 
39 |     /**
40 |      * ADP AI网关
41 |      */
42 |     ADP_AI_GATEWAY("ADP_AI_GATEWAY"),
43 | 
44 |     /**
45 |      * Higress
46 |      */
47 |     HIGRESS("Higress"),
48 | 
49 |     ;
50 | 
51 |     private final String type;
52 | 
53 |     public boolean isHigress() {
54 |         return this == HIGRESS;
55 |     }
56 | 
57 |     public boolean isAPIG() {
58 |         return this == APIG_API || this == APIG_AI || this == ADP_AI_GATEWAY;
59 |     }
60 | 
61 |     public boolean isAIGateway() {
62 |         return this == APIG_AI || this == ADP_AI_GATEWAY;
63 |     }
64 | 
65 |     public boolean isAdpAIGateway() {
66 |         return this == ADP_AI_GATEWAY;
67 |     }
68 | }
69 | 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/BaseRepository.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.repository;
21 | 
22 | import com.alibaba.apiopenplatform.entity.ProductPublication;
23 | import org.springframework.data.domain.Sort;
24 | import org.springframework.data.jpa.repository.JpaRepository;
25 | import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
26 | import org.springframework.data.repository.NoRepositoryBean;
27 | import org.springframework.lang.NonNull;
28 | 
29 | import java.util.Collection;
30 | import java.util.List;
31 | 
32 | /**
33 |  * 基础数据访问接口,提供通用的数据库操作方法
34 |  *
35 |  * @param <D> 实体类型(Domain/Entity)
36 |  * @param <I> 主键类型(ID)
37 |  */
38 | @NoRepositoryBean
39 | public interface BaseRepository<D, I> extends JpaRepository<D, I>, JpaSpecificationExecutor<D> {
40 | 
41 |     /**
42 |      * 根据ID集合批量查询实体列表
43 |      *
44 |      * @param ids
45 |      * @param sort
46 |      * @return
47 |      */
48 |     List<D> findAllByIdIn(@NonNull Collection<I> ids, @NonNull Sort sort);
49 | }
50 | 
51 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/controller/OidcController.java:
--------------------------------------------------------------------------------

```java
 1 | package com.alibaba.apiopenplatform.controller;
 2 | 
 3 | import com.alibaba.apiopenplatform.dto.result.AuthResult;
 4 | import com.alibaba.apiopenplatform.dto.result.IdpResult;
 5 | import com.alibaba.apiopenplatform.service.OidcService;
 6 | import lombok.RequiredArgsConstructor;
 7 | import lombok.extern.slf4j.Slf4j;
 8 | import org.springframework.web.bind.annotation.*;
 9 | 
10 | import javax.servlet.http.HttpServletRequest;
11 | import javax.servlet.http.HttpServletResponse;
12 | import java.io.IOException;
13 | import java.util.List;
14 | 
15 | @Slf4j
16 | @RestController
17 | @RequestMapping("/developers/oidc")
18 | @RequiredArgsConstructor
19 | public class OidcController {
20 | 
21 |     private final OidcService oidcService;
22 | 
23 |     @GetMapping("/authorize")
24 |     public void authorize(@RequestParam String provider,
25 |                           @RequestParam(defaultValue = "/api/v1") String apiPrefix,
26 |                           HttpServletRequest request,
27 |                           HttpServletResponse response) throws IOException {
28 |         String authUrl = oidcService.buildAuthorizationUrl(provider, apiPrefix, request);
29 | 
30 |         log.info("Redirecting to OIDC authorization URL: {}", authUrl);
31 |         response.sendRedirect(authUrl);
32 |     }
33 | 
34 |     @GetMapping("/callback")
35 |     public AuthResult callback(@RequestParam String code,
36 |                                @RequestParam String state,
37 |                                HttpServletRequest request,
38 |                                HttpServletResponse response) {
39 |         return oidcService.handleCallback(code, state, request, response);
40 |     }
41 | 
42 |     @GetMapping("/providers")
43 |     public List<IdpResult> getProviders() {
44 |         return oidcService.getAvailableProviders();
45 |     }
46 | }
47 | 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/entity/Administrator.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.entity;
21 | 
22 | import javax.persistence.*;
23 | import java.util.Date;
24 | import lombok.Data;
25 | import lombok.NoArgsConstructor;
26 | import lombok.AllArgsConstructor;
27 | import lombok.Builder;
28 | 
29 | /**
30 |  * 管理员实体类,映射管理员账号信息
31 |  *
32 |  */
33 | @Data
34 | @NoArgsConstructor
35 | @AllArgsConstructor
36 | @Builder
37 | @Entity
38 | @Table(name = "administrator", uniqueConstraints = {
39 |         @UniqueConstraint(columnNames = {"adminId"}),
40 |         @UniqueConstraint(columnNames = {"username"})
41 | })
42 | public class Administrator extends BaseEntity {
43 |     @Id
44 |     @GeneratedValue(strategy = GenerationType.IDENTITY)
45 |     private Long id;
46 | 
47 |     @Column(nullable = false, unique = true, length = 64)
48 |     private String adminId;
49 | 
50 |     @Column(nullable = false, unique = true, length = 64)
51 |     private String username;
52 | 
53 |     @Column(nullable = false)
54 |     private String passwordHash;
55 | 
56 | } 
```

--------------------------------------------------------------------------------
/portal-bootstrap/pom.xml:
--------------------------------------------------------------------------------

```
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <project xmlns="http://maven.apache.org/POM/4.0.0"
 3 |          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4 |          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5 |     <modelVersion>4.0.0</modelVersion>
 6 |     <parent>
 7 |         <groupId>com.alibaba.himarket</groupId>
 8 |         <artifactId>himarket</artifactId>
 9 |         <version>1.0-SNAPSHOT</version>
10 |     </parent>
11 | 
12 |     <artifactId>portal-bootstrap</artifactId>
13 | 
14 |     <properties>
15 |         <maven.compiler.source>8</maven.compiler.source>
16 |         <maven.compiler.target>8</maven.compiler.target>
17 |         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
18 |     </properties>
19 | 
20 |     <dependencies>
21 |         <dependency>
22 |             <groupId>com.alibaba.himarket</groupId>
23 |             <artifactId>portal-server</artifactId>
24 |             <version>1.0-SNAPSHOT</version>
25 |         </dependency>
26 | 
27 |         <!-- OkHttp for RestTemplate -->
28 |         <dependency>
29 |             <groupId>com.squareup.okhttp3</groupId>
30 |             <artifactId>okhttp</artifactId>
31 |         </dependency>
32 | 
33 |     </dependencies>
34 | 
35 |     <build>
36 |         <plugins>
37 |             <plugin>
38 |                 <groupId>org.springframework.boot</groupId>
39 |                 <artifactId>spring-boot-maven-plugin</artifactId>
40 |                 <version>2.7.18</version>
41 |                 <executions>
42 |                     <execution>
43 |                         <goals>
44 |                             <goal>repackage</goal>
45 |                         </goals>
46 |                     </execution>
47 |                 </executions>
48 |             </plugin>
49 |         </plugins>
50 |     </build>
51 | 
52 | </project>
```

--------------------------------------------------------------------------------
/portal-bootstrap/src/main/java/com/alibaba/apiopenplatform/config/AsyncConfig.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.config;
21 | 
22 | import org.springframework.context.annotation.Bean;
23 | import org.springframework.context.annotation.Configuration;
24 | import org.springframework.scheduling.annotation.EnableAsync;
25 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
26 | 
27 | import java.util.concurrent.Executor;
28 | import java.util.concurrent.ThreadPoolExecutor;
29 | 
30 | @Configuration
31 | @EnableAsync
32 | public class AsyncConfig {
33 | 
34 |     @Bean("taskExecutor")
35 |     public Executor getTaskExecutor() {
36 |         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
37 |         executor.setCorePoolSize(5);
38 |         executor.setMaxPoolSize(10);
39 |         executor.setQueueCapacity(25);
40 |         executor.setThreadNamePrefix("TaskExecutor-");
41 |         executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
42 |         executor.initialize();
43 |         return executor;
44 |     }
45 | }
46 | 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/DeveloperRepository.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.repository;
21 | 
22 | import com.alibaba.apiopenplatform.entity.Developer;
23 | import org.springframework.data.domain.Page;
24 | import org.springframework.data.domain.Pageable;
25 | import org.springframework.data.jpa.repository.JpaRepository;
26 | 
27 | import java.util.Optional;
28 | import java.util.List;
29 | 
30 | public interface DeveloperRepository extends BaseRepository<Developer, Long> {
31 | 
32 |     Optional<Developer> findByDeveloperId(String developerId);
33 | 
34 |     Optional<Developer> findByUsername(String username);
35 | 
36 |     List<Developer> findByPortalId(String portalId);
37 | 
38 |     Optional<Developer> findByPortalIdAndUsername(String portalId, String username);
39 | 
40 |     Optional<Developer> findByPortalIdAndEmail(String portalId, String email);
41 | 
42 |     Optional<Developer> findByDeveloperIdAndPortalId(String developerId, String portalId);
43 | 
44 |     Page<Developer> findByPortalId(String portalId, Pageable pageable);
45 | } 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/MseNacosResult.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.result;
21 | 
22 | import com.aliyun.mse20190531.models.ListClustersResponseBody.ListClustersResponseBodyData;
23 | 
24 | import lombok.Data;
25 | 
26 | @Data
27 | public class MseNacosResult {
28 |     private String instanceId;
29 | 
30 |     private String name;
31 | 
32 |     private String serverIntranetEndpoint;
33 | 
34 |     private String serverInternetEndpoint;
35 | 
36 |     private String version;
37 | 
38 |     public static MseNacosResult fromListClustersResponseBodyData(ListClustersResponseBodyData cluster) {
39 |         MseNacosResult nacosResult = new MseNacosResult();
40 |         nacosResult.setName(cluster.getClusterAliasName());
41 |         nacosResult.setVersion(cluster.getVersionCode());
42 |         nacosResult.setInstanceId(cluster.getInstanceId());
43 |         nacosResult.setServerIntranetEndpoint(cluster.getIntranetDomain());
44 |         nacosResult.setServerInternetEndpoint(cluster.getInternetDomain());
45 |         return nacosResult;
46 |     }
47 | }
48 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/ProductRefResult.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.result;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
23 | import com.alibaba.apiopenplatform.entity.ProductRef;
24 | import com.alibaba.apiopenplatform.support.enums.SourceType;
25 | import com.alibaba.apiopenplatform.support.product.APIGRefConfig;
26 | import com.alibaba.apiopenplatform.support.product.HigressRefConfig;
27 | import com.alibaba.apiopenplatform.support.product.NacosRefConfig;
28 | import lombok.Data;
29 | 
30 | @Data
31 | public class ProductRefResult implements OutputConverter<ProductRefResult, ProductRef> {
32 | 
33 |     private String productId;
34 | 
35 |     private SourceType sourceType;
36 | 
37 |     private String gatewayId;
38 | 
39 |     private APIGRefConfig apigRefConfig;
40 | 
41 |     // 新增:ADP AI 网关引用配置(与 APIGRefConfig 结构一致)
42 |     private APIGRefConfig adpAIGatewayRefConfig;
43 | 
44 |     private HigressRefConfig higressRefConfig;
45 | 
46 |     private String nacosId;
47 | 
48 |     private NacosRefConfig nacosRefConfig;
49 | }
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/ProductRepository.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.repository;
21 | 
22 | import org.springframework.stereotype.Repository;
23 | import org.springframework.data.domain.Page;
24 | import org.springframework.data.domain.Pageable;
25 | 
26 | import java.util.Collection;
27 | import java.util.List;
28 | import java.util.Optional;
29 | 
30 | import com.alibaba.apiopenplatform.entity.Product;
31 | 
32 | @Repository
33 | public interface ProductRepository extends BaseRepository<Product, Long> {
34 | 
35 |     Optional<Product> findByProductId(String productId);
36 | 
37 |     Optional<Product> findByProductIdAndAdminId(String productId, String adminId);
38 | 
39 |     Optional<Product> findByNameAndAdminId(String name, String adminId);
40 | 
41 |     Page<Product> findByProductIdIn(Collection<String> productIds, Pageable pageable);
42 | 
43 |     List<Product> findByProductIdIn(Collection<String> productIds);
44 | 
45 |     Page<Product> findByAdminId(String adminId, Pageable pageable);
46 | 
47 |     Page<Product> findByCategory(String category, Pageable pageable);
48 | }
49 | 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/repository/ConsumerRepository.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.repository;
21 | 
22 | import com.alibaba.apiopenplatform.entity.Consumer;
23 | import org.springframework.data.domain.Page;
24 | import org.springframework.data.domain.Pageable;
25 | 
26 | import java.util.Collection;
27 | import java.util.List;
28 | import java.util.Optional;
29 | 
30 | public interface ConsumerRepository extends BaseRepository<Consumer, Long> {
31 | 
32 |     Optional<Consumer> findByConsumerId(String consumerId);
33 | 
34 |     Optional<Consumer> findByDeveloperIdAndConsumerId(String developerId, String consumerId);
35 | 
36 |     Optional<Consumer> findByDeveloperIdAndName(String developerId, String name);
37 | 
38 |     Page<Consumer> findByDeveloperId(String developerId, Pageable pageable);
39 | 
40 |     Page<Consumer> findByPortalId(String portalId, Pageable pageable);
41 | 
42 |     List<Consumer> findAllByDeveloperId(String developerId);
43 | 
44 |     void deleteAllByDeveloperId(String developerId);
45 | 
46 |     List<Consumer> findByConsumerIdIn(Collection<String> consumerIds);
47 | }
48 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/product/UpdateProductParam.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.params.product;
21 | 
22 | import cn.hutool.core.util.StrUtil;
23 | import com.alibaba.apiopenplatform.dto.converter.InputConverter;
24 | import com.alibaba.apiopenplatform.entity.Product;
25 | import com.alibaba.apiopenplatform.support.enums.ProductType;
26 | import com.alibaba.apiopenplatform.support.product.ProductIcon;
27 | import lombok.Data;
28 | 
29 | import javax.validation.constraints.AssertTrue;
30 | 
31 | @Data
32 | public class UpdateProductParam implements InputConverter<Product> {
33 | 
34 |     private String name;
35 | 
36 |     private String description;
37 | 
38 |     private ProductType type;
39 | 
40 |     private Boolean enableConsumerAuth;
41 | 
42 |     private String document;
43 | 
44 |     private ProductIcon icon;
45 | 
46 |     private String category;
47 | 
48 |     private Boolean autoApprove;
49 | 
50 |     @AssertTrue(message = "Icon大小不能超过16KB")
51 |     public boolean checkIcon() {
52 |         if (icon == null || StrUtil.isBlank(icon.getValue())) {
53 |             return true;
54 |         }
55 |         return icon.getValue().length() < 16 * 1024;
56 |     }
57 | }
58 | 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/src/types/api-product.ts:
--------------------------------------------------------------------------------

```typescript
 1 | export interface ApiProductConfig {
 2 |   spec: string;
 3 |   meta: {
 4 |     source: string;
 5 |     type: string;
 6 |   }
 7 | }
 8 | 
 9 | // 产品图标类型
10 | export interface ProductIcon {
11 |   type: 'URL' | 'BASE64';
12 |   value: string;
13 | }
14 | 
15 | export interface ApiProductMcpConfig {
16 |   mcpServerName: string;
17 |   tools: string;
18 |   meta: {
19 |     source: string;
20 |     mcpServerName: string;
21 |     mcpServerConfig: any;
22 |     fromType: string;
23 |     protocol?: string;
24 |   }
25 |   mcpServerConfig: {
26 |     path: string;
27 |     domains: {
28 |       domain: string;
29 |       protocol: string;
30 |     }[];
31 |     rawConfig?: unknown;
32 |   }
33 | }
34 | 
35 | // API 配置相关类型
36 | export interface RestAPIItem {
37 |   apiId: string;
38 |   apiName: string;
39 | }
40 | 
41 | export interface HigressMCPItem {
42 |   mcpServerName: string;
43 |   fromGatewayType: 'HIGRESS';
44 | }
45 | 
46 | export interface NacosMCPItem {
47 |   mcpServerName: string;
48 |   fromGatewayType: 'NACOS';
49 |   namespaceId: string;
50 | }
51 | 
52 | export interface APIGAIMCPItem {
53 |   mcpServerName: string;
54 |   fromGatewayType: 'APIG_AI' | 'ADP_AI_GATEWAY';
55 |   mcpRouteId: string;
56 |   mcpServerId?: string;
57 |   apiId?: string;
58 |   type?: string;
59 | }
60 | 
61 | export type ApiItem = RestAPIItem | HigressMCPItem | APIGAIMCPItem | NacosMCPItem;
62 | 
63 | // 关联服务配置
64 | export interface LinkedService {
65 |   productId: string;
66 |   gatewayId?: string;
67 |   nacosId?: string;
68 |   sourceType: 'GATEWAY' | 'NACOS';
69 |   apigRefConfig?: RestAPIItem | APIGAIMCPItem;
70 |   higressRefConfig?: HigressMCPItem;
71 |   nacosRefConfig?: NacosMCPItem;
72 |   adpAIGatewayRefConfig?: APIGAIMCPItem;
73 | }
74 | 
75 | export interface ApiProduct {
76 |   productId: string;
77 |   name: string;
78 |   description: string;
79 |   type: 'REST_API' | 'MCP_SERVER';
80 |   category: string;
81 |   status: 'PENDING' | 'READY' | 'PUBLISHED' | string;
82 |   createAt: string;
83 |   enableConsumerAuth?: boolean;
84 |   autoApprove?: boolean;
85 |   apiConfig?: ApiProductConfig;
86 |   mcpConfig?: ApiProductMcpConfig;
87 |   document?: string;
88 |   icon?: ProductIcon | null;
89 | } 
90 | 
```

--------------------------------------------------------------------------------
/portal-bootstrap/src/main/java/com/alibaba/apiopenplatform/config/RestTemplateConfig.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.config;
21 | 
22 | import lombok.RequiredArgsConstructor;
23 | import okhttp3.ConnectionPool;
24 | import okhttp3.OkHttpClient;
25 | import org.springframework.context.annotation.Bean;
26 | import org.springframework.context.annotation.Configuration;
27 | import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
28 | import org.springframework.web.client.RestTemplate;
29 | 
30 | import java.util.concurrent.TimeUnit;
31 | 
32 | @Configuration
33 | public class RestTemplateConfig {
34 | 
35 |     @Bean
36 |     public RestTemplate restTemplate(OkHttpClient okHttpClient) {
37 |         // 使用OkHttp作为RestTemplate的底层客户端
38 |         return new RestTemplate(new OkHttp3ClientHttpRequestFactory(okHttpClient));
39 |     }
40 | 
41 |     @Bean
42 |     public OkHttpClient okHttpClient() {
43 |         return new OkHttpClient.Builder()
44 |                 .connectTimeout(5, TimeUnit.SECONDS)
45 |                 .readTimeout(5, TimeUnit.SECONDS)
46 |                 .writeTimeout(5, TimeUnit.SECONDS)
47 |                 .connectionPool(new ConnectionPool(10, 5, TimeUnit.MINUTES))
48 |                 .build();
49 |     }
50 | }
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/product/CreateProductRefParam.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.params.product;
21 | 
22 | import cn.hutool.core.util.StrUtil;
23 | import com.alibaba.apiopenplatform.dto.converter.InputConverter;
24 | import com.alibaba.apiopenplatform.entity.ProductRef;
25 | import com.alibaba.apiopenplatform.support.enums.SourceType;
26 | import com.alibaba.apiopenplatform.support.product.APIGRefConfig;
27 | import com.alibaba.apiopenplatform.support.product.HigressRefConfig;
28 | import com.alibaba.apiopenplatform.support.product.NacosRefConfig;
29 | import lombok.Data;
30 | 
31 | import javax.validation.constraints.AssertTrue;
32 | import javax.validation.constraints.NotNull;
33 | 
34 | @Data
35 | public class CreateProductRefParam implements InputConverter<ProductRef> {
36 | 
37 |     @NotNull(message = "数据源类型不能为空")
38 |     private SourceType sourceType;
39 | 
40 |     private String gatewayId;
41 | 
42 |     private String nacosId;
43 | 
44 |     private APIGRefConfig apigRefConfig;
45 | 
46 |     // 新增:ADP AI 网关引用配置(与 APIGRefConfig 结构一致)
47 |     private APIGRefConfig adpAIGatewayRefConfig;
48 | 
49 |     private HigressRefConfig higressRefConfig;
50 | 
51 |     private NacosRefConfig nacosRefConfig;
52 | 
53 | }
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/ProductResult.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.result;
21 | 
22 | import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
23 | import com.alibaba.apiopenplatform.entity.Product;
24 | import com.alibaba.apiopenplatform.support.enums.ProductStatus;
25 | import com.alibaba.apiopenplatform.support.enums.ProductType;
26 | import com.alibaba.apiopenplatform.support.product.ProductIcon;
27 | import lombok.Data;
28 | 
29 | import java.time.LocalDateTime;
30 | 
31 | @Data
32 | public class ProductResult implements OutputConverter<ProductResult, Product> {
33 | 
34 |     private String productId;
35 | 
36 |     private String name;
37 | 
38 |     private String description;
39 | 
40 |     private ProductStatus status = ProductStatus.PENDING;
41 | 
42 |     private Boolean enableConsumerAuth = false;
43 | 
44 |     private ProductType type;
45 | 
46 |     private String document;
47 | 
48 |     private ProductIcon icon;
49 | 
50 |     private String category;
51 | 
52 |     private Boolean autoApprove;
53 | 
54 |     private LocalDateTime createAt;
55 | 
56 |     private LocalDateTime updatedAt;
57 | 
58 |     private APIConfigResult apiConfig;
59 | 
60 |     private MCPConfigResult mcpConfig;
61 | 
62 |     private Boolean enabled;
63 | }
64 | 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/src/components/console/NacosTypeSelector.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { Modal, Radio, Button, Space } from 'antd'
 2 | import { useState } from 'react'
 3 | 
 4 | export type NacosImportType = 'OPEN_SOURCE' | 'MSE'
 5 | 
 6 | interface NacosTypeSelectorProps {
 7 |   visible: boolean
 8 |   onCancel: () => void
 9 |   onSelect: (type: NacosImportType) => void
10 | }
11 | 
12 | export default function NacosTypeSelector({ visible, onCancel, onSelect }: NacosTypeSelectorProps) {
13 |   const [selectedType, setSelectedType] = useState<NacosImportType>('MSE')
14 | 
15 |   const handleConfirm = () => {
16 |     onSelect(selectedType)
17 |   }
18 | 
19 |   const handleCancel = () => {
20 |   setSelectedType('OPEN_SOURCE')
21 |     onCancel()
22 |   }
23 | 
24 |   return (
25 |     <Modal
26 |       title="选择 Nacos 类型"
27 |       open={visible}
28 |       onCancel={handleCancel}
29 |       footer={[
30 |         <Button key="cancel" onClick={handleCancel}>
31 |           取消
32 |         </Button>,
33 |         <Button key="confirm" type="primary" onClick={handleConfirm}>
34 |           确定
35 |         </Button>
36 |       ]}
37 |       width={500}
38 |     >
39 |       <div className="py-4">
40 |         <Radio.Group 
41 |           value={selectedType} 
42 |           onChange={(e) => setSelectedType(e.target.value)}
43 |           className="w-full"
44 |         >
45 |           <Space direction="vertical" className="w-full">
46 |             <Radio value="MSE" className="w-full p-3 border rounded-lg hover:bg-gray-50">
47 |               <div className="ml-2">
48 |                 <div className="font-medium">MSE Nacos</div>
49 |                 <div className="text-sm text-gray-500">通过阿里云 MSE 账号授权后选择实例导入</div>
50 |               </div>
51 |             </Radio>
52 |             <Radio value="OPEN_SOURCE" className="w-full p-3 border rounded-lg hover:bg-gray-50">
53 |               <div className="ml-2">
54 |                 <div className="font-medium">开源 Nacos</div>
55 |                 <div className="text-sm text-gray-500">使用已有自建/开源 Nacos 地址登录创建</div>
56 |               </div>
57 |             </Radio>
58 |           </Space>
59 |         </Radio.Group>
60 |       </div>
61 |     </Modal>
62 |   )
63 | }
64 | 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/entity/PortalDomain.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.entity;
21 | 
22 | import com.alibaba.apiopenplatform.support.enums.DomainType;
23 | import com.alibaba.apiopenplatform.support.enums.ProtocolType;
24 | import lombok.Data;
25 | import lombok.EqualsAndHashCode;
26 | 
27 | import javax.persistence.*;
28 | 
29 | @Entity
30 | @Table(name = "portal_domain",
31 |         uniqueConstraints = {
32 |                 @UniqueConstraint(columnNames = {"domain"}, name = "uk_domain")
33 |         }
34 | )
35 | @Data
36 | @EqualsAndHashCode(callSuper = true)
37 | public class PortalDomain extends BaseEntity {
38 |     @Id
39 |     @GeneratedValue(strategy = GenerationType.IDENTITY)
40 |     private Long id;
41 | 
42 |     @Column(name = "portal_id", length = 64, nullable = false)
43 |     private String portalId;
44 | 
45 |     @Column(name = "domain", length = 128, nullable = false)
46 |     private String domain;
47 | 
48 |     @Enumerated(EnumType.STRING)
49 |     @Column(name = "type", length = 32, nullable = false)
50 |     private DomainType type = DomainType.DEFAULT;
51 | 
52 |     @Column(name = "protocol", length = 32, nullable = false)
53 |     @Enumerated(EnumType.STRING)
54 |     private ProtocolType protocol = ProtocolType.HTTP;
55 | }
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/entity/DeveloperExternalIdentity.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.entity;
21 | 
22 | import javax.persistence.*;
23 | 
24 | import com.alibaba.apiopenplatform.support.enums.DeveloperAuthType;
25 | import lombok.Data;
26 | import lombok.NoArgsConstructor;
27 | import lombok.AllArgsConstructor;
28 | import lombok.Builder;
29 | 
30 | @Data
31 | @NoArgsConstructor
32 | @AllArgsConstructor
33 | @Builder
34 | @Entity
35 | @Table(name = "developer_external_identity", uniqueConstraints = {
36 |         @UniqueConstraint(columnNames = {"provider", "subject"})
37 | })
38 | public class DeveloperExternalIdentity {
39 |     @Id
40 |     @GeneratedValue(strategy = GenerationType.IDENTITY)
41 |     private Long id;
42 | 
43 |     @ManyToOne
44 |     @JoinColumn(name = "developer_id", referencedColumnName = "developerId", nullable = false)
45 |     private Developer developer;
46 | 
47 |     @Column(nullable = false, length = 32)
48 |     private String provider;
49 | 
50 |     @Column(nullable = false, length = 128)
51 |     private String subject;
52 | 
53 |     @Column(length = 128)
54 |     private String displayName;
55 | 
56 |     @Column(length = 32)
57 |     private DeveloperAuthType authType;
58 | 
59 |     @Column(columnDefinition = "json")
60 |     private String rawInfoJson;
61 | } 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/entity/ConsumerRef.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.entity;
21 | 
22 | import com.alibaba.apiopenplatform.converter.GatewayConfigConverter;
23 | import com.alibaba.apiopenplatform.support.enums.GatewayType;
24 | import com.alibaba.apiopenplatform.support.gateway.GatewayConfig;
25 | import lombok.*;
26 | 
27 | import javax.persistence.*;
28 | 
29 | @Entity
30 | @Table(name = "consumer_ref")
31 | @Data
32 | @Builder
33 | @AllArgsConstructor
34 | @NoArgsConstructor
35 | @EqualsAndHashCode(callSuper = true)
36 | public class ConsumerRef extends BaseEntity {
37 | 
38 |     @Id
39 |     @GeneratedValue(strategy = GenerationType.IDENTITY)
40 |     private Long id;
41 | 
42 |     @Column(name = "consumer_id", length = 64, nullable = false)
43 |     private String consumerId;
44 | 
45 |     @Column(name = "gateway_type", length = 32, nullable = false)
46 |     @Enumerated(EnumType.STRING)
47 |     private GatewayType gatewayType;
48 | 
49 |     @Column(name = "gw_consumer_id", length = 64, nullable = false)
50 |     private String gwConsumerId;
51 | 
52 |     @Column(name = "gateway_config", columnDefinition = "json", nullable = false)
53 |     @Convert(converter = GatewayConfigConverter.class)
54 |     private GatewayConfig gatewayConfig;
55 | }
56 | 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/src/components/portal/PortalFormModal.tsx:
--------------------------------------------------------------------------------

```typescript
 1 | import { Modal, Form, Input, message } from 'antd'
 2 | import { useEffect } from 'react'
 3 | import { portalApi } from '@/lib/api'
 4 | import { Portal } from '@/types'
 5 | 
 6 | interface PortalFormModalProps {
 7 |   visible: boolean
 8 |   onCancel: () => void
 9 |   onSuccess: () => void
10 |   portal: Portal | null
11 | }
12 | 
13 | export default function PortalFormModal({
14 |   visible,
15 |   onCancel,
16 |   onSuccess,
17 |   portal,
18 | }: PortalFormModalProps) {
19 |   const [form] = Form.useForm()
20 | 
21 |   useEffect(() => {
22 |     if (visible && portal) {
23 |       form.setFieldsValue({
24 |         name: portal.name,
25 |         description: portal.description || '',
26 |       })
27 |     }
28 |   }, [visible, portal, form])
29 | 
30 |   const handleOk = async () => {
31 |     try {
32 |       const values = await form.validateFields()
33 |       if (!portal) return
34 | 
35 |       await portalApi.updatePortal(portal.portalId, {
36 |         name: values.name,
37 |         description: values.description,
38 |         portalSettingConfig: portal.portalSettingConfig,
39 |         portalDomainConfig: portal.portalDomainConfig,
40 |         portalUiConfig: portal.portalUiConfig,
41 |       })
42 | 
43 |       message.success('Portal信息更新成功')
44 |       form.resetFields()
45 |       onSuccess()
46 |     } catch (error) {
47 |       message.error('更新失败,请稍后重试')
48 |     }
49 |   }
50 | 
51 |   const handleCancel = () => {
52 |     form.resetFields()
53 |     onCancel()
54 |   }
55 | 
56 |   return (
57 |     <Modal
58 |       title="编辑Portal"
59 |       open={visible}
60 |       onOk={handleOk}
61 |       onCancel={handleCancel}
62 |       okText="保存"
63 |       cancelText="取消"
64 |       width={600}
65 |       destroyOnClose
66 |     >
67 |       <Form form={form} layout="vertical">
68 |         <Form.Item
69 |           name="name"
70 |           label="Portal名称"
71 |           rules={[{ required: true, message: "请输入Portal名称" }]}
72 |         >
73 |           <Input placeholder="请输入Portal名称" />
74 |         </Form.Item>
75 | 
76 |         <Form.Item
77 |           name="description"
78 |           label="描述"
79 |         >
80 |           <Input.TextArea rows={3} placeholder="请输入Portal描述" />
81 |         </Form.Item>
82 |       </Form>
83 |     </Modal>
84 |   )
85 | }
86 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/core/constant/Resources.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.core.constant;
21 | 
22 | public class Resources {
23 | 
24 |     public static final String ADMINISTRATOR = "Administrator";
25 | 
26 |     public static final String PORTAL = "Portal";
27 | 
28 |     public static final String PORTAL_SETTING = "PortalSetting";
29 | 
30 |     public static final String PORTAL_UI = "PortalUI";
31 | 
32 |     public static final String PORTAL_DOMAIN = "PortalDomain";
33 | 
34 |     public static final String OAUTH2_CONFIG = "OAuth2Config";
35 | 
36 |     public static final String PUBLIC_KEY = "PublicKey";
37 | 
38 |     public static final String OIDC_CONFIG = "OidcConfig";
39 | 
40 |     public static final String PRODUCT = "Product";
41 | 
42 |     public static final String PRODUCT_SETTING = "ProductSetting";
43 | 
44 |     public static final String DEVELOPER = "Developer";
45 | 
46 |     public static final String CONSUMER = "Consumer";
47 | 
48 |     public static final String CONSUMER_CREDENTIAL = "ConsumerCredential";
49 | 
50 |     public static final String GATEWAY = "Gateway";
51 | 
52 |     public static final String PRODUCT_REF = "ProductRef";
53 | 
54 |     public static final String NACOS_INSTANCE = "NacosInstance";
55 | 
56 |     public static final String SUBSCRIPTION = "Subscription";
57 | 
58 | }
59 | 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/bin/replace_var.py:
--------------------------------------------------------------------------------

```python
 1 | #!/usr/bin/python
 2 | # -*- coding: utf-8 -*-
 3 | from jinja2 import Template
 4 | import sys
 5 | import os
 6 | import traceback
 7 | import json
 8 | 
 9 | 
10 | def readFileTrimspace(filepath):
11 |     try:
12 |         result = list()
13 |         is_yaml = 'yaml' in filepath or 'yml' in filepath
14 |         if os.path.isfile(filepath):
15 |             f = open(filepath, 'r')
16 |             for line in f.readlines():
17 |                 line = (line.strip('\n') if is_yaml else line.strip())
18 |                 if not len(line):
19 |                     continue
20 |                 result.append(line)
21 |         return "\n".join(result)
22 |     except:
23 |         traceback.print_exc()
24 |         return ""
25 | 
26 | def readFile(filepath):
27 |     try:
28 |         if not os.path.isfile(filepath):
29 |             print("The input [%s] is not a file" % filepath)
30 |             return ""
31 |         if os.path.isfile(filepath):
32 |             try:
33 |                 f = open(filepath, 'r')
34 |                 return f.read()
35 |             finally:
36 |                 if f:
37 |                     f.close()
38 |     except:
39 |         traceback.print_exc()
40 |         return ""
41 | 
42 | 
43 | def writeFile(filepath, content):
44 |     try:
45 |         open(filepath, 'w+').write(content)
46 |     except:
47 |         traceback.print_exc()
48 | 
49 | 
50 | def dockerenv2json():
51 |     envJson = {}
52 |     with open('/.dockerenv') as ifs:
53 |         data = ifs.read()
54 |     assert len(data) > 2, 'invalid dockerenv'
55 |     envlist = json.loads(data)
56 |     for env in envlist:
57 |         indexOfEqual = env.index('=')
58 |         if indexOfEqual > 0:
59 |             key = env[0: indexOfEqual]
60 |             value = env[indexOfEqual + 1:]
61 |             envJson[key] = value
62 |     return envJson
63 | 
64 | 
65 | def createVarMap(filepath):
66 |     map = os.environ
67 |     # add more param to map
68 |     return map
69 | 
70 | 
71 | def main():
72 |     filepath = sys.argv[1] if len(sys.argv) > 1 else ''
73 |     t = Template(readFile(filepath))
74 |     map = createVarMap(filepath)
75 |     ret = t.render(map)
76 |     writeFile(filepath, ret)
77 | 
78 | 
79 | if __name__ == "__main__":
80 |     reload(sys)
81 |     sys.setdefaultencoding('utf-8')
82 |     main()
```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/bin/replace_var.py:
--------------------------------------------------------------------------------

```python
 1 | #!/usr/bin/python
 2 | # -*- coding: utf-8 -*-
 3 | from jinja2 import Template
 4 | import sys
 5 | import os
 6 | import traceback
 7 | import json
 8 | 
 9 | 
10 | def readFileTrimspace(filepath):
11 |     try:
12 |         result = list()
13 |         is_yaml = 'yaml' in filepath or 'yml' in filepath
14 |         if os.path.isfile(filepath):
15 |             f = open(filepath, 'r')
16 |             for line in f.readlines():
17 |                 line = (line.strip('\n') if is_yaml else line.strip())
18 |                 if not len(line):
19 |                     continue
20 |                 result.append(line)
21 |         return "\n".join(result)
22 |     except:
23 |         traceback.print_exc()
24 |         return ""
25 | 
26 | def readFile(filepath):
27 |     try:
28 |         if not os.path.isfile(filepath):
29 |             print("The input [%s] is not a file" % filepath)
30 |             return ""
31 |         if os.path.isfile(filepath):
32 |             try:
33 |                 f = open(filepath, 'r')
34 |                 return f.read()
35 |             finally:
36 |                 if f:
37 |                     f.close()
38 |     except:
39 |         traceback.print_exc()
40 |         return ""
41 | 
42 | 
43 | def writeFile(filepath, content):
44 |     try:
45 |         open(filepath, 'w+').write(content)
46 |     except:
47 |         traceback.print_exc()
48 | 
49 | 
50 | def dockerenv2json():
51 |     envJson = {}
52 |     with open('/.dockerenv') as ifs:
53 |         data = ifs.read()
54 |     assert len(data) > 2, 'invalid dockerenv'
55 |     envlist = json.loads(data)
56 |     for env in envlist:
57 |         indexOfEqual = env.index('=')
58 |         if indexOfEqual > 0:
59 |             key = env[0: indexOfEqual]
60 |             value = env[indexOfEqual + 1:]
61 |             envJson[key] = value
62 |     return envJson
63 | 
64 | 
65 | def createVarMap(filepath):
66 |     map = os.environ
67 |     # add more param to map
68 |     return map
69 | 
70 | 
71 | def main():
72 |     filepath = sys.argv[1] if len(sys.argv) > 1 else ''
73 |     t = Template(readFile(filepath))
74 |     map = createVarMap(filepath)
75 |     ret = t.render(map)
76 |     writeFile(filepath, ret)
77 | 
78 | 
79 | if __name__ == "__main__":
80 |     reload(sys)
81 |     sys.setdefaultencoding('utf-8')
82 |     main()
```

--------------------------------------------------------------------------------
/portal-bootstrap/src/main/java/com/alibaba/apiopenplatform/config/FilterConfig.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.config;
21 | 
22 | import com.alibaba.apiopenplatform.core.security.ContextHolder;
23 | import com.alibaba.apiopenplatform.filter.PortalResolvingFilter;
24 | import com.alibaba.apiopenplatform.service.PortalService;
25 | import lombok.RequiredArgsConstructor;
26 | import org.springframework.boot.web.servlet.FilterRegistrationBean;
27 | import org.springframework.context.annotation.Bean;
28 | import org.springframework.context.annotation.Configuration;
29 | import org.springframework.core.Ordered;
30 | 
31 | @Configuration
32 | @RequiredArgsConstructor
33 | public class FilterConfig {
34 | 
35 |     private final PortalService portalService;
36 | 
37 |     private final ContextHolder contextHolder;
38 | 
39 |     @Bean
40 |     public FilterRegistrationBean<PortalResolvingFilter> portalResolvingFilter() {
41 |         FilterRegistrationBean<PortalResolvingFilter> registrationBean = new FilterRegistrationBean<>();
42 | 
43 |         PortalResolvingFilter filter = new PortalResolvingFilter(portalService, contextHolder);
44 |         registrationBean.setFilter(filter);
45 |         registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
46 |         registrationBean.addUrlPatterns("/*");
47 | 
48 |         return registrationBean;
49 |     }
50 | }
51 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/result/AdpMCPServerResult.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.result;
21 | 
22 | import com.fasterxml.jackson.annotation.JsonProperty;
23 | import lombok.Data;
24 | import lombok.EqualsAndHashCode;
25 | 
26 | import java.util.List;
27 | 
28 | @EqualsAndHashCode(callSuper = true)
29 | @Data
30 | public class AdpMCPServerResult extends GatewayMCPServerResult {
31 | 
32 |     private String gwInstanceId;
33 |     
34 |     @JsonProperty("name")
35 |     private String name;
36 |     
37 |     private String description;
38 |     private List<String> domains;
39 |     private List<Service> services;
40 |     private ConsumerAuthInfo consumerAuthInfo;
41 |     private String rawConfigurations;
42 |     private String type;
43 |     private String dsn;
44 |     private String dbType;
45 |     private String upstreamPathPrefix;
46 | 
47 |     /**
48 |      * 确保 mcpServerName 字段被正确设置
49 |      */
50 |     public void setName(String name) {
51 |         this.name = name;
52 |         // 同时设置父类的 mcpServerName 字段
53 |         this.setMcpServerName(name);
54 |     }
55 | 
56 |     @Data
57 |     public static class Service {
58 |         private String name;
59 |         private Integer port;
60 |         private String version;
61 |         private Integer weight;
62 |     }
63 | 
64 |     @Data
65 |     public static class ConsumerAuthInfo {
66 |         private String type;
67 |         private Boolean enable;
68 |         private List<String> allowedConsumers;
69 |     }
70 | }
71 | 
72 | 
73 | 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/dto/params/product/CreateProductParam.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.dto.params.product;
21 | 
22 | import cn.hutool.core.util.StrUtil;
23 | import com.alibaba.apiopenplatform.dto.converter.InputConverter;
24 | import com.alibaba.apiopenplatform.entity.Product;
25 | import com.alibaba.apiopenplatform.support.enums.ProductType;
26 | import com.alibaba.apiopenplatform.support.product.ProductIcon;
27 | import lombok.Data;
28 | 
29 | import javax.validation.constraints.AssertTrue;
30 | import javax.validation.constraints.NotBlank;
31 | import javax.validation.constraints.NotNull;
32 | import javax.validation.constraints.Size;
33 | 
34 | @Data
35 | public class CreateProductParam implements InputConverter<Product> {
36 | 
37 |     @NotBlank(message = "API产品名称不能为空")
38 |     @Size(max = 50, message = "API产品名称长度不能超过50个字符")
39 |     private String name;
40 | 
41 |     @Size(max = 256, message = "API产品描述长度不能超过256个字符")
42 |     private String description;
43 | 
44 |     @NotNull(message = "API产品类型不能为空")
45 |     private ProductType type;
46 | 
47 |     private String document;
48 | 
49 |     private ProductIcon icon;
50 | 
51 |     private String category;
52 | 
53 |     private Boolean autoApprove;
54 | 
55 |     @AssertTrue(message = "Icon大小不能超过16KB")
56 |     public boolean checkIcon() {
57 |         if (icon == null || StrUtil.isBlank(icon.getValue())) {
58 |             return true;
59 |         }
60 |         return icon.getValue().length() < 16 * 1024;
61 |     }
62 | }
63 | 
```

--------------------------------------------------------------------------------
/deploy/helm/templates/himarket-server-deployment.yaml:
--------------------------------------------------------------------------------

```yaml
 1 | apiVersion: apps/v1
 2 | kind: Deployment
 3 | metadata:
 4 |   name: himarket-server
 5 |   labels:
 6 |     app: himarket-server
 7 | spec:
 8 |   replicas: {{ .Values.server.replicaCount }}
 9 |   selector:
10 |     matchLabels:
11 |       app: himarket-server
12 |   template:
13 |     metadata:
14 |       labels:
15 |         app: himarket-server
16 |     spec:
17 |       {{- with .Values.imagePullSecrets }}
18 |       imagePullSecrets:
19 |         {{- toYaml . | nindent 8 }}
20 |       {{- end }}
21 |       serviceAccountName: {{ include "himarket.serviceAccountName" . }}
22 |       containers:
23 |         - name: server
24 |           image: "{{ .Values.hub }}/{{ .Values.server.image.repository }}:{{ .Values.server.image.tag}}"
25 |           imagePullPolicy: {{ .Values.server.image.pullPolicy }}
26 |           ports:
27 |             - name: http
28 |               containerPort: {{ .Values.server.serverPort }}
29 |               protocol: TCP
30 |           envFrom:
31 |             - configMapRef:
32 |                 name: himarket-server        # 非敏感配置
33 | {{- if .Values.mysql.enabled }}
34 |             - secretRef:
35 |                 name: himarket-server-secret # 内置MySQL的敏感配置
36 | {{- end }}
37 | {{/*          {{- with .Values.livenessProbe }}*/}}
38 | {{/*          livenessProbe:*/}}
39 | {{/*            {{- toYaml . | nindent 12 }}*/}}
40 | {{/*          {{- end }}*/}}
41 | {{/*          {{- with .Values.readinessProbe }}*/}}
42 | {{/*          readinessProbe:*/}}
43 | {{/*            {{- toYaml . | nindent 12 }}*/}}
44 | {{/*          {{- end }}*/}}
45 |           {{- with .Values.resources }}
46 |           resources:
47 |             {{- toYaml . | nindent 12 }}
48 |           {{- end }}
49 |           {{- with .Values.volumeMounts }}
50 |           volumeMounts:
51 |             {{- toYaml . | nindent 12 }}
52 |           {{- end }}
53 |       {{- with .Values.volumes }}
54 |       volumes:
55 |         {{- toYaml . | nindent 8 }}
56 |       {{- end }}
57 |       {{- with .Values.nodeSelector }}
58 |       nodeSelector:
59 |         {{- toYaml . | nindent 8 }}
60 |       {{- end }}
61 |       {{- with .Values.affinity }}
62 |       affinity:
63 |         {{- toYaml . | nindent 8 }}
64 |       {{- end }}
65 |       {{- with .Values.tolerations }}
66 |       tolerations:
67 |         {{- toYaml . | nindent 8 }}
68 |       {{- end }}
69 | 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/entity/NacosInstance.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.entity;
21 | 
22 | import lombok.Data;
23 | import lombok.EqualsAndHashCode;
24 | 
25 | import javax.persistence.*;
26 | 
27 | /**
28 |  * Nacos实例实体
29 |  */
30 | @EqualsAndHashCode(callSuper = true)
31 | @Entity
32 | @Table(name = "nacos_instance",
33 |         uniqueConstraints = {
34 |                 @UniqueConstraint(columnNames = {"nacos_id"}, name = "uk_nacos_id"),
35 |         })
36 | @Data
37 | public class NacosInstance extends BaseEntity {
38 | 
39 |     @Id
40 |     @GeneratedValue(strategy = GenerationType.IDENTITY)
41 |     private Long id;
42 | 
43 |     @Column(name = "nacos_name", length = 64, nullable = false)
44 |     private String nacosName;
45 | 
46 |     @Column(name = "nacos_id", length = 64, nullable = false)
47 |     private String nacosId;
48 | 
49 |     @Column(name = "admin_id", length = 64, nullable = false)
50 |     private String adminId;
51 | 
52 |     @Column(name = "server_url", length = 256, nullable = false)
53 |     private String serverUrl;
54 | 
55 | 
56 |     @Column(name = "username", length = 64)
57 |     private String username;
58 | 
59 |     @Column(name = "password", length = 128)
60 |     private String password;
61 | 
62 |     @Column(name = "access_key", length = 128)
63 |     private String accessKey;
64 | 
65 |     @Column(name = "secret_key", length = 256)
66 |     private String secretKey;
67 | 
68 |     @Column(name = "description", length = 512)
69 |     private String description;
70 | } 
```

--------------------------------------------------------------------------------
/portal-bootstrap/src/main/java/com/alibaba/apiopenplatform/config/PageConfig.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.config;
21 | 
22 | import org.springframework.context.annotation.Bean;
23 | import org.springframework.context.annotation.Configuration;
24 | import org.springframework.data.domain.PageRequest;
25 | import org.springframework.data.domain.Sort;
26 | import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
27 | import org.springframework.web.method.support.HandlerMethodArgumentResolver;
28 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
29 | 
30 | import java.util.List;
31 | 
32 | @Configuration
33 | public class PageConfig {
34 |     @Bean
35 |     public PageableHandlerMethodArgumentResolver pageableResolver() {
36 |         PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
37 |         // 默认分页和排序
38 |         resolver.setFallbackPageable(PageRequest.of(0, 100,
39 |                 Sort.by(Sort.Direction.DESC, "createAt")));
40 |         // 页码从1开始
41 |         resolver.setOneIndexedParameters(true);
42 |         return resolver;
43 |     }
44 | 
45 |     @Bean
46 |     public WebMvcConfigurer webMvcConfigurer() {
47 |         return new WebMvcConfigurer() {
48 |             @Override
49 |             public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
50 |                 resolvers.add(pageableResolver());
51 |             }
52 |         };
53 |     }
54 | }
55 | 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/entity/Developer.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.entity;
21 | 
22 | import javax.persistence.*;
23 | import java.util.Date;
24 | 
25 | import com.alibaba.apiopenplatform.support.enums.DeveloperAuthType;
26 | import com.alibaba.apiopenplatform.support.enums.DeveloperStatus;
27 | import lombok.Data;
28 | import lombok.NoArgsConstructor;
29 | import lombok.AllArgsConstructor;
30 | import lombok.Builder;
31 | 
32 | @Data
33 | @NoArgsConstructor
34 | @AllArgsConstructor
35 | @Builder
36 | @Entity
37 | @Table(name = "developer", uniqueConstraints = {
38 |         @UniqueConstraint(columnNames = {"developerId"}),
39 |         @UniqueConstraint(columnNames = {"portalId", "username"})
40 | })
41 | public class Developer extends BaseEntity {
42 | 
43 |     @Id
44 |     @GeneratedValue(strategy = GenerationType.IDENTITY)
45 |     private Long id;
46 | 
47 |     @Column(nullable = false, unique = true, length = 64)
48 |     private String developerId;
49 | 
50 |     @Column(length = 64)
51 |     private String username;
52 | 
53 |     @Column()
54 |     private String passwordHash;
55 | 
56 |     @Column(length = 128)
57 |     private String email;
58 | 
59 |     @Column(nullable = false, length = 64)
60 |     private String portalId;
61 | 
62 |     @Column(length = 256)
63 |     private String avatarUrl;
64 | 
65 |     @Column(nullable = false, length = 16)
66 |     @Enumerated(EnumType.STRING)
67 |     private DeveloperStatus status;
68 | 
69 |     @Column(length = 16)
70 |     @Enumerated(EnumType.STRING)
71 |     private DeveloperAuthType authType;
72 | 
73 | } 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/entity/Consumer.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.entity;
21 | 
22 | import com.alibaba.apiopenplatform.support.enums.ConsumerStatus;
23 | import lombok.Data;
24 | import lombok.EqualsAndHashCode;
25 | import org.hibernate.annotations.ColumnDefault;
26 | 
27 | import javax.persistence.*;
28 | 
29 | @Entity
30 | @Table(name = "consumer",
31 |         uniqueConstraints = {
32 |                 @UniqueConstraint(columnNames = {"consumer_id"}, name = "uk_consumer_id"),
33 |                 @UniqueConstraint(columnNames = {"name", "portal_id", "developer_id"},
34 |                         name = "uk_name_portal_developer")
35 |         })
36 | @Data
37 | @EqualsAndHashCode(callSuper = true)
38 | public class Consumer extends BaseEntity {
39 | 
40 |     @Id
41 |     @GeneratedValue(strategy = GenerationType.IDENTITY)
42 |     private Long id;
43 | 
44 |     @Column(name = "consumer_id", length = 64, nullable = false)
45 |     private String consumerId;
46 | 
47 |     @Column(name = "name", length = 64, nullable = false)
48 |     private String name;
49 | 
50 |     @Column(name = "description", length = 256)
51 |     private String description;
52 | 
53 | //    @Enumerated(EnumType.STRING)
54 | //    @Column(name = "status", length = 32, nullable = false)
55 | //    private ConsumerStatus status;
56 | 
57 |     @Column(name = "portal_id", length = 64, nullable = false)
58 |     private String portalId;
59 | 
60 |     @Column(name = "developer_id", length = 64, nullable = false)
61 |     private String developerId;
62 | }
63 | 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/entity/ConsumerCredential.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.entity;
21 | 
22 | import com.alibaba.apiopenplatform.converter.ApiKeyConfigConverter;
23 | import com.alibaba.apiopenplatform.converter.HmacConfigConverter;
24 | import com.alibaba.apiopenplatform.converter.JwtConfigConverter;
25 | import com.alibaba.apiopenplatform.support.consumer.ApiKeyConfig;
26 | import com.alibaba.apiopenplatform.support.consumer.HmacConfig;
27 | import com.alibaba.apiopenplatform.support.consumer.JwtConfig;
28 | import lombok.Data;
29 | 
30 | import javax.persistence.*;
31 | 
32 | @Entity
33 | @Table(name = "consumer_credential",
34 |         uniqueConstraints = {
35 |                 @UniqueConstraint(columnNames = {"consumer_id"}, name = "uk_consumer_id")
36 |         })
37 | @Data
38 | public class ConsumerCredential extends BaseEntity {
39 | 
40 |     @Id
41 |     @GeneratedValue(strategy = GenerationType.IDENTITY)
42 |     private Long id;
43 | 
44 |     @Column(name = "consumer_id", nullable = false)
45 |     private String consumerId;
46 | 
47 |     @Column(name = "apikey_config", columnDefinition = "json")
48 |     @Convert(converter = ApiKeyConfigConverter.class)
49 |     private ApiKeyConfig apiKeyConfig;
50 | 
51 |     @Column(name = "hmac_config", columnDefinition = "json")
52 |     @Convert(converter = HmacConfigConverter.class)
53 |     private HmacConfig hmacConfig;
54 | 
55 |     @Column(name = "jwt_config", columnDefinition = "json")
56 |     @Convert(converter = JwtConfigConverter.class)
57 |     private JwtConfig jwtConfig;
58 | }
59 | 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/support/common/Encryptor.java:
--------------------------------------------------------------------------------

```java
 1 | /*
 2 |  * Licensed to the Apache Software Foundation (ASF) under one
 3 |  * or more contributor license agreements.  See the NOTICE file
 4 |  * distributed with this work for additional information
 5 |  * regarding copyright ownership.  The ASF licenses this file
 6 |  * to you under the Apache License, Version 2.0 (the
 7 |  * "License"); you may not use this file except in compliance
 8 |  * with the License.  You may obtain a copy of the License at
 9 |  *
10 |  *   http://www.apache.org/licenses/LICENSE-2.0
11 |  *
12 |  * Unless required by applicable law or agreed to in writing,
13 |  * software distributed under the License is distributed on an
14 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 |  * KIND, either express or implied.  See the License for the
16 |  * specific language governing permissions and limitations
17 |  * under the License.
18 |  */
19 | 
20 | package com.alibaba.apiopenplatform.support.common;
21 | 
22 | import cn.hutool.core.util.CharsetUtil;
23 | import cn.hutool.core.util.StrUtil;
24 | import cn.hutool.crypto.SecureUtil;
25 | import cn.hutool.crypto.symmetric.AES;
26 | import cn.hutool.extra.spring.SpringUtil;
27 | import lombok.extern.slf4j.Slf4j;
28 | 
29 | @Slf4j
30 | public class Encryptor {
31 | 
32 |     private static String ROOT_KEY;
33 | 
34 |     private static AES getAes() {
35 |         if (StrUtil.isBlank(ROOT_KEY)) {
36 |             ROOT_KEY = SpringUtil.getProperty("encryption.root-key");
37 |         }
38 | 
39 |         if (StrUtil.isBlank(ROOT_KEY)) {
40 |             throw new RuntimeException("Encryption root key is not set");
41 |         }
42 | 
43 |         return SecureUtil.aes(ROOT_KEY.getBytes(CharsetUtil.CHARSET_UTF_8));
44 |     }
45 | 
46 |     public static String encrypt(String value) {
47 |         if (StrUtil.isBlank(value)) {
48 |             return value;
49 |         }
50 |         try {
51 |             return getAes().encryptHex(value);
52 |         } catch (Exception e) {
53 |             log.error("Encrypt failed: {}", e.getMessage());
54 |             return value;
55 |         }
56 |     }
57 | 
58 |     public static String decrypt(String value) {
59 |         if (StrUtil.isBlank(value)) {
60 |             return value;
61 |         }
62 |         try {
63 |             return getAes().decryptStr(value);
64 |         } catch (Exception e) {
65 |             log.error("Decrypt failed: {}", e.getMessage());
66 |             return value;
67 |         }
68 |     }
69 | }
70 | 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/nginx.conf:
--------------------------------------------------------------------------------

```
 1 | user nginx;
 2 | worker_processes auto;
 3 | error_log /var/log/nginx/error.log;
 4 | pid /run/nginx.pid;
 5 | 
 6 | # Load dynamic modules. See /usr/share/nginx/README.dynamic.
 7 | include /usr/share/nginx/modules/*.conf;
 8 | 
 9 | events {
10 |     worker_connections 1024;
11 | }
12 | 
13 | http {
14 |     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
15 |                       '$status $body_bytes_sent "$http_referer" '
16 |                       '"$http_user_agent" "$http_x_forwarded_for"';
17 | 
18 |     access_log  /var/log/nginx/access.log  main;
19 | 
20 |     sendfile           on;
21 |     tcp_nopush         on;
22 |     tcp_nodelay        off;
23 |     gzip               on;
24 |     gzip_http_version  1.0;
25 |     gzip_comp_level    2;
26 |     gzip_proxied       any;
27 |     gzip_types         text/plain text/css application/javascript text/xml application/xml+rss;
28 |     keepalive_timeout  65;
29 |     ssl_protocols      TLSv1 TLSv1.1 TLSv1.2;
30 |     ssl_ciphers        HIGH:!aNULL:!MD5;
31 |     client_max_body_size 80M;
32 |     server_tokens off;
33 | 
34 |     include             /etc/nginx/mime.types;
35 |     default_type        application/octet-stream;
36 | 
37 |     # Load modular configuration files from the /etc/nginx/conf.d directory.
38 |     # See http://nginx.org/en/docs/ngx_core_module.html#include
39 |     # for more information.
40 |     include /etc/nginx/conf.d/*.conf;
41 | 
42 |     # HTTP Server
43 |     server {
44 |         # Port to listen on, can also be set in IP:PORT format
45 |         listen  8000;
46 | 
47 |         # compression-webpack-plugin 配置
48 |         gzip on;
49 |         gzip_min_length 1k;
50 |         gzip_comp_level 9;
51 |         gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
52 |         gzip_vary on;
53 |         # 配置禁用 gzip 条件,支持正则,此处表示 ie6 及以下不启用 gzip(因为ie低版本不支持)
54 |         gzip_disable "MSIE [1-6]\.";
55 | 
56 |         add_header Access-Control-Allow-Origin *;
57 |         add_header Access-Control-Allow-Headers Content-Type;
58 |         add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
59 | 
60 |         include  "/etc/nginx/default.d/*.conf";
61 | 
62 |         location /status {
63 |             stub_status on;
64 |             access_log   off;
65 |             allow 127.0.0.1;
66 |             deny all;
67 |         }
68 |     }
69 | }
```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/nginx.conf:
--------------------------------------------------------------------------------

```
 1 | user nginx;
 2 | worker_processes auto;
 3 | error_log /var/log/nginx/error.log;
 4 | pid /run/nginx.pid;
 5 | 
 6 | # Load dynamic modules. See /usr/share/nginx/README.dynamic.
 7 | include /usr/share/nginx/modules/*.conf;
 8 | 
 9 | events {
10 |     worker_connections 1024;
11 | }
12 | 
13 | http {
14 |     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
15 |                       '$status $body_bytes_sent "$http_referer" '
16 |                       '"$http_user_agent" "$http_x_forwarded_for"';
17 | 
18 |     access_log  /var/log/nginx/access.log  main;
19 | 
20 |     sendfile           on;
21 |     tcp_nopush         on;
22 |     tcp_nodelay        off;
23 |     gzip               on;
24 |     gzip_http_version  1.0;
25 |     gzip_comp_level    2;
26 |     gzip_proxied       any;
27 |     gzip_types         text/plain text/css application/javascript text/xml application/xml+rss;
28 |     keepalive_timeout  65;
29 |     ssl_protocols      TLSv1 TLSv1.1 TLSv1.2;
30 |     ssl_ciphers        HIGH:!aNULL:!MD5;
31 |     client_max_body_size 80M;
32 |     server_tokens off;
33 | 
34 |     include             /etc/nginx/mime.types;
35 |     default_type        application/octet-stream;
36 | 
37 |     # Load modular configuration files from the /etc/nginx/conf.d directory.
38 |     # See http://nginx.org/en/docs/ngx_core_module.html#include
39 |     # for more information.
40 |     include /etc/nginx/conf.d/*.conf;
41 | 
42 |     # HTTP Server
43 |     server {
44 |         # Port to listen on, can also be set in IP:PORT format
45 |         listen  8000;
46 | 
47 |         # compression-webpack-plugin 配置
48 |         gzip on;
49 |         gzip_min_length 1k;
50 |         gzip_comp_level 9;
51 |         gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
52 |         gzip_vary on;
53 |         # 配置禁用 gzip 条件,支持正则,此处表示 ie6 及以下不启用 gzip(因为ie低版本不支持)
54 |         gzip_disable "MSIE [1-6]\.";
55 | 
56 |         add_header Access-Control-Allow-Origin *;
57 |         add_header Access-Control-Allow-Headers Content-Type;
58 |         add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
59 | 
60 |         include  "/etc/nginx/default.d/*.conf";
61 | 
62 |         location /status {
63 |             stub_status on;
64 |             access_log   off;
65 |             allow 127.0.0.1;
66 |             deny all;
67 |         }
68 |     }
69 | }
```
Page 2/9FirstPrevNextLast