#
tokens: 49959/50000 182/349 files (page 1/7)
lines: off (toggle) GitHub
raw markdown copy
This is page 1 of 7. Use http://codebase.md/higress-group/himarket?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-web/api-portal-admin/.env:
--------------------------------------------------------------------------------

```
VITE_API_BASE_URL=/api/v1
```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/.env:
--------------------------------------------------------------------------------

```
VITE_API_BASE_URL=/api/v1
```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/.gitignore:
--------------------------------------------------------------------------------

```
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
image-push.sh
```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/.gitignore:
--------------------------------------------------------------------------------

```
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
image-push.sh
```

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/

### VS Code ###
.vscode/

### Mac OS ###
.DS_Store

/front-auth-app

package-lock.json
```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/src/vite-env.d.ts:
--------------------------------------------------------------------------------

```typescript
/// <reference types="vite/client" /> 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/src/vite-env.d.ts:
--------------------------------------------------------------------------------

```typescript
/// <reference types="vite/client" />

```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/postcss.config.js:
--------------------------------------------------------------------------------

```javascript
export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}
```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/postcss.config.js:
--------------------------------------------------------------------------------

```javascript
export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
} 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/src/types/shims-js-yaml.d.ts:
--------------------------------------------------------------------------------

```typescript
declare module 'js-yaml' {
  export function load(str: string, opts?: unknown): unknown;
}



```

--------------------------------------------------------------------------------
/deploy/helm/templates/serviceaccount.yaml:
--------------------------------------------------------------------------------

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: {{ include "himarket.serviceAccountName" . }}
```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/src/components/common/index.ts:
--------------------------------------------------------------------------------

```typescript
export { AdvancedSearch } from './AdvancedSearch';
export type { SearchParam } from './AdvancedSearch';

```

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

```java
package com.alibaba.apiopenplatform.support.enums;

public enum PublicKeyFormat {
    PEM,

    JWK,

    ;
}

```

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

```json
{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ]
}

```

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

```java
package com.alibaba.apiopenplatform.support.enums;

/**
 * @author zh
 */
public enum ProductIconType {

    URL,

    BASE64,

    ;
}

```

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

```yaml
kind: ConfigMap
apiVersion: v1
metadata:
  labels:
    app: himarket-admin
  name: himarket-admin
data:
  HIMARKET_SERVER: "http://himarket-server"
```

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

```yaml
kind: ConfigMap
apiVersion: v1
metadata:
  labels:
    app: himarket-frontend
  name: himarket-frontend
data:
  HIMARKET_SERVER: "http://himarket-server"
```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/src/components/consumer/index.ts:
--------------------------------------------------------------------------------

```typescript
export { ConsumerBasicInfo } from './ConsumerBasicInfo';
export { CredentialManager } from './CredentialManager';
export { SubscriptionManager } from './SubscriptionManager'; 
```

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

```java
package com.alibaba.apiopenplatform.support.enums;

/**
 * @author zh
 */
public enum JwtAlgorithm {

    RS256,

    RS384,

    RS512,

    ES256,

    ES384,

    ES512,

    ;
}

```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/tailwind.config.js:
--------------------------------------------------------------------------------

```javascript
/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

```

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

```typescript
import { createRoot } from 'react-dom/client'
import 'antd/dist/reset.css'
import './index.css'
import App from './App.tsx'

createRoot(document.getElementById('root')!).render(
  <App />
)

```

--------------------------------------------------------------------------------
/portal-bootstrap/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
FROM docker.m.daocloud.io/openjdk:8-jdk-slim

WORKDIR /app

COPY target/*.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "app.jar", "--logging.file.name=/app/logs/himarket-server.log"]
```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/tsconfig.node.json:
--------------------------------------------------------------------------------

```json
{
  "compilerOptions": {
    "composite": true,
    "skipLibCheck": true,
    "module": "ESNext",
    "moduleResolution": "bundler",
    "allowSyntheticDefaultImports": true
  },
  "include": ["vite.config.ts"]
} 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
FROM docker.m.daocloud.io/nginx:1.24-alpine

COPY nginx.conf /etc/nginx/nginx.conf
COPY proxy.conf /etc/nginx/default.d/proxy.conf
COPY bin /home/admin/bin

WORKDIR /app

COPY dist/ /app

CMD ["/bin/sh", "/home/admin/bin/start.sh"]
```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
FROM docker.m.daocloud.io/nginx:1.24-alpine

COPY nginx.conf /etc/nginx/nginx.conf
COPY proxy.conf /etc/nginx/default.d/proxy.conf
COPY bin /home/admin/bin


WORKDIR /app

COPY dist/ /app

CMD ["/bin/sh", "/home/admin/bin/start.sh"]
```

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

```java
package com.alibaba.apiopenplatform.support.portal;

import lombok.Data;

import java.util.List;

/**
 * @author zh
 */
@Data
public class JwtBearerConfig {

    /**
     * JWT公钥
     */
    private List<PublicKeyConfig> publicKeys;
}

```

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

```java
package com.alibaba.apiopenplatform.support.consumer;

import lombok.Builder;
import lombok.Data;

/**
 * @author zh
 */
@Data
@Builder
public class HigressAuthConfig {

    private String resourceType;

    private String resourceName;
}

```

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

```java
package com.alibaba.apiopenplatform.support.consumer;

import lombok.Builder;
import lombok.Data;

import java.util.List;

/**
 * @author zh
 */
@Data
@Builder
public class APIGAuthConfig {

    private List<String> authorizationRuleIds;
}

```

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

```java
package com.alibaba.apiopenplatform.dto.params.gateway;

import com.alibaba.apiopenplatform.support.enums.GatewayType;
import lombok.Data;

/**
 * @author zh
 */
@Data
public class QueryGatewayParam {

    private GatewayType gatewayType;
}

```

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

```java
package com.alibaba.apiopenplatform.support.product;

import com.alibaba.apiopenplatform.support.enums.ProductIconType;
import lombok.Data;

/**
 * @author zh
 */
@Data
public class ProductIcon {

    private ProductIconType type;

    private String value;
}

```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/bin/start.sh:
--------------------------------------------------------------------------------

```bash
#!/bin/sh

if [ -z "$HIMARKET_SERVER" ]; then
    echo "HIMARKET_SERVER not set"
    exit 1
fi
sed -i "s|{{ HIMARKET_SERVER }}|${HIMARKET_SERVER}|g" /etc/nginx/default.d/proxy.conf

nginx
echo "HiMarket Admin started successfully"
tail -f /var/log/nginx/access.log
```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/bin/start.sh:
--------------------------------------------------------------------------------

```bash
#!/bin/sh

if [ -z "$HIMARKET_SERVER" ]; then
    echo "HIMARKET_SERVER not set"
    exit 1
fi
sed -i "s|{{ HIMARKET_SERVER }}|${HIMARKET_SERVER}|g" /etc/nginx/default.d/proxy.conf

nginx
echo "HiMarket Frontend started successfully"
tail -f /var/log/nginx/access.log
```

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

```yaml
apiVersion: v1
kind: Service
metadata:
  name: himarket-admin
  labels:
    app: himarket-admin
spec:
  type: {{ .Values.admin.service.type }}
  ports:
    - port: {{ .Values.admin.service.port }}
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: himarket-admin

```

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

```java
package com.alibaba.apiopenplatform.dto.params.product;

import com.alibaba.apiopenplatform.support.enums.SubscriptionStatus;
import lombok.Data;

/**
 * @author zh
 */
@Data
public class QueryProductSubscriptionParam {

    private SubscriptionStatus status;

    private String consumerName;
}

```

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

```yaml
apiVersion: v1
kind: Service
metadata:
  name: himarket-server
  labels:
    app: himarket-server
spec:
  type: {{ .Values.server.service.type }}
  ports:
    - port: {{ .Values.server.service.port }}
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: himarket-server

```

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

```java
package com.alibaba.apiopenplatform.support.enums;

/**
 * @author zh
 */
public enum DeveloperAuthType {

    @Deprecated
    LOCAL,

    BUILTIN,

    @Deprecated
    EXTERNAL,

    OIDC,

    OAUTH2,

    ;

    public boolean isBuiltIn() {
        return this == BUILTIN || this == LOCAL;
    }
}

```

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

```yaml
apiVersion: v1
kind: Service
metadata:
  name: himarket-frontend
  labels:
    app: himarket-frontend
spec:
  type: {{ .Values.frontend.service.type }}
  ports:
    - port: {{ .Values.frontend.service.port }}
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: himarket-frontend

```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/service/OAuth2Service.java:
--------------------------------------------------------------------------------

```java
package com.alibaba.apiopenplatform.service;

import com.alibaba.apiopenplatform.dto.result.AuthResult;

/**
 * @author zh
 */
public interface OAuth2Service {

    /**
     * JWT Bearer认证
     *
     * @param grantType
     * @param jwtToken
     * @return
     */
    AuthResult authenticate(String grantType, String jwtToken);

}

```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/ProductIconConverter.java:
--------------------------------------------------------------------------------

```java
package com.alibaba.apiopenplatform.converter;

import com.alibaba.apiopenplatform.support.product.ProductIcon;

import javax.persistence.Converter;

/**
 * @author zh
 */
@Converter(autoApply = true)
public class ProductIconConverter extends JsonConverter<ProductIcon> {

    protected ProductIconConverter() {
        super(ProductIcon.class);
    }
}


```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/index.html:
--------------------------------------------------------------------------------

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/logo.png" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>HiMarket</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>

```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/index.html:
--------------------------------------------------------------------------------

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/logo.png" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>HiMarket</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>

```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/AdpAIGatewayConfigConverter.java:
--------------------------------------------------------------------------------

```java
package com.alibaba.apiopenplatform.converter;

import com.alibaba.apiopenplatform.support.gateway.AdpAIGatewayConfig;

import javax.persistence.Converter;

@Converter(autoApply = true)
public class AdpAIGatewayConfigConverter extends JsonConverter<AdpAIGatewayConfig> {

