import React, { useEffect, useState, useCallback } from 'react'; import { Card, Grid, Input, Tag, Typography, Divider, Collapse, Button, Message } from '@arco-design/web-react'; import { IconSearch, IconSync } from '@arco-design/web-react/icon'; import styles from './style/market.module.less'; import { useSelector, useDispatch } from 'react-redux'; import { addProjectComp, addProjectBaseComp } from '@/api/scene'; import dayjs from 'dayjs'; const { Row, Col } = Grid; const { Title, Text } = Typography; type componentItemType = { label: string; children?: any[]; }; interface MarketProps { updateProjectComp: () => void; } const Market: React.FC = ({ updateProjectComp }) => { const [compList, setCompList] = useState([]); const [firstLevelCategory, setFirstLevelCategory] = useState('全部'); // 第一层分类:全部,基础,复合 const [secondLevelCategory, setSecondLevelCategory] = useState('全部'); // 第二层分类:全部,我的,公开,协同 const { projectComponentData, info } = useSelector((state: any) => state.ideContainer); const dispatch = useDispatch(); // 第一层分类选项 const firstLevelCategories = [ { label: '全部', value: '全部' }, { label: '基础', value: '基础' }, { label: '复合', value: '复合' } ]; // 第二层分类选项 const secondLevelCategories = [ { label: '全部', value: '全部' }, { label: '我的', value: '我的' }, { label: '公开', value: '公开' }, { label: '协同', value: '协同' } ]; // 计算各分类的数量 const getCategoryCounts = useCallback(() => { if (!compList) return { allCount: 0, basicCount: 0, compositeCount: 0, myCount: 0, publicCount: 0, teamCount: 0, myFlowCount: 0, pubFlowCount: 0 }; // 基础组件数量 (myLibs, pubLibs, teamLibs) // 需要统计children中的组件数量 const myCount = compList.myLibs ? compList.myLibs.reduce((acc, cur) => acc + (cur.children ? cur.children.length : 0), 0) : 0; const publicCount = compList.pubLibs ? compList.pubLibs.reduce((acc, cur) => acc + (cur.children ? cur.children.length : 0), 0) : 0; const teamCount = compList.teamLibs ? compList.teamLibs.reduce((acc, cur) => acc + (cur.children ? cur.children.length : 0), 0) : 0; const basicCount = myCount + publicCount + teamCount; // 复合组件数量 (myFlow, pubFlow) - 直接统计数组长度 const myFlowCount = compList.myFlow ? compList.myFlow.length : 0; const pubFlowCount = compList.pubFlow ? compList.pubFlow.length : 0; const compositeCount = myFlowCount + pubFlowCount; return { allCount: basicCount + compositeCount, basicCount, compositeCount, myCount, publicCount, teamCount, myFlowCount, pubFlowCount }; }, [compList]); // 渲染Tag选择器 const renderCategoryTage = useCallback(() => { /* * 分类规则:先分类(全部,基础,复合) 再分类(全部,我的,公开,协同:复合类型中没有协同组件) * 目前数据类型中存在的字段: 基础类型 [myLibs,pubLibs,teamLibs], 复合类型[pubFlow,myFlow] * 需要渲染出两层Tag标签的选择,第一次的选择影响第二层的部分渲染 * */ const counts = getCategoryCounts(); // 根据第一层分类动态调整第二层分类选项 const getFilteredSecondLevelCategories = () => { // 如果是复合类型,则不显示协同组件选项 if (firstLevelCategory === '复合') { return secondLevelCategories.filter(item => item.value !== '协同'); } return secondLevelCategories; }; // 获取第二层分类的数量 const getSecondLevelCount = (category: string) => { if (firstLevelCategory === '全部') { switch (category) { case '全部': return counts.allCount; case '我的': return counts.myCount + counts.myFlowCount; case '公开': return counts.publicCount + counts.pubFlowCount; case '协同': return counts.teamCount; default: return 0; } } else if (firstLevelCategory === '基础') { switch (category) { case '全部': return counts.basicCount; case '我的': return counts.myCount; case '公开': return counts.publicCount; case '协同': return counts.teamCount; default: return 0; } } else if (firstLevelCategory === '复合') { switch (category) { case '全部': return counts.compositeCount; case '我的': return counts.myFlowCount; case '公开': return counts.pubFlowCount; default: return 0; } } return 0; }; return (
{/* 第一层分类标签 */}
{firstLevelCategories.map((category) => { let count = 0; switch (category.value) { case '全部': count = counts.allCount; break; case '基础': count = counts.basicCount; break; case '复合': count = counts.compositeCount; break; } return ( { setFirstLevelCategory(category.value); // 当切换第一层分类时,默认选中"全部"作为第二层分类 setSecondLevelCategory('全部'); }} > {category.label} ({count}) ); })}
{/* 第二层分类标签 */}
{getFilteredSecondLevelCategories().map((category) => ( setSecondLevelCategory(category.value)} > {category.label} ({getSecondLevelCount(category.value)}) ))}
); }, [firstLevelCategory, secondLevelCategory, getCategoryCounts]); // 渲染组件分类 const renderComponentCategory = useCallback(() => { // 根据第一层和第二层分类筛选组件 let filteredComponents = []; // 构建筛选条件 const conditions = { includeMyLibs: (firstLevelCategory === '全部' || firstLevelCategory === '基础') && (secondLevelCategory === '全部' || secondLevelCategory === '我的'), includePubLibs: (firstLevelCategory === '全部' || firstLevelCategory === '基础') && (secondLevelCategory === '全部' || secondLevelCategory === '公开'), includeTeamLibs: (firstLevelCategory === '全部' || firstLevelCategory === '基础') && (secondLevelCategory === '全部' || secondLevelCategory === '协同'), includeMyFlow: (firstLevelCategory === '全部' || firstLevelCategory === '复合') && (secondLevelCategory === '全部' || secondLevelCategory === '我的'), includePubFlow: (firstLevelCategory === '全部' || firstLevelCategory === '复合') && (secondLevelCategory === '全部' || secondLevelCategory === '公开') }; // 收集符合条件的基础组件 if (conditions.includeMyLibs && compList.myLibs) { filteredComponents = [...filteredComponents, ...compList.myLibs]; } if (conditions.includePubLibs && compList.pubLibs) { filteredComponents = [...filteredComponents, ...compList.pubLibs]; } if (conditions.includeTeamLibs && compList.teamLibs) { filteredComponents = [...filteredComponents, ...compList.teamLibs]; } // 收集符合条件的复合组件 const flowComponents = []; if (conditions.includeMyFlow && compList.myFlow) { flowComponents.push(...compList.myFlow.map(item => ({ ...item, isFlow: true }))); } if (conditions.includePubFlow && compList.pubFlow) { flowComponents.push(...compList.pubFlow.map(item => ({ ...item, isFlow: true }))); } // 合并相同标签的组件 const mergedComponents = {}; // 处理基础组件(按label分组) filteredComponents.forEach(category => { if (category && category.children && category.children.length > 0) { const label = category.label; if (!mergedComponents[label]) { mergedComponents[label] = { label: label, children: [] }; } mergedComponents[label].children.push(...category.children); } }); // 处理复合组件 if (flowComponents.length > 0) { const label = '复合组件'; if (!mergedComponents[label]) { mergedComponents[label] = { label: label, children: [] }; } mergedComponents[label].children.push(...flowComponents); } // 转换为数组格式 const resultComponents = Object.values(mergedComponents); // 如果没有组件,显示提示信息 if (resultComponents.length === 0) { return (
暂无组件数据
); } // 将组件添加到工程中 const addToProject = async (component) => { const params = { sceneId: info.id, compIds: [] }; params['compIds'].push(component.id || component.comp.id); params['type'] = component.fontCompType; if (component.fontCompType === 'complex') { const res: any = await addProjectComp(params); if (res.code === 200) Message.success('添加成功'); else Message.error('添加失败'); } else { const res: any = await addProjectBaseComp(params); if (res.code === 200) Message.success('添加成功'); else Message.error('添加失败'); } // 通知父组件更新 updateProjectComp(); }; // 渲染组件 return ( {resultComponents.map((category: componentItemType, index) => { // 确保category有children属性 if (!category || !category.children || category.children.length === 0) { return null; } return ( {category.label} } > {category.children.map((component, compIndex) => (
{component.label || component.flowName}
{/*两种状态 未添加的是primary 已添加的是secondary*/} { component.isAdd ? ( ) : ( ) }
))}
); }).filter(item => item !== null)}
); }, [compList, firstLevelCategory, secondLevelCategory]); // 给账号下的组件列表(本地存储中的组件列表)增加一个是否添加至工程的初始状态 const addInitState = (componentData) => { // 当前工程下已添加的组件ID列表 const projectComponent = projectComponentData[info.id]; const compListByProject = projectComponent.compIds.concat(projectComponent.flowIds); const objectKeys = Object.keys(componentData); /* * 账号下的组件列表分两种结构: * 1. myLibs,pubLibs,teamLibs 这三个是带有children数组的结构 * 2. pubFlow,myFlow 这两个是直接一个数组 * */ objectKeys.forEach(key => { if (key === 'pubFlow' || key === 'myFlow') { componentData[key].forEach(item => { item.isAdd = compListByProject.includes(item.id); }); } else if (key === 'myLibs' || key === 'pubLibs' || key === 'teamLibs') { componentData[key].length && componentData[key].forEach(item => { item.children.forEach(v => { v.isAdd = compListByProject.includes(v.comp.id); }); }); } }); setCompList(componentData); }; // 从缓存中获取组件列表的信息 const getCompList = () => { const userInfo = JSON.parse(sessionStorage.getItem('userInfo') || '{}'); const componentData = JSON.parse(sessionStorage.getItem(`compLibs${userInfo.userId}`)); addInitState(componentData); }; useEffect(() => { getCompList(); }, []); // 监听 Redux 中 projectComponentData 的变化,更新组件列表状态 useEffect(() => { getCompList(); }, [projectComponentData]); return (
{/* 头部搜索区域 */}
组件仓库
} style={{ marginRight: 16 }} />
{/* tag样式选择器 */}
{renderCategoryTage()}
{renderComponentCategory()}
); }; export default Market;