fix:reset

This commit is contained in:
yujiangping
2026-03-13 10:33:11 +08:00
parent 168cce1678
commit 6c69181290

View File

@@ -9,7 +9,6 @@ import type { McpServiceModalRef } from './types';
import pageEmptyIcon from '@/assets/images/empty/pageEmpty.png'
import Empty from '@/components/Empty/index'
import { getMarketTools, getMarketConfig, getMarketMCPs, getMarketMCPDetail, getMarketMCPsActivated, getTools } from '@/api/tools';
import BodyWrapper from '@/components/Empty/BodyWrapper';
interface MarketSource {
id: string;
name: string;
@@ -75,6 +74,7 @@ const Market: React.FC<{ getStatusTag?: (status: string) => ReactNode }> = () =>
const [activatedMcps, setActivatedMcps] = useState<string[]>([]);
const [currentPage, setCurrentPage] = useState(1);
const pageSize = 20;
const searchTimerRef = useRef<number | null>(null);
// 获取市场数据
useEffect(() => {
@@ -109,7 +109,7 @@ const Market: React.FC<{ getStatusTag?: (status: string) => ReactNode }> = () =>
fetchMarketData();
}, [message]);
const fetchMcpList = async (sourceId: string, page = 1, append = false) => {
const fetchMcpList = async (sourceId: string, page = 1, append = false, keywords = '') => {
setLoading(true);
try {
let configId = configIdMap[sourceId];
@@ -139,7 +139,12 @@ const Market: React.FC<{ getStatusTag?: (status: string) => ReactNode }> = () =>
const allTools: any = await getTools({ tool_type: 'mcp' });
const toolsList = Array.isArray(allTools) ? allTools : [];
const res: any = await getMarketMCPs({ mcp_market_config_id: configId, page, pagesize: pageSize });
const res: any = await getMarketMCPs({
mcp_market_config_id: configId,
page,
pagesize: pageSize,
...(keywords ? { keywords } : {})
});
if (res?.items && Array.isArray(res.items)) {
// 标记已激活和已入库的 MCP
const mcpsWithActivated = res.items.map((item: MarketMcp) => {
@@ -176,8 +181,46 @@ const Market: React.FC<{ getStatusTag?: (status: string) => ReactNode }> = () =>
const loadMore = useCallback(() => {
if (!selectedSource || loading) return;
fetchMcpList(selectedSource, currentPage + 1, true);
}, [selectedSource, currentPage, loading]);
fetchMcpList(selectedSource, currentPage + 1, true, searchKeyword);
}, [selectedSource, currentPage, loading, searchKeyword]);
const handleSearchChange = (value: string) => {
setSearchKeyword(value);
// 清除之前的定时器
if (searchTimerRef.current) {
clearTimeout(searchTimerRef.current);
}
// 如果清空搜索框,恢复原始列表
if (!value.trim()) {
if (selectedSource) {
// 清除缓存,重新加载原始列表
setMcpCache(prev => {
const next = { ...prev };
delete next[selectedSource];
return next;
});
setCurrentPage(1);
fetchMcpList(selectedSource, 1, false, '');
}
return;
}
// 设置新的定时器500ms 后执行搜索
searchTimerRef.current = setTimeout(() => {
if (selectedSource) {
// 清除缓存,重新搜索
setMcpCache(prev => {
const next = { ...prev };
delete next[selectedSource];
return next;
});
setCurrentPage(1);
fetchMcpList(selectedSource, 1, false, value);
}
}, 500);
};
const handleSelectSource = async (sourceId: string) => {
setSelectedSource(sourceId);
@@ -313,12 +356,6 @@ const Market: React.FC<{ getStatusTag?: (status: string) => ReactNode }> = () =>
if (!source) return null;
const mcpList = mcpCache[selectedSource] || [];
const filteredList = mcpList.filter(mcp => {
const name = getLocaleField(mcp, 'name');
const desc = getLocaleField(mcp, 'description');
return name.toLowerCase().includes(searchKeyword.toLowerCase()) ||
desc.toLowerCase().includes(searchKeyword.toLowerCase());
});
return (
<>
@@ -358,15 +395,14 @@ const Market: React.FC<{ getStatusTag?: (status: string) => ReactNode }> = () =>
{t('tool.marketRefresh')}
</Button>
)}
{mcpList.length > 0 && (
<Input
prefix={<SearchOutlined />}
placeholder={t('tool.marketSearchPlaceholder')}
value={searchKeyword}
onChange={(e) => setSearchKeyword(e.target.value)}
onChange={(e) => handleSearchChange(e.target.value)}
allowClear
style={{ width: 200 }}
/>
)}
</div>
<Button icon={<SettingOutlined />} onClick={() => handleOpenConfig(selectedSource)}>
{t('tool.marketConfigBtn')}
@@ -378,10 +414,18 @@ const Market: React.FC<{ getStatusTag?: (status: string) => ReactNode }> = () =>
</div>
<div className="rb:mt-6">
<BodyWrapper loading={loading} empty={mcpList.length === 0}>
<div id="mcpScrollableDiv" className="rb:overflow-y-auto rb:h-[calc(100vh-260px)]">
{!loading && mcpList.length === 0 ? (
<Empty
url={pageEmptyIcon}
title={searchKeyword ? t('tool.marketNoSearchResult') : t('tool.marketNoData')}
subTitle={searchKeyword ? t('tool.marketNoSearchResultDesc') : t('tool.marketNoDataDesc')}
size={200}
className="rb:h-full"
/>
) : (
<InfiniteScroll
dataLength={filteredList.length}
dataLength={mcpList.length}
next={loadMore}
hasMore={hasMore}
loader={<Skeleton active paragraph={{ rows: 2 }} className="rb:mt-4" />}
@@ -394,7 +438,7 @@ const Market: React.FC<{ getStatusTag?: (status: string) => ReactNode }> = () =>
gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))'
}}
>
{filteredList.map(mcp => (
{mcpList.map(mcp => (
<div
key={mcp.id}
className="rb:bg-white rb:border rb:border-gray-200 rb:rounded-lg rb:p-4 rb:pb-2 rb:transition-all rb:duration-200 hover:rb:shadow-lg hover:rb:border-gray-300"
@@ -453,8 +497,8 @@ const Market: React.FC<{ getStatusTag?: (status: string) => ReactNode }> = () =>
))}
</div>
</InfiniteScroll>
)}
</div>
</BodyWrapper>
</div>
</>
);