    public AdpAIGatewayConfigConverter() {
        super(AdpAIGatewayConfig.class);
    }
}

```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/src/main.tsx:
--------------------------------------------------------------------------------

```typescript
import React from 'react'
import ReactDOM from 'react-dom/client'
// import { RouterProvider } from 'react-router-dom'
import App from './App.tsx'
import './index.css'

const rootElement = document.getElementById('root')
if (!rootElement) throw new Error('Failed to find the root element')

ReactDOM.createRoot(rootElement).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

```

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

```
    location ^~ /api/v1 {
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        rewrite ^/api/v1/(.*)$ /$1 break;
        proxy_pass  {{ HIMARKET_SERVER }};
    }

    location ~ .*\.(js|css|gif|jpg|jpeg|png|svg|json|otf|ico)$ {
        root   /app;
    }

    location / {
        try_files $uri $uri/ /index.html;
        root   /app;
        index  index.html index.htm;
    }

```

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

```java
package com.alibaba.apiopenplatform.support.enums;

import lombok.Getter;

/**
 * @author zh
 */
@Getter
public enum GrantType {

    /**
     * 授权码模式
     */
    AUTHORIZATION_CODE("authorization_code"),


    /**
     * JWT断言,OAuth2.0标准拓展
     */
    JWT_BEARER("urn:ietf:params:oauth:grant-type:jwt-bearer"),

    ;

    private final String type;

    GrantType(String type) {
        this.type = type;
    }
}

```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/service/AdpAIGatewayService.java:
--------------------------------------------------------------------------------

```java
package com.alibaba.apiopenplatform.service;

import com.alibaba.apiopenplatform.dto.params.gateway.QueryAdpAIGatewayParam;
import com.alibaba.apiopenplatform.dto.result.GatewayResult;
import com.alibaba.apiopenplatform.dto.result.PageResult;
import org.springframework.data.domain.Pageable;

public interface AdpAIGatewayService {
    PageResult<GatewayResult> fetchGateways(QueryAdpAIGatewayParam param, int page, int size);
}
```

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

```typescript
export interface Subscription {
  subscriptionId: string;
  consumerId: string;
  productId: string;
  status: 'PENDING' | 'APPROVED';
  createAt: string;
  updatedAt: string;
  productName: string;
  productType: string;
}

export interface Product {
  productId: string;
  name: string;
  description?: string;
  type: string;
}

export interface SubscriptionModalProps {
  visible: boolean;
  consumerId: string;
  consumerName: string;
  onCancel: () => void;
}




```

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

```typescript
import { BrowserRouter } from "react-router-dom";
import { Router } from "./router";
import { ConfigProvider } from 'antd';
import zhCN from 'antd/locale/zh_CN';
import './App.css'
import aliyunThemeToken from './aliyunThemeToken.ts';

function App() {
  return (
    <ConfigProvider
      locale={zhCN}
      theme={{
        token: aliyunThemeToken
      }}
    >
      <BrowserRouter>
        <Router />
      </BrowserRouter>
    </ConfigProvider>
  );
}

export default App;

```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/tailwind.config.js:
--------------------------------------------------------------------------------

```javascript
/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {
      colors: {
        gray: {
          50: '#f9fafb',
          100: '#f3f4f6',
          200: '#e5e7eb',
          300: '#d1d5db',
          400: '#9ca3af',
          500: '#6b7280',
          600: '#4b5563',
          700: '#374151',
          800: '#1f2937',
          900: '#111827',
        }
      }
    },
  },
  plugins: [],
} 
```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/src/components/consumer/ConsumerBasicInfo.tsx:
--------------------------------------------------------------------------------

```typescript
import { Card, Descriptions } from "antd";
import type { Consumer } from "../../types/consumer";

interface ConsumerBasicInfoProps {
  consumer: Consumer;
}

export function ConsumerBasicInfo({ consumer }: ConsumerBasicInfoProps) {
  return (
    <Card title="基本信息">
      <Descriptions column={2}>
        <Descriptions.Item label="名称">{consumer.name}</Descriptions.Item>
        <Descriptions.Item label="描述">{consumer.description || '-'}</Descriptions.Item>
      </Descriptions>
    </Card>
  );
} 
```

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

```css
#root {

}

.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
}
.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
  filter: drop-shadow(0 0 2em #61dafbaa);
}

@keyframes logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: no-preference) {
  a:nth-of-type(2) .logo {
    animation: logo-spin infinite 20s linear;
  }
}

.card {
  padding: 2em;
}

.read-the-docs {
  color: #888;
}

```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/src/App.tsx:
--------------------------------------------------------------------------------

```typescript
import { RouterProvider } from 'react-router-dom'
import { ConfigProvider } from 'antd'
import zhCN from 'antd/locale/zh_CN'
import { router } from './routes'
import aliyunThemeToken from './aliyunThemeToken'
import { LoadingProvider } from './contexts/LoadingContext'
import './App.css'

function App() {
  return (
    <LoadingProvider>
      <ConfigProvider
        locale={zhCN}
        theme={{
          token: aliyunThemeToken,
        }}
      >
        <RouterProvider router={router} />
      </ConfigProvider>
    </LoadingProvider>
  )
}

export default App

```

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

```java
package com.alibaba.apiopenplatform.dto.params.developer;

import com.alibaba.apiopenplatform.dto.converter.InputConverter;
import com.alibaba.apiopenplatform.entity.DeveloperExternalIdentity;
import com.alibaba.apiopenplatform.support.enums.DeveloperAuthType;
import lombok.Builder;
import lombok.Data;

/**
 * @author zh
 */
@Data
@Builder
public class CreateExternalDeveloperParam implements InputConverter<DeveloperExternalIdentity> {

    private String provider;

    private String subject;

    private String displayName;

    private String email;

    private DeveloperAuthType authType;
}

```

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

```java
package com.alibaba.apiopenplatform.support.portal;

import com.alibaba.apiopenplatform.support.enums.GrantType;
import lombok.Data;

/**
 * @author zh
 */
@Data
public class OAuth2Config {

    /**
     * 提供商
     */
    private String provider;

    /**
     * 名称
     */
    private String name;

    /**
     * 是否启用
     */
    private boolean enabled = true;

    /**
     * 授权模式
     */
    private GrantType grantType;

    /**
     * JWT断言配置
     */
    private JwtBearerConfig jwtBearerConfig;

    /**
     * 身份映射
     */
    private IdentityMapping identityMapping = new IdentityMapping();

}

```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/eslint.config.js:
--------------------------------------------------------------------------------

```javascript
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { globalIgnores } from 'eslint/config'

export default tseslint.config([
  globalIgnores(['dist']),
  {
    files: ['**/*.{ts,tsx}'],
    extends: [
      js.configs.recommended,
      tseslint.configs.recommended,
      reactHooks.configs['recommended-latest'],
      reactRefresh.configs.vite,
    ],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
    },
  },
])

```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/tsconfig.node.json:
--------------------------------------------------------------------------------

```json
{
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
    "target": "ES2023",
    "lib": ["ES2023"],
    "module": "ESNext",
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "verbatimModuleSyntax": true,
    "moduleDetection": "force",
    "noEmit": true,

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "erasableSyntaxOnly": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true
  },
  "include": ["vite.config.ts"]
}

```

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

```java
package com.alibaba.apiopenplatform.support.portal;

import lombok.Data;

/**
 * @author zh
 */
@Data
public class AuthCodeConfig {

    /**
     * 凭证
     */
    private String clientId;
    private String clientSecret;

    /**
     * 访问范围
     */
    private String scopes;

    /**
     * Issuer
     */
    private String issuer;

    /**
     * 授权端点
     */
    private String authorizationEndpoint;

    /**
     * 令牌端点
     */
    private String tokenEndpoint;

    /**
     * 用户信息端点
     */
    private String userInfoEndpoint;

    /**
     * JWK Set URI
     */
    private String jwkSetUri;

    /**
     * 重定向URI
     */
    private String redirectUri;
}

```

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

```json
{
  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,

    /* Path mapping */
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src"],
  "references": [{ "path": "./tsconfig.node.json" }]
} 
```

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

```typescript
export interface Gateway {
  gatewayId: string
  gatewayName: string
  gatewayType: 'APIG_API' | 'HIGRESS' | 'APIG_AI' | 'ADP_AI_GATEWAY'
  createAt: string
  apigConfig?: ApigConfig
  higressConfig?: HigressConfig
}

export interface ApigConfig {
  region: string
  accessKey: string
  secretKey: string
}

export interface HigressConfig {
  username: string
  address: string
  password: string
}

export interface NacosInstance {
  nacosId: string
  nacosName: string
  serverUrl: string
  username: string
  password?: string
  accessKey?: string
  secretKey?: string
  description: string
  adminId: string
  createAt?: string | number
}

export type GatewayType = 'APIG_API' | 'APIG_AI' | 'HIGRESS' | 'ADP_AI_GATEWAY'

```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/tsconfig.app.json:
--------------------------------------------------------------------------------

```json
{
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "target": "ES2022",
    "useDefineForClassFields": true,
    "lib": ["ES2022", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "verbatimModuleSyntax": true,
    "moduleDetection": "force",
    "noEmit": true,
    "jsx": "react-jsx",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "erasableSyntaxOnly": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true,
    "allowSyntheticDefaultImports": true
  },
  "include": ["src"]
}

```

--------------------------------------------------------------------------------
/portal-web/api-portal-frontend/vite.config.ts:
--------------------------------------------------------------------------------

```typescript
import { defineConfig, loadEnv } from 'vite'
import react from '@vitejs/plugin-react'

// https://vite.dev/config/
const env = loadEnv(process.env.NODE_ENV || 'development', process.cwd(), '')
const apiPrefix = env.VITE_API_BASE_URL

