mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-17 11:14:19 +00:00
feat: plugin market pagination access api
This commit is contained in:
@@ -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 PluginMarketCardComponent from "@/app/home/plugins/plugin-market/plugin-market-card/PluginMarketCardComponent";
|
||||||
import {Input, Pagination} from "antd";
|
import {Input, Pagination} from "antd";
|
||||||
import {debounce} from "lodash"
|
import {debounce} from "lodash"
|
||||||
|
import {httpClient, spaceClient} from "@/app/infra/http/HttpClient";
|
||||||
|
|
||||||
export default function PluginMarketComponent () {
|
export default function PluginMarketComponent () {
|
||||||
const [marketPluginList, setMarketPluginList] = useState<PluginMarketCardVO[]>([])
|
const [marketPluginList, setMarketPluginList] = useState<PluginMarketCardVO[]>([])
|
||||||
|
const [totalCount, setTotalCount] = useState(0)
|
||||||
|
const [nowPage, setNowPage] = useState(1)
|
||||||
const [searchKeyword, setSearchKeyword] = useState("")
|
const [searchKeyword, setSearchKeyword] = useState("")
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -20,65 +23,25 @@ export default function PluginMarketComponent () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onInputSearchKeyword(keyword: string) {
|
function onInputSearchKeyword(keyword: string) {
|
||||||
|
// 这里记得加防抖,暂时没加
|
||||||
setSearchKeyword(keyword)
|
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[]> {
|
function getPluginList(page: number = nowPage, keyword: string = searchKeyword) {
|
||||||
// TODO 实现搜索
|
spaceClient.getMarketPlugins(page, 10, keyword).then(res => {
|
||||||
const demoResult: PluginMarketCardVO[] = []
|
setMarketPluginList(res.plugins.map(marketPlugin => new PluginMarketCardVO({
|
||||||
for (let i = 0; i < keyword.length; i ++) {
|
author: marketPlugin.author,
|
||||||
demoResult.push(new PluginMarketCardVO({
|
description: marketPlugin.description,
|
||||||
author: "/hanahana",
|
githubURL: marketPlugin.repository,
|
||||||
description: "一个搜索测试的描述",
|
name: marketPlugin.name,
|
||||||
githubURL: "?",
|
pluginId: String(marketPlugin.ID),
|
||||||
name: "搜索插件" + i,
|
starCount: marketPlugin.stars,
|
||||||
pluginId: `${i}`,
|
})))
|
||||||
starCount: 19 + i,
|
setTotalCount(res.total)
|
||||||
version: `0.${i}`,
|
console.log("market plugins:", res)
|
||||||
}))
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,8 +67,9 @@ export default function PluginMarketComponent () {
|
|||||||
</div>
|
</div>
|
||||||
<Pagination
|
<Pagination
|
||||||
defaultCurrent={1}
|
defaultCurrent={1}
|
||||||
total={500}
|
total={totalCount}
|
||||||
onChange={(pageNumber) => {
|
onChange={(pageNumber) => {
|
||||||
|
setNowPage(pageNumber)
|
||||||
getPluginList(pageNumber)
|
getPluginList(pageNumber)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
export interface IPluginMarketCardVO {
|
export interface IPluginMarketCardVO {
|
||||||
pluginId: string;
|
pluginId: string;
|
||||||
author: string,
|
author: string,
|
||||||
version: string,
|
|
||||||
name: string,
|
name: string,
|
||||||
description: string,
|
description: string,
|
||||||
starCount: number,
|
starCount: number,
|
||||||
@@ -13,7 +12,6 @@ export class PluginMarketCardVO implements IPluginMarketCardVO {
|
|||||||
description: string;
|
description: string;
|
||||||
name: string;
|
name: string;
|
||||||
author: string;
|
author: string;
|
||||||
version: string;
|
|
||||||
githubURL: string;
|
githubURL: string;
|
||||||
starCount: number;
|
starCount: number;
|
||||||
|
|
||||||
@@ -21,11 +19,8 @@ export class PluginMarketCardVO implements IPluginMarketCardVO {
|
|||||||
this.description = prop.description
|
this.description = prop.description
|
||||||
this.name = prop.name
|
this.name = prop.name
|
||||||
this.author = prop.author
|
this.author = prop.author
|
||||||
this.version = prop.version
|
|
||||||
this.githubURL = prop.githubURL
|
this.githubURL = prop.githubURL
|
||||||
this.starCount = prop.starCount
|
this.starCount = prop.starCount
|
||||||
this.pluginId = prop.pluginId
|
this.pluginId = prop.pluginId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,4 +179,26 @@ export interface AsyncTask {
|
|||||||
|
|
||||||
export interface ApiRespUserToken {
|
export interface ApiRespUserToken {
|
||||||
token: string;
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import {
|
|||||||
ApiRespSystemInfo,
|
ApiRespSystemInfo,
|
||||||
ApiRespAsyncTasks,
|
ApiRespAsyncTasks,
|
||||||
ApiRespAsyncTask,
|
ApiRespAsyncTask,
|
||||||
ApiRespUserToken
|
ApiRespUserToken, MarketPluginResponse
|
||||||
} from "../api/api-types";
|
} from "../api/api-types";
|
||||||
import { notification } from "antd";
|
import { notification } from "antd";
|
||||||
|
|
||||||
@@ -50,19 +50,22 @@ export interface RequestConfig extends AxiosRequestConfig {
|
|||||||
|
|
||||||
class HttpClient {
|
class HttpClient {
|
||||||
private instance: AxiosInstance;
|
private instance: AxiosInstance;
|
||||||
|
private disableToken: boolean = false
|
||||||
// 暂不需要SSR
|
// 暂不需要SSR
|
||||||
// private ssrInstance: AxiosInstance | null = null
|
// private ssrInstance: AxiosInstance | null = null
|
||||||
|
|
||||||
constructor(baseURL?: string) {
|
constructor(
|
||||||
|
baseURL?: string,
|
||||||
|
disableToken?: boolean
|
||||||
|
) {
|
||||||
this.instance = axios.create({
|
this.instance = axios.create({
|
||||||
baseURL: baseURL || this.getBaseUrl(),
|
baseURL: baseURL || this.getBaseUrl(),
|
||||||
timeout: 15000,
|
timeout: 15000,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"X-Requested-With": "XMLHttpRequest"
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.disableToken = disableToken || false
|
||||||
this.initInterceptors();
|
this.initInterceptors();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +105,7 @@ class HttpClient {
|
|||||||
// config.headers.Cookie = cookies().toString()
|
// config.headers.Cookie = cookies().toString()
|
||||||
|
|
||||||
// 客户端添加认证头
|
// 客户端添加认证头
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined" && !this.disableToken) {
|
||||||
const session = this.getSessionSync();
|
const session = this.getSessionSync();
|
||||||
config.headers.Authorization = `Bearer ${session}`;
|
config.headers.Authorization = `Bearer ${session}`;
|
||||||
}
|
}
|
||||||
@@ -352,6 +355,19 @@ class HttpClient {
|
|||||||
return this.post(`/api/v1/plugins/${author}/${name}/update`);
|
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(
|
public installPluginFromGithub(
|
||||||
source: string
|
source: string
|
||||||
): Promise<AsyncTaskCreatedResp> {
|
): Promise<AsyncTaskCreatedResp> {
|
||||||
@@ -397,3 +413,6 @@ class HttpClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const httpClient = new HttpClient("https://version-4.langbot.dev");
|
export const httpClient = new HttpClient("https://version-4.langbot.dev");
|
||||||
|
|
||||||
|
// 临时写法,未来两种Client都继承自HttpClient父类,不允许共享方法
|
||||||
|
export const spaceClient = new HttpClient("https://space.langbot.app")
|
||||||
|
|||||||
Reference in New Issue
Block a user