feat: marketplace page

This commit is contained in:
Junyan Qin
2025-08-16 18:05:33 +08:00
parent 5179b3e53a
commit 28d4b1dd61
35 changed files with 1095 additions and 395 deletions
+11 -24
View File
@@ -1,8 +1,8 @@
import { IDynamicFormItemSchema } from '@/app/infra/entities/form/dynamic';
import { PipelineConfigTab } from '@/app/infra/entities/pipeline';
import { I18nLabel } from '@/app/infra/entities/common';
import { I18nObject } from '@/app/infra/entities/common';
import { Message } from '@/app/infra/entities/message';
import { Plugin } from '@/app/infra/entities/plugin';
import { Plugin, PluginV4 } from '@/app/infra/entities/plugin';
export interface ApiResponse<T> {
code: number;
@@ -24,8 +24,8 @@ export interface ApiRespProviderRequester {
export interface Requester {
name: string;
label: I18nLabel;
description: I18nLabel;
label: I18nObject;
description: I18nObject;
icon?: string;
spec: {
config: IDynamicFormItemSchema[];
@@ -82,8 +82,8 @@ export interface ApiRespPlatformAdapter {
export interface Adapter {
name: string;
label: I18nLabel;
description: I18nLabel;
label: I18nObject;
description: I18nObject;
icon?: string;
spec: {
config: IDynamicFormItemSchema[];
@@ -183,26 +183,13 @@ export interface ApiRespUserToken {
token: string;
}
export interface MarketPlugin {
ID: number;
CreatedAt: string; // ISO 8601 格式日期
UpdatedAt: string;
DeletedAt: string | null;
name: string;
author: string;
description: string;
repository: string; // GitHub 仓库路径
artifacts_path: string;
stars: number;
downloads: number;
status: 'initialized' | 'mounted'; // 可根据实际状态值扩展联合类型
synced_at: string;
pushed_at: string; // 最后一次代码推送时间
export interface ApiRespMarketplacePlugins {
plugins: PluginV4[];
total: number;
}
export interface MarketPluginResponse {
plugins: MarketPlugin[];
total: number;
export interface ApiRespMarketplacePluginDetail {
plugin: PluginV4;
}
interface GetPipelineConfig {
+4 -4
View File
@@ -1,4 +1,4 @@
export interface I18nLabel {
export interface I18nObject {
en_US: string;
zh_Hans: string;
ja_JP?: string;
@@ -9,12 +9,12 @@ export interface ComponentManifest {
kind: string;
metadata: {
name: string;
label: I18nLabel;
description?: I18nLabel;
label: I18nObject;
description?: I18nObject;
icon?: string;
repository?: string;
version?: string;
author?: string;
};
spec: object;
spec: Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any
}
+4 -4
View File
@@ -1,13 +1,13 @@
import { I18nLabel } from '@/app/infra/entities/common';
import { I18nObject } from '@/app/infra/entities/common';
export interface IDynamicFormItemSchema {
id: string;
default: string | number | boolean | Array<unknown>;
label: I18nLabel;
label: I18nObject;
name: string;
required: boolean;
type: DynamicFormItemType;
description?: I18nLabel;
description?: I18nObject;
options?: IDynamicFormItemOption[];
}
@@ -25,5 +25,5 @@ export enum DynamicFormItemType {
export interface IDynamicFormItemOption {
name: string;
label: I18nLabel;
label: I18nObject;
}
+4 -4
View File
@@ -1,4 +1,4 @@
import { I18nLabel } from '@/app/infra/entities/common';
import { I18nObject } from '@/app/infra/entities/common';
import { IDynamicFormItemSchema } from '@/app/infra/entities/form/dynamic';
export interface PipelineFormEntity {
@@ -11,13 +11,13 @@ export interface PipelineFormEntity {
export interface PipelineConfigTab {
name: string;
label: I18nLabel;
label: I18nObject;
stages: PipelineConfigStage[];
}
export interface PipelineConfigStage {
name: string;
label: I18nLabel;
description?: I18nLabel;
label: I18nObject;
description?: I18nObject;
config: IDynamicFormItemSchema[];
}
+27 -1
View File
@@ -1,4 +1,4 @@
import { ComponentManifest } from '@/app/infra/entities/common';
import { ComponentManifest, I18nObject } from '@/app/infra/entities/common';
export interface Plugin {
status: 'intialized' | 'mounted' | 'unmounted';
@@ -9,6 +9,8 @@ export interface Plugin {
};
debug: boolean;
enabled: boolean;
install_source: string;
install_info: Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any
components: {
component_config: object;
manifest: {
@@ -16,3 +18,27 @@ export interface Plugin {
};
};
}
// marketplace plugin v4
export enum PluginV4Status {
Any = 'any',
Live = 'live',
Deleted = 'deleted',
}
export interface PluginV4 {
id: number;
plugin_id: string;
author: string;
name: string;
label: I18nObject;
description: I18nObject;
icon: string;
repository: string;
tags: string[];
install_count: number;
latest_version: string;
status: PluginV4Status;
created_at: string;
updated_at: string;
}
+12
View File
@@ -259,6 +259,18 @@ export class BackendClient extends BaseHttpClient {
return this.postFile('/api/v1/plugins/install/local', formData);
}
public installPluginFromMarketplace(
author: string,
name: string,
version: string,
): Promise<AsyncTaskCreatedResp> {
return this.post('/api/v1/plugins/install/marketplace', {
plugin_author: author,
plugin_name: name,
plugin_version: version,
});
}
public removePlugin(
author: string,
name: string,
+54 -21
View File
@@ -1,5 +1,8 @@
import { BaseHttpClient } from './BaseHttpClient';
import { MarketPluginResponse } from '@/app/infra/entities/api';
import {
ApiRespMarketplacePluginDetail,
ApiRespMarketplacePlugins,
} from '@/app/infra/entities/api';
/**
* 云服务客户端
@@ -11,29 +14,59 @@ export class CloudServiceClient extends BaseHttpClient {
super(baseURL, true);
}
/**
* 获取插件市场插件列表
* @param page 页码
* @param page_size 每页大小
* @param query 搜索关键词
* @param sort_by 排序字段
* @param sort_order 排序顺序
*/
public getMarketPlugins(
public getMarketplacePlugins(
page: number,
page_size: number,
query: string,
sort_by: string = 'stars',
sort_order: string = 'DESC',
): Promise<MarketPluginResponse> {
return this.post(`/api/v1/market/plugins`, {
page,
page_size,
query,
sort_by,
sort_order,
sort_by?: string,
sort_order?: string,
): Promise<ApiRespMarketplacePlugins> {
return this.get<ApiRespMarketplacePlugins>('/api/v1/marketplace/plugins', {
params: { page, page_size, sort_by, sort_order },
});
}
// 未来可以在这里添加更多 cloud service 相关的方法
public searchMarketplacePlugins(
query: string,
page: number,
page_size: number,
sort_by?: string,
sort_order?: string,
): Promise<ApiRespMarketplacePlugins> {
return this.post<ApiRespMarketplacePlugins>(
'/api/v1/marketplace/plugins/search',
{
query,
page,
page_size,
sort_by,
sort_order,
},
);
}
public getPluginDetail(
author: string,
pluginName: string,
): Promise<ApiRespMarketplacePluginDetail> {
return this.get<ApiRespMarketplacePluginDetail>(
`/api/v1/marketplace/plugins/${author}/${pluginName}`,
);
}
public getPluginREADME(
author: string,
pluginName: string,
): Promise<{ readme: string }> {
return this.get<{ readme: string }>(
`/api/v1/marketplace/plugins/${author}/${pluginName}/resources/README`,
);
}
public getPluginIconURL(author: string, name: string): string {
return `${this.baseURL}/api/v1/marketplace/plugins/${author}/${name}/resources/icon`;
}
public getPluginMarketplaceURL(author: string, name: string): string {
return `${this.baseURL}/market?author=${author}&plugin=${name}`;
}
}
+5 -1
View File
@@ -32,7 +32,11 @@ const marketPlugins = await cloudClient.getMarketPlugins(1, 10, 'search term');
// 使用云服务客户端(同步方式,可能使用默认 URL)
import { cloudServiceClient } from '@/app/infra/http';
const marketPlugins = await cloudServiceClient.getMarketPlugins(1, 10, 'search term');
const marketPlugins = await cloudServiceClient.getMarketPlugins(
1,
10,
'search term',
);
```
### 向后兼容(不推荐)