export default defineConfig({
  plugins: [react()],
  server: {
    host: '0.0.0.0',
    allowedHosts: true,
    port: 5173,
    proxy: {
      [apiPrefix]: {
        target: 'http://localhost:8080',
        changeOrigin: true,
        rewrite: (p) => p.replace(new RegExp(`^${apiPrefix}`), ''),
      },
    },
  },
  optimizeDeps: {
    include: ['monaco-editor/esm/vs/editor/editor.api']
  },
  build: {
    rollupOptions: {
      external: ['monaco-editor']
    }
  },
  define: {
    'process.env': {}
  }
})

```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/eslint.config.js:
--------------------------------------------------------------------------------

```javascript
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
  globalIgnores(['dist']),
  {
    files: ['**/*.{js,jsx}'],
    extends: [
      js.configs.recommended,
      reactHooks.configs['recommended-latest'],
      reactRefresh.configs.vite,
    ],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
      parserOptions: {
        ecmaVersion: 'latest',
        ecmaFeatures: { jsx: true },
        sourceType: 'module',
      },
    },
    rules: {
      'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
    },
  },
])

```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/service/IdpService.java:
--------------------------------------------------------------------------------

```java
package com.alibaba.apiopenplatform.service;

import com.alibaba.apiopenplatform.support.enums.PublicKeyFormat;
import com.alibaba.apiopenplatform.support.portal.OAuth2Config;
import com.alibaba.apiopenplatform.support.portal.OidcConfig;

import java.security.PublicKey;
import java.util.List;

/**
 * @author zh
 */
public interface IdpService {

    /**
     * 验证OIDC配置
     *
     * @param oidcConfigs
     */
    void validateOidcConfigs(List<OidcConfig> oidcConfigs);

    /**
     * 验证OAuth2配置
     *
     * @param oauth2Configs
     */
    void validateOAuth2Configs(List<OAuth2Config> oauth2Configs);

    /**
     * 加载JWT公钥
     *
     * @param format
     * @param publicKey
     * @return
     */
    PublicKey loadPublicKey(PublicKeyFormat format, String publicKey);
}

```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/src/contexts/LoadingContext.tsx:
--------------------------------------------------------------------------------

```typescript
import React, { createContext, useContext, useState, ReactNode } from 'react';

interface LoadingContextType {
  loading: boolean;
  setLoading: (loading: boolean) => void;
}

const LoadingContext = createContext<LoadingContextType | undefined>(undefined);

export const useLoading = () => {
  const context = useContext(LoadingContext);
  if (context === undefined) {
    throw new Error('useLoading must be used within a LoadingProvider');
  }
  return context;
};

interface LoadingProviderProps {
  children: ReactNode;
}

export const LoadingProvider: React.FC<LoadingProviderProps> = ({ children }) => {
  const [loading, setLoading] = useState(false);

  return (
    <LoadingContext.Provider value={{ loading, setLoading }}>
      {children}
    </LoadingContext.Provider>
  );
};

```

--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------

```bash
#!/bin/bash

VERSION=1.0.0

set -e

# 构建 server
echo "=== Building backend server ==="
echo "Building with Maven..."
mvn clean package -DskipTests

cd portal-bootstrap
echo "Building backend Docker image..."
docker buildx build \
    --platform linux/amd64 \
    -t himarket-server:$VERSION \
    --load .
echo "Backend server build completed"
cd ..

# 构建 frontend
cd portal-web/api-portal-frontend
echo "=== Building frontend ==="
rm -rf ./dist
npm install --force
npm run build
docker buildx build \
    -t himarket-frontend:$VERSION \
    --platform linux/amd64 \
    --load .

# 构建 admin
cd ../api-portal-admin
echo "=== Building admin ==="
rm -rf ./dist
npm install --force
npm run build
docker buildx build \
    -t himarket-admin:$VERSION \
    --platform linux/amd64 \
    --load .

echo "All images have been built successfully!"

```

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

```
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="200px" height="200px" viewBox="0 0 200 200" preserveAspectRatio="xMidYMid meet">
 <g fill="#000000">
  <path d="M97.7 185.2 l-8.7 -8.7 40.5 -40.5 c22.3 -22.3 40.5 -40.9 40.5 -41.5 0 -0.6 -6.8 -7.8 -15 -16 l-15 -15 -32.8 32.8 -32.7 32.7 -4.3 -4.2 -4.2 -4.3 32.7 -32.7 32.8 -32.8 -15.5 -15.5 -15.5 -15.5 -41 41 -41.1 41 -3.9 -4 -4 -4 45.3 -45.3 45.2 -45.2 43.2 43.2 43.3 43.3 -41 41 -41 41 5 5 4.9 5 -3.9 4 c-2.1 2.2 -4.2 4 -4.5 4 -0.3 0 -4.5 -3.9 -9.3 -8.8z"/>
  <path d="M53.7 141.2 l-23.7 -23.7 35.3 -35.3 35.3 -35.2 3.9 4 3.9 4 -30.9 31 -31 31 15.5 15.5 15.5 15.5 31 -31 31 -31 4.3 4.3 4.2 4.2 -35.3 35.3 -35.2 35.2 -23.8 -23.8z"/>
 </g>
</svg>
```

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

```java
package com.alibaba.apiopenplatform.controller;

import com.alibaba.apiopenplatform.dto.result.AuthResult;
import com.alibaba.apiopenplatform.service.OAuth2Service;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author zh
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/developers/oauth2")
public class OAuth2Controller {

    private final OAuth2Service oAuth2Service;

    @PostMapping("/token")
    public AuthResult authenticate(@RequestParam("grant_type") String grantType,
                                   @RequestParam("assertion") String assertion) {
        return oAuth2Service.authenticate(grantType, assertion);
    }
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.consumer;

import lombok.Data;

@Data
public class JwtConfig {

}
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.enums;

public enum ProtocolType {

    HTTP,

    HTTPS,

    ;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.enums;

public enum DomainType {

    DEFAULT,

    CUSTOM,

    ;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.enums;

public enum CredentialMode {

    SYSTEM,

    CUSTOM,

    ;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.enums;

public enum ProductType {

    REST_API,

    HTTP_API,

    MCP_SERVER,
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.enums;

public enum ConsumerAuthType {

    KEY_AUTH,

    HMAC,

    JWT,

    ;
}

```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/service/OidcService.java:
--------------------------------------------------------------------------------

```java
package com.alibaba.apiopenplatform.service;

import com.alibaba.apiopenplatform.dto.result.AuthResult;
import com.alibaba.apiopenplatform.dto.result.IdpResult;
import com.alibaba.apiopenplatform.support.portal.OidcConfig;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

public interface OidcService {

    /**
     * 重定向到授权服务器
     *
     * @param provider
     * @param apiPrefix
     * @param request
     * @return
     */
    String buildAuthorizationUrl(String provider, String apiPrefix, HttpServletRequest request);

    /**
     * 授权服务器回调
     *
     * @param code
     * @param state
     * @param request
     * @param response
     * @return
     */
    AuthResult handleCallback(String code, String state, HttpServletRequest request, HttpServletResponse response);

    /**
     * 可用的OIDC认证列表
     *
     * @return
     */
    List<IdpResult> getAvailableProviders();

}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.portal;

import lombok.Data;

@Data
public class PortalUiConfig {

    private String logo;

    private String icon;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.enums;

public enum UserType {
    /**
     * 管理员用户
     */
    ADMIN,

    /**
     * 开发者用户
     */
    DEVELOPER,

    ;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.enums;

public enum DeveloperStatus {

    /**
     * 已激活
     */
    APPROVED,

    /**
     * 待审核
     */
    PENDING,

    ;
}

```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/vite.config.ts:
--------------------------------------------------------------------------------

```typescript
import { defineConfig, loadEnv } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path'
import { fileURLToPath } from 'url'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
const env = loadEnv(process.env.NODE_ENV || 'development', process.cwd(), '')
const apiPrefix = env.VITE_API_BASE_URL || '/api/v1'
// https://vite.dev/config/
export default defineConfig({
  plugins: [react()],
  server: {
    host: '0.0.0.0',
    port: 5174,
    proxy: {
      [apiPrefix]: {
        target: 'http://localhost:8080',
        changeOrigin: true,
        rewrite: (path) => path.replace(new RegExp(`^${apiPrefix}`), ''),
      },
    },
  },
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  },
  build: {
    rollupOptions: {
      output: {
        entryFileNames: 'index.js',
        chunkFileNames: 'chunk-[name].js',
        assetFileNames: 'assets/[name].[ext]'
      }
    }
  },
  define: {
    'process.env': {}
  }
}) 
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.product;

import lombok.Data;

@Data
public class HigressRefConfig {

    private String routeName;

    private String mcpServerName;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.enums;

public enum SubscriptionStatus {
    /**
     * Pending approval
     */
    PENDING,

    /**
     * Approved and active
     */
    APPROVED,

    ;
}
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.admin;

import lombok.Data;

/**
 * 修改密码参数
 *
 */
@Data
public class ResetPasswordParam {

    private String oldPassword;

    private String newPassword;
} 
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.consumer;

import lombok.Data;

@Data
public class QueryConsumerParam {

    private String portalId;

    private String developerId;

    private String name;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.product;

import lombok.Data;

/**
 * Nacos MCP Server 配置
 */
@Data
public class NacosRefConfig {

    private String mcpServerName;

    private String namespaceId;
} 
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.enums;

public enum ConsumerStatus {

    /**
     * 待审核
     */
    PENDING,

    /**
     * 已审核
     */
    APPROVED,

    /**
     * 不可用,对应的网关资源已删除
     */
    DISABLED,

    ;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.product;

import lombok.Data;

import javax.validation.constraints.NotBlank;

@Data
public class UnPublishProductParam {

    @NotBlank(message = "门户ID不能为空")
    private String portalId;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.enums;

public enum ProductStatus {

    /**
     * 未配置API和MCP Server
     */
    PENDING,

    /**
     * 已配置API或MCP Server
     */
    READY,

    /**
     * 已发布
     */
    PUBLISHED,

