feat: plugin market pagination access api

This commit is contained in:
HYana
2025-04-28 19:06:41 +08:00
parent 3d31ace50b
commit 9850a0c2bf
4 changed files with 67 additions and 67 deletions

View File

@@ -6,9 +6,12 @@ import {PluginMarketCardVO} from "@/app/home/plugins/plugin-market/plugin-market
import PluginMarketCardComponent from "@/app/home/plugins/plugin-market/plugin-market-card/PluginMarketCardComponent";
import {Input, Pagination} from "antd";
import {debounce} from "lodash"
import {httpClient, spaceClient} from "@/app/infra/http/HttpClient";
export default function PluginMarketComponent () {
const [marketPluginList, setMarketPluginList] = useState<PluginMarketCardVO[]>([])
const [totalCount, setTotalCount] = useState(0)
const [nowPage, setNowPage] = useState(1)
const [searchKeyword, setSearchKeyword] = useState("")
useEffect(() => {
@@ -20,65 +23,25 @@ export default function PluginMarketComponent () {
}
function onInputSearchKeyword(keyword: string) {
// 这里记得加防抖,暂时没加
setSearchKeyword(keyword)
debounceSearch(keyword)
setNowPage(1)
getPluginList(1, keyword)
}
const debounceSearch = useCallback(
debounce((keyword: string) => {
console.log("debounce search", keyword)
searchPlugin(keyword).then(marketPluginList => {
setMarketPluginList(marketPluginList)
})
}, 500), []
)
async function searchPlugin(keyword: string, pageNumber: number = 1): Promise<PluginMarketCardVO[]> {
// TODO 实现搜索
const demoResult: PluginMarketCardVO[] = []
for (let i = 0; i < keyword.length; i ++) {
demoResult.push(new PluginMarketCardVO({
author: "/hanahana",
description: "一个搜索测试的描述",
githubURL: "",
name: "搜索插件" + i,
pluginId: `${i}`,
starCount: 19 + i,
version: `0.${i}`,
}))
}
return demoResult
}
function getPluginList(pageNumber: number = 1) {
new Promise<PluginMarketCardVO[]>((resolve, reject) => {
const result = [
new PluginMarketCardVO({
pluginId: "aaa",
description: "一般的描述",
name: "插件AAA",
author: "/hana",
version: "0.1",
githubURL: "",
starCount: 23
}),
]
for (let i = 0; i < pageNumber; i ++) {
result.push(
new PluginMarketCardVO({
pluginId: "aaa",
description: "一般的描述",
name: "插件AAA",
author: "/hana",
version: "0.1",
githubURL: "",
starCount: 23
})
)
}
resolve(result)
}).then((value) => {
setMarketPluginList(value)
function getPluginList(page: number = nowPage, keyword: string = searchKeyword) {
spaceClient.getMarketPlugins(page, 10, keyword).then(res => {
setMarketPluginList(res.plugins.map(marketPlugin => new PluginMarketCardVO({
author: marketPlugin.author,
description: marketPlugin.description,
githubURL: marketPlugin.repository,
name: marketPlugin.name,
pluginId: String(marketPlugin.ID),
starCount: marketPlugin.stars,
})))
setTotalCount(res.total)
console.log("market plugins:", res)
})
}
@@ -104,8 +67,9 @@ export default function PluginMarketComponent () {
</div>
<Pagination
defaultCurrent={1}
total={500}
total={totalCount}
onChange={(pageNumber) => {
setNowPage(pageNumber)
getPluginList(pageNumber)
}}
/>

View File

@@ -1,7 +1,6 @@
export interface IPluginMarketCardVO {
pluginId: string;
author: string,
version: string,
name: string,
description: string,
starCount: number,
@@ -13,7 +12,6 @@ export class PluginMarketCardVO implements IPluginMarketCardVO {
description: string;
name: string;
author: string;
version: string;
githubURL: string;
starCount: number;
@@ -21,11 +19,8 @@ export class PluginMarketCardVO implements IPluginMarketCardVO {
this.description = prop.description
this.name = prop.name
this.author = prop.author
this.version = prop.version
this.githubURL = prop.githubURL
this.starCount = prop.starCount
this.pluginId = prop.pluginId
}
}

View File

@@ -179,4 +179,26 @@ export interface AsyncTask {
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: "synced" | string // 可根据实际状态值扩展联合类型
synced_at: string
pushed_at: string // 最后一次代码推送时间
}
export interface MarketPluginResponse {
plugins: MarketPlugin[]
total: number
}

View File

@@ -26,7 +26,7 @@ import {
ApiRespSystemInfo,
ApiRespAsyncTasks,
ApiRespAsyncTask,
ApiRespUserToken
ApiRespUserToken, MarketPluginResponse
} from "../api/api-types";
import { notification } from "antd";
@@ -50,19 +50,22 @@ export interface RequestConfig extends AxiosRequestConfig {
class HttpClient {
private instance: AxiosInstance;
private disableToken: boolean = false
// 暂不需要SSR
// private ssrInstance: AxiosInstance | null = null
constructor(baseURL?: string) {
constructor(
baseURL?: string,
disableToken?: boolean
) {
this.instance = axios.create({
baseURL: baseURL || this.getBaseUrl(),
timeout: 15000,
headers: {
"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest"
}
});
this.disableToken = disableToken || false
this.initInterceptors();
}
@@ -102,7 +105,7 @@ class HttpClient {
// config.headers.Cookie = cookies().toString()
// 客户端添加认证头
if (typeof window !== "undefined") {
if (typeof window !== "undefined" && !this.disableToken) {
const session = this.getSessionSync();
config.headers.Authorization = `Bearer ${session}`;
}
@@ -352,6 +355,19 @@ class HttpClient {
return this.post(`/api/v1/plugins/${author}/${name}/update`);
}
public getMarketPlugins(
page: number,
page_size: number,
query: string,
): Promise<MarketPluginResponse> {
return this.post(`/api/v1/market/plugins`, {
page,
page_size,
query,
sort_by: "stars",
sort_order: "DESC"
})
}
public installPluginFromGithub(
source: string
): Promise<AsyncTaskCreatedResp> {
@@ -397,3 +413,6 @@ class HttpClient {
}
export const httpClient = new HttpClient("https://version-4.langbot.dev");
// 临时写法未来两种Client都继承自HttpClient父类不允许共享方法
export const spaceClient = new HttpClient("https://space.langbot.app")