You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
5.7 KiB
TypeScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import React, { useEffect, useState } from 'react';
import styles from './style/compCard.module.less';
import { Card, Grid, Rate, Typography, Pagination, Spin, Empty, Image } from '@arco-design/web-react';
import { useRouter } from 'next/router';
import { getComponentMarket } from '@/api/componentMarket';
import { IconStarFill } from '@arco-design/web-react/icon';
const { Row, Col } = Grid;
interface CompCardProps {
selectedTab: string;
componentClassify: string;
searchClassify: string;
searchKeyword: string;
selectedComp: (component: ComponentItem) => void;
}
interface ComponentItem {
id: string;
name: string;
identifier?: string;
componentClassify?: string;
deployType?: string;
star?: number;
description?: string;
[key: string]: any;
}
const CompCard: React.FC<CompCardProps> = ({
selectedTab,
componentClassify,
searchClassify,
searchKeyword,
selectedComp
}) => {
const [componentList, setComponentList] = useState<ComponentItem[]>([]);
const [loading, setLoading] = useState(false);
const [current, setCurrent] = useState(1);
const [total, setTotal] = useState(0);
const pageSize = 12; // 每页显示12条数据
const router = useRouter();
// 获取组件市场数据
const fetchComponentData = async (page = 1) => {
try {
setLoading(true);
// 根据搜索条件或当前Tab确定分类
let classifyLabel = '全部';
// 如果搜索框有选择分类,使用搜索框的分类
if (searchClassify && searchClassify !== '全部') {
classifyLabel = searchClassify;
}
// 否则使用当前Tab的分类
else if (componentClassify && componentClassify !== '全部') {
classifyLabel = componentClassify;
}
const params = {
componentClassify: classifyLabel,
keyword: searchKeyword || '',
current: page,
size: pageSize
};
const res: any = await getComponentMarket(params);
if (res?.code === 200 && res?.data) {
setComponentList(res.data.list || []);
setTotal(res.data.totalCount || 0);
}
else {
setComponentList([]);
setTotal(0);
}
} catch (error) {
console.error('获取组件市场数据失败:', error);
setComponentList([]);
setTotal(0);
} finally {
setLoading(false);
}
};
// 监听分类、搜索条件变化
useEffect(() => {
setCurrent(1);
fetchComponentData(1);
}, [searchKeyword, selectedTab]);
// 处理分页变化
const handlePageChange = (page: number) => {
setCurrent(page);
fetchComponentData(page);
};
// 跳转到组件详情
const handleDetails = (component: ComponentItem) => {
selectedComp(component);
};
return (
<div className={styles['comp-card']}>
<Spin loading={loading} style={{ width: '100%' }}>
{componentList.length > 0 ? (
<>
<Row style={{ marginBottom: 16 }}>
{componentList.map((item) => (
<Col
xs={12}
sm={12}
md={12}
lg={6}
xl={6}
xxl={6}
key={item.id}
style={{ marginBottom: 16 }}
>
<Card
style={{ cursor: 'pointer', border: '1px solid #d9d9d9' }}
onClick={() => handleDetails(item)}
hoverable
>
{/*左侧图片*/}
<div className={styles['img-box']}>
<Image width={'100%'} height={'100%'} src={item.logoUrl} alt="暂无图片"></Image>
</div>
{/*右侧数据*/}
<div className={styles['info-box']}>
<div className={styles['info-title']}>{item.name || '未命名组件'}</div>
<div className={styles['info-author']}>{item.identifier || '-'}</div>
<div className={styles['info-score']}>
<div></div>
<div className={styles['info-rate']}>
{/*<Rate readonly allowHalf value={item.star || 5} />*/}
<Typography.Text style={{ margin: '0 5px', fontSize: 14 }}>
{item.star || 5}
</Typography.Text>
<IconStarFill
style={{ color: '#ffcd00' }} />
</div>
</div>
</div>
</Card>
<div className={styles['comp-card-footer']}>
<div className={styles['comp-type']}>{item.componentClassify || '-'}</div>
<div className={styles['comp-language']}>{item.codeLanguage || '-'}</div>
</div>
</Col>
))}
</Row>
{/* 分页组件 */}
{total > pageSize && (
<div style={{ display: 'flex', justifyContent: 'center', marginTop: 24 }}>
<Pagination
current={current}
pageSize={pageSize}
total={total}
onChange={handlePageChange}
showTotal
showJumper
sizeCanChange={false}
/>
</div>
)}
</>
) : (
<Empty description="暂无组件数据" />
)}
</Spin>
</div>
);
};
export default CompCard;