    ;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.common;

import com.alibaba.apiopenplatform.support.enums.UserType;
import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class User {

    private UserType userType;

    private String userId;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.enums;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Getter
public enum HigressAPIType {

    ROUTE("Route"),

    MCP("MCP"),

    ;

    private final String type;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.developer;

import lombok.Data;

/**
 * 解绑外部身份参数
 *
 */
@Data
public class UnbindExternalIdentityParam {

    private String providerName;

    private String providerSubject;

    private String portalId;
} 
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.developer;

import com.alibaba.apiopenplatform.support.enums.DeveloperStatus;
import lombok.Data;

@Data
public class UpdateDeveloperStatusParam {

    private String portalId;

    private DeveloperStatus status;
} 
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.consumer;

import com.alibaba.apiopenplatform.support.enums.SubscriptionStatus;
import lombok.Data;

@Data
public class QuerySubscriptionParam {

    private SubscriptionStatus status;

    private String productName;
}
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.enums;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum APIGAPIType {

    REST("Rest"),

    HTTP("Http"),

    MCP("MCP"),

    ;

    private final String type;
}

```

--------------------------------------------------------------------------------
/portal-web/api-portal-admin/src/components/icons/McpServerIcon.tsx:
--------------------------------------------------------------------------------

```typescript
import React from 'react';
import Icon from '@ant-design/icons';
import type { CustomIconComponentProps } from '@ant-design/icons/lib/components/Icon';

// 基于真实的 MCP.svg 文件的图标组件
const McpSvg = () => (
  <svg
    width="1em"
    height="1em"
    viewBox="0 0 200 200"
    fill="currentColor"
    xmlns="http://www.w3.org/2000/svg"
  >
    <g fill="currentColor">
      <path d="M97.7 185.2 l-8.7 -8.7 40.5 -40.5 c22.3 -22.3 40.5 -40.9 40.5 -41.5 0 -0.6 -6.8 -7.8 -15 -16 l-15 -15 -32.8 32.8 -32.7 32.7 -4.3 -4.2 -4.2 -4.3 32.7 -32.7 32.8 -32.8 -15.5 -15.5 -15.5 -15.5 -41 41 -41.1 41 -3.9 -4 -4 -4 45.3 -45.3 45.2 -45.2 43.2 43.2 43.3 43.3 -41 41 -41 41 5 5 4.9 5 -3.9 4 c-2.1 2.2 -4.2 4 -4.5 4 -0.3 0 -4.5 -3.9 -9.3 -8.8z"/>
      <path d="M53.7 141.2 l-23.7 -23.7 35.3 -35.3 35.3 -35.2 3.9 4 3.9 4 -30.9 31 -31 31 15.5 15.5 15.5 15.5 31 -31 31 -31 4.3 4.3 4.2 4.2 -35.3 35.3 -35.2 35.2 -23.8 -23.8z"/>
    </g>
  </svg>
);

const McpServerIcon: React.FC<Partial<CustomIconComponentProps>> = (props) => (
  <Icon component={McpSvg} {...props} />
);

export default McpServerIcon;

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.developer;

import com.alibaba.apiopenplatform.support.enums.DeveloperStatus;
import lombok.Data;

@Data
public class QueryDeveloperParam {

    private String portalId;

    private String username;

    private DeveloperStatus status;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.nacos;

import lombok.Data;

/**
 * 查询Nacos命名空间参数
 *
 */
@Data
public class QueryNacosNamespaceParam extends CreateNacosParam {
	/**
	 * runtime namespace to query on remote Nacos (not stored on instance)
	 */
	private String namespace;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.product;

import lombok.Data;

@Data
public class APIGRefConfig {

    private String apiId;

    private String apiName;

    /**
     * MCP标识信息
     */
    private String mcpServerId;
    private String mcpRouteId;
    private String mcpServerName;

}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.common;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Encrypted {
}

```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/JwtConfigConverter.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.converter;

import com.alibaba.apiopenplatform.support.consumer.JwtConfig;

import javax.persistence.Converter;

@Converter(autoApply = true)
public class JwtConfigConverter extends JsonConverter<JwtConfig> {

    protected JwtConfigConverter() {
        super(JwtConfig.class);
    }
}

```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/NacosRefConfigConverter.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.converter;

import com.alibaba.apiopenplatform.support.product.NacosRefConfig;

import javax.persistence.Converter;

@Converter
public class NacosRefConfigConverter extends JsonConverter<NacosRefConfig> {

    public NacosRefConfigConverter() {
        super(NacosRefConfig.class);
    }
} 
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/APIGConfigConverter.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.converter;

import com.alibaba.apiopenplatform.support.gateway.APIGConfig;

import javax.persistence.Converter;

@Converter(autoApply = true)
public class APIGConfigConverter extends JsonConverter<APIGConfig> {

    protected APIGConfigConverter() {
        super(APIGConfig.class);
    }
}

```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/HmacConfigConverter.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.converter;

import com.alibaba.apiopenplatform.support.consumer.HmacConfig;

import javax.persistence.Converter;

@Converter(autoApply = true)
public class HmacConfigConverter extends JsonConverter<HmacConfig> {

    protected HmacConfigConverter() {
        super(HmacConfig.class);
    }
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.developer;

import lombok.Data;
import javax.validation.constraints.NotBlank;
import lombok.NoArgsConstructor;

@Data
public class DeveloperLoginParam {

    @NotBlank(message = "用户名不能为空")
    private String username;

    @NotBlank(message = "密码不能为空")
    private String password;
}
```

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

```css
#root {

}

.logo {
  height: 6em;
  padding: 1.5em;
  will-change: filter;
  transition: filter 300ms;
}
.logo:hover {
  filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
  filter: drop-shadow(0 0 2em #61dafbaa);
}

@keyframes logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: no-preference) {
  a:nth-of-type(2) .logo {
    animation: logo-spin infinite 20s linear;
  }
}

.card {
  padding: 2em;
}

.read-the-docs {
  color: #888;
}

/* 用户下拉菜单样式 */
.user-dropdown .ant-dropdown-menu {
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  border: 1px solid #f0f0f0;
  min-width: 200px;
}

.user-dropdown .ant-dropdown-menu-item {
  padding: 8px 12px;
  font-size: 14px;
}

.user-dropdown .ant-dropdown-menu-item:hover {
  background-color: #f5f5f5;
}

.user-dropdown .ant-dropdown-menu-item-disabled {
  cursor: default;
  color: inherit;
  background-color: transparent;
}

.user-dropdown .ant-dropdown-menu-item-disabled:hover {
  background-color: transparent;
}

.user-dropdown .ant-dropdown-menu-divider {
  margin: 4px 0;
}

```

--------------------------------------------------------------------------------
/deploy/helm/Chart.yaml:
--------------------------------------------------------------------------------

```yaml
apiVersion: v2
name: himarket
description: HiMarket AI 开放平台 Helm Chart

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.16.0"

```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/ApiKeyConfigConverter.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.converter;

import com.alibaba.apiopenplatform.support.consumer.ApiKeyConfig;

import javax.persistence.Converter;

@Converter(autoApply = true)
public class ApiKeyConfigConverter extends JsonConverter<ApiKeyConfig> {

    protected ApiKeyConfigConverter() {
        super(ApiKeyConfig.class);
    }
}

```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/GatewayConfigConverter.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.converter;

import com.alibaba.apiopenplatform.support.gateway.GatewayConfig;

import javax.persistence.Converter;

@Converter(autoApply = true)
public class GatewayConfigConverter extends JsonConverter<GatewayConfig> {

    public GatewayConfigConverter() {
        super(GatewayConfig.class);
    }
}

```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/APIGRefConfigConverter.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.converter;

import com.alibaba.apiopenplatform.support.product.APIGRefConfig;

import javax.persistence.Converter;

@Converter(autoApply = true)
public class APIGRefConfigConverter extends JsonConverter<APIGRefConfig> {

    protected APIGRefConfigConverter() {
        super(APIGRefConfig.class);
    }
}

```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/HigressConfigConverter.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.converter;

import com.alibaba.apiopenplatform.support.gateway.HigressConfig;

import javax.persistence.Converter;

@Converter(autoApply = true)
public class HigressConfigConverter extends JsonConverter<HigressConfig> {

    protected HigressConfigConverter() {
        super(HigressConfig.class);
    }
}

```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/PortalUiConfigConverter.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.converter;

import com.alibaba.apiopenplatform.support.portal.PortalUiConfig;

import javax.persistence.Converter;

@Converter(autoApply = true)
public class PortalUiConfigConverter extends JsonConverter<PortalUiConfig> {

    public PortalUiConfigConverter() {
        super(PortalUiConfig.class);
    }
}
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/core/event/PortalDeletingEvent.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.core.event;

import lombok.Getter;
import org.springframework.context.ApplicationEvent;

@Getter
public class PortalDeletingEvent extends ApplicationEvent {

    private final String portalId;

    public PortalDeletingEvent(String portalId) {
        super(portalId);
        this.portalId = portalId;
    }
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.admin;

import lombok.Data;
import javax.validation.constraints.NotBlank;
import lombok.NoArgsConstructor;

/**
 * 管理员登录参数DTO
 *
 */
@Data
public class AdminLoginParam {
    @NotBlank(message = "用户名不能为空")
    private String username;

    @NotBlank(message = "密码不能为空")
    private String password;
} 
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.enums;

/**
 * 数据来源类型枚举
 *
 */
public enum SourceType {

    /**
     * 来自Gateway (Higress, APIG等)
     */
    GATEWAY,

    /**
     * 来自Nacos注册中心
     */
    NACOS;

    public boolean isGateway() {
        return this == GATEWAY;
    }

    public boolean isNacos() {
        return this == NACOS;
    }
} 
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/core/event/ProductDeletingEvent.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.core.event;

import lombok.Getter;
import org.springframework.context.ApplicationEvent;

@Getter
public class ProductDeletingEvent extends ApplicationEvent {

    private final String productId;

    public ProductDeletingEvent(String productId) {
        super(productId);
        this.productId = productId;
    }
}

```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/HigressRefConfigConverter.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.converter;

import com.alibaba.apiopenplatform.support.product.HigressRefConfig;

import javax.persistence.Converter;

@Converter(autoApply = true)
public class HigressRefConfigConverter extends JsonConverter<HigressRefConfig> {

    protected HigressRefConfigConverter() {
        super(HigressRefConfig.class);
    }
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.repository;

import com.alibaba.apiopenplatform.entity.ConsumerCredential;

import java.util.Optional;

public interface ConsumerCredentialRepository extends BaseRepository<ConsumerCredential, Long> {

    Optional<ConsumerCredential> findByConsumerId(String consumerId);

    void deleteAllByConsumerId(String consumerId);
}

```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/ConsumerAuthConfigConverter.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.converter;

import com.alibaba.apiopenplatform.support.consumer.ConsumerAuthConfig;

import javax.persistence.Converter;

@Converter(autoApply = true)
public class ConsumerAuthConfigConverter extends JsonConverter<ConsumerAuthConfig> {

    public ConsumerAuthConfigConverter() {
        super(ConsumerAuthConfig.class);
    }
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.consumer;

import lombok.Builder;
import lombok.Data;

/**
 * ADP AI网关授权配置
 */
@Data
@Builder
public class AdpAIAuthConfig {

    /**
     * MCP Server名称
     */
    private String mcpServerName;

    /**
     * 消费者ID
     */
    private String consumerId;

    /**
     * 网关实例ID
     */
    private String gwInstanceId;
}
```

--------------------------------------------------------------------------------
/portal-dal/src/main/java/com/alibaba/apiopenplatform/converter/PortalSettingConfigConverter.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.converter;

import com.alibaba.apiopenplatform.support.portal.PortalSettingConfig;

import javax.persistence.Converter;

@Converter(autoApply = true)
public class PortalSettingConfigConverter extends JsonConverter<PortalSettingConfig> {

    public PortalSettingConfigConverter() {
        super(PortalSettingConfig.class);
    }
}

```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/core/event/DeveloperDeletingEvent.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.core.event;

import lombok.Getter;
import org.springframework.context.ApplicationEvent;

@Getter
public class DeveloperDeletingEvent extends ApplicationEvent {

    private final String developerId;

    public DeveloperDeletingEvent(String developerId) {
        super(developerId);
        this.developerId = developerId;
    }
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.gateway;

import com.alibaba.apiopenplatform.support.common.Encrypted;
import lombok.Data;

@Data
public class HigressConfig {

    private String address;

    private String username;

    @Encrypted
    private String password;

    public String buildUniqueKey() {
        return String.format("%s:%s:%s", address, username, password);
    }
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.consumer;

import com.alibaba.apiopenplatform.support.enums.CredentialMode;
import lombok.Data;

import java.util.List;

@Data
public class HmacConfig {

    private List<HmacCredential> credentials;

    @Data
    public static class HmacCredential {
        private String ak;
        private String sk;

        private CredentialMode mode;
    }
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.product;

import com.alibaba.apiopenplatform.support.enums.ProductStatus;
import com.alibaba.apiopenplatform.support.enums.ProductType;
import lombok.Data;

@Data
public class QueryProductParam {

    private String portalId;

    private ProductType type;

    private String name;

    private String category;

    private ProductStatus status;
}

```

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

```
    location ^~ /api/v1 {
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        
        # 保留原始host header - 这是最重要的配置
        proxy_set_header Host $http_host;
        
        # 设置X-Forwarded-Host header
        proxy_set_header X-Forwarded-Host $http_host;
        
        # 设置真实的客户端IP
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        # 设置协议信息
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # 设置原始请求的Origin header
        proxy_set_header Origin $http_origin;
        
        # 设置Referer header
        proxy_set_header Referer $http_referer;
        
        # 设置User-Agent
        proxy_set_header User-Agent $http_user_agent;
        
        # 超时设置
        proxy_connect_timeout 30s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
        
        rewrite ^/api/v1/(.*)$ /$1 break;
        proxy_pass  {{ HIMARKET_SERVER }};
    }

    location ~ .*\.(js|css|gif|jpg|jpeg|png|svg|json|otf|ico)$ {
        root   /app;
    }

    location / {
        try_files $uri $uri/ /index.html;
        root   /app;
        index  index.html index.htm;
    }

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.consumer;

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class ConsumerAuthConfig {

    /**
     * for APIG
     */
    private APIGAuthConfig apigAuthConfig;

    /**
     * for Higress
     */
    private HigressAuthConfig higressAuthConfig;

    /**
     * for ADP AI Gateway
     */
    private AdpAIAuthConfig adpAIAuthConfig;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.gateway;

import com.alibaba.apiopenplatform.support.common.Encrypted;
import lombok.Data;

@Data
public class APIGConfig {

    @Encrypted
    private String accessKey;

    @Encrypted
    private String secretKey;

    private String region;

    public String buildUniqueKey() {
        return String.format("%s:%s:%s", accessKey, secretKey, region);
    }
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.product;

import com.alibaba.apiopenplatform.dto.converter.InputConverter;
import com.alibaba.apiopenplatform.entity.ProductPublication;
import lombok.Data;

import javax.validation.constraints.NotBlank;

@Data
public class PublishProductParam implements InputConverter<ProductPublication> {

    @NotBlank(message = "门户ID不能为空")
    private String portalId;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.result;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

@Data
@Schema(
        oneOf = {
                APIGMCPServerResult.class,
                HigressMCPServerResult.class,
                NacosMCPServerResult.class
        },
        discriminatorProperty = "type"
)

public class MCPServerResult {
    protected String mcpServerName;
}
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.result;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

@Data
@Schema(
        oneOf = {
                APIGMCPServerResult.class,
                HigressMCPServerResult.class,
                AdpMCPServerResult.class
        },
        discriminatorProperty = "type"
)
public class GatewayMCPServerResult {

    protected String mcpServerName;
} 
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.consumer;

import com.alibaba.apiopenplatform.dto.converter.InputConverter;
import com.alibaba.apiopenplatform.entity.ProductSubscription;
import lombok.Data;

import javax.validation.constraints.NotBlank;

@Data
public class CreateSubscriptionParam implements InputConverter<ProductSubscription> {

    @NotBlank(message = "Product ID不能为空")
    private String productId;
}
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.repository;

import com.alibaba.apiopenplatform.entity.Gateway;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.Optional;

public interface GatewayRepository extends BaseRepository<Gateway, Long> {

    Optional<Gateway> findByGatewayId(String gatewayId);

    Page<Gateway> findByAdminId(String adminId, Pageable pageable);
}

```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/core/annotation/AdminAuth.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.core.annotation;

import org.springframework.security.access.prepost.PreAuthorize;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasRole('ADMIN')")
public @interface AdminAuth {
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.result;

import lombok.Data;

@Data
public class APIConfigResult {

    private String spec;

    private APIMetadata meta;

    @Data
    public static class APIMetadata {

        /**
         * 来源
         * API网关/Higress
         */
        private String source;

        /**
         * 类型
         * API网关:HTTP/REST
         * Higress:Route
         */
        private String type;
    }
}

```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/core/annotation/DeveloperAuth.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.core.annotation;

import org.springframework.security.access.prepost.PreAuthorize;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasRole('DEVELOPER')")
public @interface DeveloperAuth {
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.result;

import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
import com.alibaba.apiopenplatform.entity.Consumer;
import lombok.Data;

import java.time.LocalDateTime;

@Data
public class ConsumerResult implements OutputConverter<ConsumerResult, Consumer> {

    private String consumerId;

    private String name;

    private String description;

    private LocalDateTime createAt;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.repository;

import com.alibaba.apiopenplatform.entity.Administrator;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;

/**
 * 管理员数据访问接口,提供管理员相关的数据库操作
 *
 */
public interface AdministratorRepository extends JpaRepository<Administrator, Long> {
    Optional<Administrator> findByAdminId(String adminId);
    Optional<Administrator> findByUsername(String username);
} 
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.result;

import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
import com.alibaba.apiopenplatform.entity.Administrator;
import lombok.Data;

import java.time.LocalDateTime;

@Data
public class AdminResult implements OutputConverter<AdminResult, Administrator> {

    private String adminId;

    private String username;

    private LocalDateTime createAt;

    private LocalDateTime updatedAt;
}
```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/core/annotation/AdminOrDeveloperAuth.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.core.annotation;

import org.springframework.security.access.prepost.PreAuthorize;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasRole('ADMIN') or hasRole('DEVELOPER')")
public @interface AdminOrDeveloperAuth {
}

```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/core/utils/PasswordHasher.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.core.utils;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class PasswordHasher {

    private static final BCryptPasswordEncoder ENCODER = new BCryptPasswordEncoder();

    public static String hash(String plainPassword) {
        return ENCODER.encode(plainPassword);
    }

    public static boolean verify(String plainPassword, String hashed) {
        return ENCODER.matches(plainPassword, hashed);
    }
} 
```

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

```typescript
// Consumer 相关类型定义

export interface Consumer {
  consumerId: string;
  name: string;
  description?: string;
  status?: string;
  createAt?: string;
  createdAt?: string;  // 支持两种字段名
  enabled?: boolean;
}

// Portal 开发者统计信息(之前错误命名为Consumer)
export interface DeveloperStats {
  id: string;
  name: string;
  email: string;
  status: string;
  plan: string;
  joinedAt: string;
  lastActive: string;
  apiCalls: number;
  subscriptions: number;
}

// 凭据相关类型
export interface HMACCredential {
  ak?: string;
  sk?: string;
}

export interface APIKeyCredential {
  apiKey?: string;
}

export type ConsumerCredential = HMACCredential | APIKeyCredential;

export interface ConsumerCredentialResult {
  apiKeyConfig?: {
    credentials?: Array<{
      apiKey?: string;
      mode?: 'SYSTEM' | 'CUSTOM';
    }>;
    source?: string;
    key?: string;
  };
  hmacConfig?: {
    credentials?: Array<{
      ak?: string;
      sk?: string;
      mode?: 'SYSTEM' | 'CUSTOM';
    }>;
    source?: string;
    accessKeyId?: string;
    secretAccessKey?: string;
  };
}

export interface Subscription {
  subscriptionId: string;
  productId: string;
  productName?: string;
  status: string;
  createdAt: string;
}

export interface CreateCredentialParam {
  credentialType: 'HMAC' | 'API_KEY';
  apiKey?: string;
}

```

--------------------------------------------------------------------------------
/portal-bootstrap/src/main/resources/application.yaml:
--------------------------------------------------------------------------------

```yaml
spring:
  datasource:
    url: jdbc:mariadb://${db.host}:${db.port}/${db.name}?createDatabaseIfNotExist=true&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC
    username: ${db.username}
    password: ${db.password}
    driver-class-name: org.mariadb.jdbc.Driver
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    properties:
      hibernate:
        format_sql: true

#db:
#   host: YourDBHost
#   port: 3306
#   name: YourDBName
#   username: YourDBUser
#   password: YourDBPassword
db:
   host: rm-uf6pc9n1jzi2478l4eo.mysql.rds.aliyuncs.com
   port: 3306
   name: portal_db
   username: portal_test
   password: portal-Go


#  -Ddb.host=rm-uf6pc9n1jzi2478l4eo.mysql.rds.aliyuncs.com \
#  -Ddb.port=3306 \
#  -Ddb.name=portal_db \
#  -Ddb.username=portal_test \
#  -Ddb.password=portal-Go \


# Encryptor
encryption:
  root-key: portalmanagement

springdoc:
  api-docs:
    enabled: true
    path: /portal/v3/api-docs
  swagger-ui:
    path: /portal/swagger-ui.html
    disable-swagger-default-url: true
  packages-to-scan: com.alibaba.apiopenplatform.controller

jwt:
  secret: YourJWTSecret
  expiration: 2h

logging:
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"
  level:
    root: INFO
    com.alibaba.apiopenplatform: INFO
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.result;

import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
import com.alibaba.apiopenplatform.entity.Developer;
import lombok.Data;

import java.time.LocalDateTime;

@Data
public class DeveloperResult implements OutputConverter<DeveloperResult, Developer> {

    private String developerId;

    private String portalId;

    private String username;

    private String status;

    private String avatarUrl;

    private LocalDateTime createAt;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.gateway;

import com.alibaba.apiopenplatform.entity.Gateway;
import com.alibaba.apiopenplatform.support.enums.GatewayType;
import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class GatewayConfig {

    private GatewayType gatewayType;

    private APIGConfig apigConfig;

    private AdpAIGatewayConfig adpAIGatewayConfig;

    private HigressConfig higressConfig;
    
    /**
     * 网关实体引用,用于获取gatewayId等信息
     */
    private Gateway gateway;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.result;

import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
import com.alibaba.apiopenplatform.entity.ProductPublication;
import lombok.Data;

import java.time.LocalDateTime;

@Data
public class ProductPublicationResult implements OutputConverter<ProductPublicationResult, ProductPublication> {

    private String portalId;

    private String portalName;

    private Boolean autoApproveSubscriptions = false;

    private LocalDateTime createAt;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.repository;

import com.alibaba.apiopenplatform.entity.NacosInstance;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface NacosInstanceRepository extends BaseRepository<NacosInstance, Long> {

    Optional<NacosInstance> findByNacosId(String nacosId);

    Optional<NacosInstance> findByNacosName(String nacosName);
} 
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.config;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SwaggerConfig {
    @Bean
    public OpenAPI openAPI() {
        return new OpenAPI()
                .info(new Info()
                        .title("开放平台 API")
                        .version("1.0.0")
                        .description("API 文档描述"));
    }
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.entity;

import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.persistence.*;

@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "publication")
@Data
public class ProductPublication extends BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "portal_id", length = 64, nullable = false)
    private String portalId;

    @Column(name = "product_id", length = 64, nullable = false)
    private String productId;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.result;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

import java.util.List;

@Data
public class AdpMcpServerListResult {

    private Integer code;
    
    private String message;
    
    private String msg;
    
    private AdpMcpServerListData data;
    
    @Data
    public static class AdpMcpServerListData {
        private List<AdpMCPServerResult> records;
        private Integer total;
        private Integer size;
        private Integer current;
    }
}

```

--------------------------------------------------------------------------------
/portal-server/src/main/java/com/alibaba/apiopenplatform/core/exception/BusinessException.java:
--------------------------------------------------------------------------------

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.core.exception;

import lombok.Getter;
import org.springframework.http.HttpStatus;

@Getter
public class BusinessException extends RuntimeException {
    private final HttpStatus status;
    private final String code;
    private final String message;

    public BusinessException(ErrorCode errorCode, Object... args) {
        super(errorCode.getMessage(args));
        this.status = errorCode.getStatus();
        this.code = errorCode.name();
        this.message = errorCode.getMessage(args);
    }
}
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.consumer;

import com.alibaba.apiopenplatform.support.enums.CredentialMode;
import lombok.Data;

import java.util.List;

@Data
public class ApiKeyConfig {

    private List<ApiKeyCredential> credentials;

    /**
     * apikey的位置
     */
    private String source = "Default";

    /**
     * apikey参数名称
     */
    private String key = "Authorization";

    @Data
    public static class ApiKeyCredential {

        private String apiKey;

        private CredentialMode mode = CredentialMode.SYSTEM;
    }
}
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.portal;

import lombok.Data;

import java.util.List;

@Data
public class PortalSettingConfig {

    /**
     * 内置的账号密码认证,默认开启
     */
    private Boolean builtinAuthEnabled = true;

    /**
     * OIDC配置
     */
    private List<OidcConfig> oidcConfigs;

    /**
     * 开启自动审批开发者注册
     */
    private Boolean autoApproveDevelopers = false;

    /**
     * 开启自动审批订阅申请
     */
    private Boolean autoApproveSubscriptions = true;

    /**
     * OAuth2配置
     */
    private List<OAuth2Config> oauth2Configs;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.admin;

import com.alibaba.apiopenplatform.dto.converter.InputConverter;
import com.alibaba.apiopenplatform.entity.Administrator;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

/**
 * 管理员注册/创建参数DTO
 *
 */
@Data
public class AdminCreateParam implements InputConverter<Administrator> {

    @NotBlank(message = "用户名不能为空")
    private String username;

    @NotBlank(message = "密码不能为空")
    private String password;
} 
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.repository;

import com.alibaba.apiopenplatform.entity.PortalDomain;

import java.util.List;
import java.util.Optional;

public interface PortalDomainRepository extends BaseRepository<PortalDomain, Long> {

    Optional<PortalDomain> findByDomain(String domain);

    Optional<PortalDomain> findByPortalIdAndDomain(String portalId, String domain);

    List<PortalDomain> findAllByPortalId(String portalId);

    List<PortalDomain> findAllByPortalIdIn(List<String> portalIds);

    void deleteAllByPortalId(String portalId);
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.result;

import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
import com.alibaba.apiopenplatform.entity.NacosInstance;
import lombok.Data;
import java.time.LocalDateTime;

@Data
public class NacosResult implements OutputConverter<NacosResult, NacosInstance> {

    private String nacosId;

    private String nacosName;

    private String serverUrl;


    private String username;

    private String accessKey;

    private String description;

    private String adminId;
    
    private LocalDateTime createAt;
} 
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@EnableJpaAuditing
public class PortalApplication {

    public static void main(String[] args) {
        SpringApplication.run(PortalApplication.class, args);
    }
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.consumer;

import com.alibaba.apiopenplatform.dto.converter.InputConverter;
import com.alibaba.apiopenplatform.entity.Consumer;
import lombok.Data;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

@Data
public class CreateConsumerParam implements InputConverter<Consumer> {

    @NotBlank(message = "Consumer名称不能为空")
    @Size(max = 50, message = "Consumer名称长度不能超过50个字符")
    private String name;

    @Size(max = 256, message = "Consumer描述长度不能超过256个字符")
    private String description;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.result;

import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
import com.alibaba.apiopenplatform.support.enums.GatewayType;
import com.aliyun.sdk.service.apig20240327.models.HttpApiApiInfo;
import lombok.Data;

@Data
public class APIResult implements OutputConverter<APIResult, HttpApiApiInfo> {

    private String apiId;

    private String apiName;

    @Override
    public APIResult convertFrom(HttpApiApiInfo apiInfo) {
        setApiId(apiInfo.getHttpApiId());
        setApiName(apiInfo.getName());
        return this;
    }
}

```

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

```yaml
version: '3'
services:
  mysql:
    image: opensource-registry.cn-hangzhou.cr.aliyuncs.com/higress-group/mysql:1.0.0
    container_name: mysql
    environment:
      - MYSQL_ROOT_PASSWORD=123456
      - MYSQL_DATABASE=portal_db
      - MYSQL_USER=portal_user
      - MYSQL_PASSWORD=portal_pass
    ports:
      - "3306:3306"
    volumes:
      - ./mysql/data:/var/lib/mysql
    restart: always

  himarket-server:
    image: opensource-registry.cn-hangzhou.cr.aliyuncs.com/higress-group/himarket-server:1.0.0
    container_name: himarket-server
    environment:
      - DB_HOST=mysql
      - DB_PORT=3306
      - DB_NAME=portal_db
      - DB_USERNAME=portal_user
      - DB_PASSWORD=portal_pass
    ports:
      - "8080:8080"
    depends_on:
      - mysql
    restart: always

  himarket-admin:
    image: opensource-registry.cn-hangzhou.cr.aliyuncs.com/higress-group/himarket-admin:1.0.0
    container_name: himarket-admin
    environment:
      - HIMARKET_SERVER=http://himarket-server:8080
    ports:
      - "5174:8000"
    depends_on:
      - himarket-server
    restart: always

  himarket-frontend:
    image: opensource-registry.cn-hangzhou.cr.aliyuncs.com/higress-group/himarket-frontend:1.0.0
    container_name: himarket-frontend
    environment:
      - HIMARKET_SERVER=http://himarket-server:8080
    ports:
      - "5173:8000"
    depends_on:
      - himarket-server
    restart: always
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.core.constant;

public class CommonConstants {

    // Token相关
    public static final String AUTHORIZATION_HEADER = "Authorization";
    public static final String BEARER_PREFIX = "Bearer ";

    // 角色前缀
    public static final String ROLE_PREFIX = "ROLE_";
    public static final String USER_TYPE = "userType";
    public static final String USER_ID = "userId";

    // Cookie相关
    public static final String AUTH_TOKEN_COOKIE = "auth_token";

    // HTTP
    public static final Integer HTTP_PORT = 80;
    public static final Integer HTTPS_PORT = 443;

}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.consumer;

import com.alibaba.apiopenplatform.dto.converter.InputConverter;
import com.alibaba.apiopenplatform.entity.ConsumerCredential;
import com.alibaba.apiopenplatform.support.consumer.ApiKeyConfig;
import com.alibaba.apiopenplatform.support.consumer.HmacConfig;
import com.alibaba.apiopenplatform.support.consumer.JwtConfig;
import lombok.Data;

@Data
public class UpdateCredentialParam implements InputConverter<ConsumerCredential> {

    private ApiKeyConfig apiKeyConfig;

    private HmacConfig hmacConfig;

    private JwtConfig jwtConfig;
}

```

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

```typescript
import { Routes, Route } from "react-router-dom";
import Home from "./pages/Home";
import Apis from "./pages/Apis";
import ApiDetail from "./pages/ApiDetail";
import Consumers from "./pages/Consumers";
import ConsumerDetail from "./pages/ConsumerDetail";
import GettingStarted from "./pages/GettingStarted";
import Mcp from "./pages/Mcp";
import Login from "./pages/Login";
import Register from "./pages/Register";
import Profile from './pages/Profile'
import McpDetail from "./pages/McpDetail";
import Callback from "./pages/Callback";
import OidcCallback from "./pages/OidcCallback";

export function Router() {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/getting-started" element={<GettingStarted />} />
      <Route path="/apis" element={<Apis />} />
      <Route path="/apis/:id" element={<ApiDetail />} />
      <Route path="/consumers/:consumerId" element={<ConsumerDetail />} />
      <Route path="/consumers" element={<Consumers />} />
      <Route path="/mcp" element={<Mcp />} />
      <Route path="/mcp/:mcpName" element={<McpDetail />} />
      <Route path="/login" element={<Login />} />
      <Route path="/register" element={<Register />} />
      <Route path="/profile" element={<Profile />} />
      <Route path="/callback" element={<Callback />} />
      <Route path="/oidc/callback" element={<OidcCallback />} />

      {/* 其他页面可继续添加 */}
    </Routes>
  );
} 
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.converter;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;

public interface OutputConverter<Target extends OutputConverter<Target, Source>, Source> {

    /**
     * 以Source更新Target
     *
     * @param source
     * @return
     */
    @SuppressWarnings("unchecked")
    default Target convertFrom(Source source) {
        BeanUtil.copyProperties(source, this, configOptions());
        return (Target) this;
    }

    default CopyOptions configOptions() {
        return CopyOptions.create().ignoreNullValue().ignoreError();
    }
}


```

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

```typescript
import { createBrowserRouter, Navigate } from 'react-router-dom';
import LayoutWrapper from '@/components/LayoutWrapper';
import Portals from '@/pages/Portals';
import ApiProducts from '@/pages/ApiProducts';
import GatewayConsoles from '@/pages/GatewayConsoles';
import NacosConsoles from '@/pages/NacosConsoles';
import PortalDetail from '@/pages/PortalDetail';
import ApiProductDetail from '@/pages/ApiProductDetail';
import Login from '@/pages/Login';

export const router = createBrowserRouter([
  {
    path: '/login',
    element: <Login />,
  },
  {
    path: '/',
    element: <LayoutWrapper />,
    children: [
      {
        index: true,
        element: <Navigate to="/portals" replace />,
      },
      {
        path: 'portals',
        element: <Portals />,
      },
      {
        path: 'portals/detail',
        element: <PortalDetail />,
      },
      {
        path: 'api-products',
        element: <ApiProducts />,
      },
      {
        path: 'api-products/detail',
        element: <ApiProductDetail />,
      },
      {
        path: 'consoles',
        element: <Navigate to="/consoles/gateway" replace />,
      },
      {
        path: 'consoles/gateway',
        element: <GatewayConsoles />,
      },
      {
        path: 'consoles/nacos',
        element: <NacosConsoles />,
      },
      {
        path: '*',
        element: <Navigate to="/portals" replace />,
      },
    ],
  },
]);

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.result;

import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
import com.alibaba.apiopenplatform.entity.ConsumerCredential;
import com.alibaba.apiopenplatform.support.consumer.ApiKeyConfig;
import com.alibaba.apiopenplatform.support.consumer.HmacConfig;
import com.alibaba.apiopenplatform.support.consumer.JwtConfig;
import lombok.Data;

@Data
public class ConsumerCredentialResult implements OutputConverter<ConsumerCredentialResult, ConsumerCredential> {

    private JwtConfig jwtConfig;

    private HmacConfig hmacConfig;

    private ApiKeyConfig apiKeyConfig;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.portal;

import com.alibaba.apiopenplatform.dto.converter.InputConverter;
import com.alibaba.apiopenplatform.entity.Portal;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

@Schema(description = "创建门户参数")
@Data
public class CreatePortalParam implements InputConverter<Portal> {

    @NotBlank(message = "门户名称不能为空")
    @Size(max = 50, message = "门户名称长度不能超过50个字符")
    private String name;

    @Size(max = 1024, message = "门户描述长度不能超过1024个字符")
    private String description;
}

```

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

```typescript
import type { Product } from "./index";

export interface Consumer {
  consumerId: string;
  name: string;
  description?: string;
  status?: string;
  createAt?: string;
  enabled?: boolean;
}

export type ConsumerCredential = HMACCredential | APIKeyCredential;

export interface HMACCredential {
  ak?: string;
  sk?: string;
  mode?: 'SYSTEM' | 'CUSTOM';
}

export interface APIKeyCredential {
  apiKey?: string;
  mode?: 'SYSTEM' | 'CUSTOM';
}

export interface ConsumerCredentialResult {
  apiKeyConfig?: {
    credentials?: Array<{
      apiKey?: string;
      mode?: 'SYSTEM' | 'CUSTOM';
    }>;
    source?: string;
    key?: string;
  };
  hmacConfig?: {
    credentials?: Array<{
      ak?: string;
      sk?: string;
      mode?: 'SYSTEM' | 'CUSTOM';
    }>;
  };
  jwtConfig?: Record<string, unknown>;
}

export interface Subscription {
  productId: string;
  consumerId: string;
  status: 'PENDING' | 'APPROVED';
  createAt: string;
  updatedAt: string;
  productName: string;
  productType: 'REST_API' | 'MCP_SERVER';
  consumerName?: string;
  product?: Product;
}

export interface CreateCredentialParam {
  apiKeyConfig?: {
    credentials?: Array<{
      apiKey?: string;
      mode?: 'SYSTEM' | 'CUSTOM';
    }>;
    source?: string;
    key?: string;
  };
  hmacConfig?: {
    credentials?: Array<{
      ak?: string;
      sk?: string;
      mode?: 'SYSTEM' | 'CUSTOM';
    }>;
  };
  jwtConfig?: Record<string, unknown>;
} 
```

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

```json
{
  "name": "portal-frontend",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc -b && vite build",
    "lint": "eslint .",
    "preview": "vite preview",
    "prepare": "husky",
    "serve": "npm run build && npm start",
    "type-check": "tsc -b"
  },
  "dependencies": {
    "@ant-design/icons": "^5.2.7",
    "antd": "^5.15.8",
    "axios": "^1.10.0",
    "clsx": "^2.1.1",
    "js-yaml": "^4.1.0",
    "monaco-editor": "^0.52.2",
    "postcss": "^8.5.6",
    "react": "^18.0.0",
    "react-dom": "^18.0.0",
    "react-markdown": "^10.1.0",
    "react-markdown-editor-lite": "^1.3.4",
    "react-monaco-editor": "^0.59.0",
    "react-router-dom": "^6.23.1",
    "remark-gfm": "^4.0.1",
    "swagger-ui-react": "^5.29.0",
    "terser": "^5.43.1"
  },
  "devDependencies": {
    "@eslint/js": "^9.30.1",
    "@types/js-yaml": "^4.0.9",
    "@types/node": "^24.3.0",
    "@types/react": "^18.3.3",
    "@types/react-dom": "^18.3.3",
    "@types/swagger-ui-react": "^5.18.0",
    "@vitejs/plugin-react": "^4.6.0",
    "autoprefixer": "^10.4.19",
    "compression": "^1.8.1",
    "eslint": "^9.30.1",
    "eslint-plugin-react-hooks": "^5.2.0",
    "eslint-plugin-react-refresh": "^0.4.20",
    "globals": "^16.3.0",
    "husky": "^9.1.7",
    "postcss": "^8.5.6",
    "tailwindcss": "^3.4.3",
    "typescript": "~5.8.3",
    "typescript-eslint": "^8.35.1",
    "vite": "^4.5.14"
  }
}

```

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

```css
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
  --radius: 0.625rem;
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.145 0 0);
  --popover: oklch(1 0 0);
  --popover-foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --secondary: oklch(0.97 0 0);
  --secondary-foreground: oklch(0.205 0 0);
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);
  --accent: oklch(0.97 0 0);
  --accent-foreground: oklch(0.205 0 0);
  --destructive: oklch(0.577 0.245 27.325);
  --border: oklch(0.922 0 0);
  --input: oklch(0.922 0 0);
  --ring: oklch(0.708 0 0);
}

.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --card: oklch(0.205 0 0);
  --card-foreground: oklch(0.985 0 0);
  --popover: oklch(0.205 0 0);
  --popover-foreground: oklch(0.985 0 0);
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
  --secondary: oklch(0.269 0 0);
  --secondary-foreground: oklch(0.985 0 0);
  --muted: oklch(0.269 0 0);
  --muted-foreground: oklch(0.708 0 0);
  --accent: oklch(0.269 0 0);
  --accent-foreground: oklch(0.985 0 0);
  --destructive: oklch(0.704 0.191 22.216);
  --border: oklch(1 0 0 / 10%);
  --input: oklch(1 0 0 / 15%);
  --ring: oklch(0.556 0 0);
}

@layer base {
  * {
    @apply border-gray-200;
  }
  body {
    @apply bg-white text-gray-900;
  }
}

```

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

```css
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
  --radius: 0.625rem;
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.145 0 0);
  --popover: oklch(1 0 0);
  --popover-foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --secondary: oklch(0.97 0 0);
  --secondary-foreground: oklch(0.205 0 0);
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);
  --accent: oklch(0.97 0 0);
  --accent-foreground: oklch(0.205 0 0);
  --destructive: oklch(0.577 0.245 27.325);
  --border: oklch(0.922 0 0);
  --input: oklch(0.922 0 0);
  --ring: oklch(0.708 0 0);
}

.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --card: oklch(0.205 0 0);
  --card-foreground: oklch(0.985 0 0);
  --popover: oklch(0.205 0 0);
  --popover-foreground: oklch(0.985 0 0);
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
  --secondary: oklch(0.269 0 0);
  --secondary-foreground: oklch(0.985 0 0);
  --muted: oklch(0.269 0 0);
  --muted-foreground: oklch(0.708 0 0);
  --accent: oklch(0.269 0 0);
  --accent-foreground: oklch(0.985 0 0);
  --destructive: oklch(0.704 0.191 22.216);
  --border: oklch(1 0 0 / 10%);
  --input: oklch(1 0 0 / 15%);
  --ring: oklch(0.556 0 0);
}

@layer base {
  * {
    @apply border-gray-200;
  }
  body {
    @apply bg-white text-gray-900;
  }
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.result;

import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
import com.alibaba.apiopenplatform.service.gateway.HigressOperator.HigressMCPConfig;
import lombok.Data;
import lombok.EqualsAndHashCode;

@EqualsAndHashCode(callSuper = true)
@Data
public class HigressMCPServerResult extends GatewayMCPServerResult implements OutputConverter<HigressMCPServerResult, HigressMCPConfig> {

    @Override
    public HigressMCPServerResult convertFrom(HigressMCPConfig mcp) {
        HigressMCPServerResult r = OutputConverter.super.convertFrom(mcp);
        r.setMcpServerName(mcp.getName());
        return r;
    }
}
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.repository;

import com.alibaba.apiopenplatform.entity.Portal;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.Optional;

public interface PortalRepository extends BaseRepository<Portal, Long> {

    Optional<Portal> findFirstByOrderByIdAsc();

    Optional<Portal> findByPortalIdAndAdminId(String portalId, String adminId);

    Optional<Portal> findByPortalId(String portalId);

    Optional<Portal> findByNameAndAdminId(String name, String adminId);

    Optional<Portal> findByName(String name);

    Page<Portal> findByAdminId(String adminId, Pageable pageable);
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.result;

import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
import com.alibaba.apiopenplatform.entity.ProductSubscription;
import com.alibaba.apiopenplatform.support.enums.ProductType;
import lombok.Data;

import java.time.LocalDateTime;

@Data
public class SubscriptionResult implements OutputConverter<SubscriptionResult, ProductSubscription> {

    private String productId;

    private String consumerId;

    private String status;

    private ProductType productType;

    private String productName;

    private String consumerName;

    private LocalDateTime createAt;

    private LocalDateTime updatedAt;
}
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.support.portal;

import com.alibaba.apiopenplatform.support.enums.GrantType;
import lombok.Data;

@Data
public class OidcConfig {
    /**
     * 提供商
     */
    private String provider;

    /**
     * 对外的名称
     */
    private String name;

    /**
     * 登录按钮logo
     */
    private String logoUrl;

    /**
     * 是否启用
     */
    private boolean enabled = true;

    /**
     * 授权类型,默认授权码
     */
    private GrantType grantType = GrantType.AUTHORIZATION_CODE;

    /**
     * 授权码模式配置
     */
    private AuthCodeConfig authCodeConfig;

    /**
     * 身份映射
     */
    private IdentityMapping identityMapping = new IdentityMapping();
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.portal;

import com.alibaba.apiopenplatform.dto.converter.InputConverter;
import com.alibaba.apiopenplatform.entity.PortalDomain;
import com.alibaba.apiopenplatform.support.enums.DomainType;
import com.alibaba.apiopenplatform.support.enums.ProtocolType;
import lombok.Data;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

@Data
public class BindDomainParam implements InputConverter<PortalDomain> {

    @NotBlank(message = "门户域名不能为空")
    private String domain;

    @NotNull(message = "域名协议不能为空")
    private ProtocolType protocol;

    private DomainType type = DomainType.CUSTOM;
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.repository;

import com.alibaba.apiopenplatform.entity.ProductSubscription;

import java.util.List;
import java.util.Optional;

public interface SubscriptionRepository extends BaseRepository<ProductSubscription, Long> {

    Optional<ProductSubscription> findByConsumerIdAndProductId(String consumerId, String productId);

    List<ProductSubscription> findALlByConsumerId(String consumerId);

    List<ProductSubscription> findAllByProductId(String productId);

    void deleteAllByConsumerId(String consumerId);

    void deleteAllByProductId(String productId);

    void deleteByConsumerIdAndProductId(String consumerId, String productId);
}
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.core.response;

import lombok.Data;
import lombok.experimental.Accessors;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class Response<T> {
    private String code;
    private String message;
    private T data;

    public static <T> Response<T> ok(T data) {
        return new Response<T>()
                .setCode("SUCCESS")
                .setData(data);
    }

    public static <T> Response<T> fail(String code, String message) {
        return new Response<T>()
                .setCode(code)
                .setMessage(message);
    }
}


```

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

```
<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:
--------------------------------------------------------------------------------

```
<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
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.nacos;

import lombok.Data;

import javax.validation.constraints.NotBlank;

import com.aliyun.teaopenapi.models.Config;

/**
 * 查询Nacos集群参数
 *
 */
@Data
public class QueryNacosParam {

    @NotBlank(message = "地域不能为空")
    private String regionId;

    @NotBlank(message = "accessKey不能为空")
    private String accessKey;

    @NotBlank(message = "secretKey不能为空")
    private String secretKey;

    public Config toClientConfig() {
        Config config = new Config()
                .setAccessKeyId(this.accessKey)
                .setAccessKeySecret(this.secretKey)
                .setRegionId(this.regionId);
        return config;
    }
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.service.gateway.client;

import java.net.InetSocketAddress;
import java.net.Socket;

public abstract class GatewayClient {

    public void close() {

    }

    protected String getAPIGEndpoint(String region) {
        String internalEndpoint = String.format("apig-vpc.%s.aliyuncs.com", region);
        String publicEndpoint = String.format("apig.%s.aliyuncs.com", region);

        // 优先尝试内网endpoint
        try (Socket socket = new Socket()) {
            socket.connect(new InetSocketAddress(internalEndpoint, 443), 1000); // 1秒超时
            return internalEndpoint;
        } catch (Exception e) {
            return publicEndpoint;
        }
    }
}

```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.result;

import com.alibaba.apiopenplatform.dto.converter.OutputConverter;
import com.alibaba.nacos.api.ai.model.mcp.McpServerBasicInfo;
import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
@EqualsAndHashCode(callSuper = true)
public class NacosMCPServerResult extends MCPServerResult implements OutputConverter<NacosMCPServerResult, McpServerBasicInfo> {

    private String version;

    @Override
    public NacosMCPServerResult convertFrom(McpServerBasicInfo basicInfo) {
        OutputConverter.super.convertFrom(basicInfo);
        setMcpServerName(basicInfo.getName());
        setVersion(basicInfo.getVersion());
        return this;
    }
} 
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.repository;

import com.alibaba.apiopenplatform.entity.DeveloperExternalIdentity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.Optional;

public interface DeveloperExternalIdentityRepository extends JpaRepository<DeveloperExternalIdentity, Long> {

    List<DeveloperExternalIdentity> findByDeveloper_DeveloperId(String developerId);

    Optional<DeveloperExternalIdentity> findByProviderAndSubject(String provider, String subject);

    void deleteByProviderAndSubjectAndDeveloper_DeveloperId(String provider, String subject, String developerId);

    void deleteByDeveloper_DeveloperId(String developerId);
}
```

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

```java
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.alibaba.apiopenplatform.dto.params.portal;

import com.alibaba.apiopenplatform.dto.converter.InputConverter;
import com.alibaba.apiopenplatform.entity.Portal;
import com.alibaba.apiopenplatform.support.portal.PortalSettingConfig;
import com.alibaba.apiopenplatform.support.portal.PortalUiConfig;
import lombok.Data;

import javax.validation.constraints.Size;

@Data
public class UpdatePortalParam implements InputConverter<Portal> {

    @Size(max = 50, message = "门户名称长度不能超过50个字符")
    private String name;

    @Size(max = 1024, message = "门户描述长度不能超过1024个字符")
    private String description;

    private PortalSettingConfig portalSettingConfig;

    private PortalUiConfig portalUiConfig;
}

```
Page 1/7FirstPrevNextLast