diff --git a/src/api/scene.ts b/src/api/scene.ts index 808bb65..2d01b15 100644 --- a/src/api/scene.ts +++ b/src/api/scene.ts @@ -61,4 +61,14 @@ export function getSceneAndId() { // 场景管理-获取工程下的所有组件 export function getProjectComp(projectId: string) { return axios.get(`${urlPrefix}/scenes/projectComp/${projectId}`); +} + +// 增加工程复合组件 +export function addProjectComp(data: any) { + return axios.post(`${urlPrefix}/scenes/addProjectSubComp`, data); +} + +// 增加工程基础组件 +export function addProjectBaseComp(data: any) { + return axios.post(`${urlPrefix}/scenes/addProjectComp`, data); } \ No newline at end of file diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 3cfb34f..3ccfc46 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -99,11 +99,28 @@ export default function MyApp({ const res: any = await promise; if (res?.code === 200) { if (key === 'pubFlow' || key === 'myFlow') { + res?.data.list.forEach(item => { + item['fontCompType'] = 'complex'; + }); // 更新本地存储数据 obj[key] = res?.data.list || null; } + // 给协同组件添加一个后续处理数据时使用的类型 + else if (key === 'teamLibs') { + res.data.forEach(item => { + item.children.forEach(v => { + v['fontCompType'] = 'team'; + }); + }); + obj[key] = res?.data || null; + } else { // 更新本地存储数据 + res.data.forEach(item => { + item.children.forEach(v => { + v['fontCompType'] = 'normal'; + }); + }); obj[key] = res?.data || null; } } diff --git a/src/pages/ideContainer/index.tsx b/src/pages/ideContainer/index.tsx index 603e889..df8a70b 100644 --- a/src/pages/ideContainer/index.tsx +++ b/src/pages/ideContainer/index.tsx @@ -63,7 +63,9 @@ function IDEContainer() { const getProjectCompData = async () => { const res: any = await getProjectComp(urlParams.id); - if (res.code === 200) dispatch(updateProjectComponentData({ [urlParams.id]: res.data })); + if (res.code === 200) { + await dispatch(updateProjectComponentData({ [urlParams.id]: res.data })); + } }; useEffect(() => { @@ -270,7 +272,8 @@ function IDEContainer() { - {['appList', 'appFlow'].includes(selected.parentKey) && } + {['appList', 'appFlow'].includes(selected.parentKey) && + getProjectCompData()}>} ); diff --git a/src/pages/ideContainer/market.tsx b/src/pages/ideContainer/market.tsx index 41a0f20..bcd2770 100644 --- a/src/pages/ideContainer/market.tsx +++ b/src/pages/ideContainer/market.tsx @@ -1,14 +1,24 @@ import React, { useEffect, useState, useCallback } from 'react'; -import { Card, Grid, Input, Tag, Typography, Divider, Collapse, Button } from '@arco-design/web-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 = () => { +const Market: React.FC = ({ updateProjectComp }) => { const [compList, setCompList] = useState([]); const [firstLevelCategory, setFirstLevelCategory] = useState('全部'); // 第一层分类:全部,基础,复合 const [secondLevelCategory, setSecondLevelCategory] = useState('全部'); // 第二层分类:全部,我的,公开,协同 @@ -93,7 +103,7 @@ const Market: React.FC = () => { case '全部': return counts.allCount; case '我的': - return counts.myCount; + return counts.myCount + counts.myFlowCount; case '公开': return counts.publicCount + counts.pubFlowCount; case '协同': @@ -206,7 +216,7 @@ const Market: React.FC = () => { (secondLevelCategory === '全部' || secondLevelCategory === '公开') }; - // 添加基础组件 + // 收集符合条件的基础组件 if (conditions.includeMyLibs && compList.myLibs) { filteredComponents = [...filteredComponents, ...compList.myLibs]; } @@ -217,22 +227,49 @@ const Market: React.FC = () => { filteredComponents = [...filteredComponents, ...compList.teamLibs]; } - // 处理复合组件 - const flowComponents = { label: '复合组件', children: [] }; + // 收集符合条件的复合组件 + const flowComponents = []; if (conditions.includeMyFlow && compList.myFlow) { - flowComponents.children.push(...compList.myFlow); + flowComponents.push(...compList.myFlow.map(item => ({ ...item, isFlow: true }))); } if (conditions.includePubFlow && compList.pubFlow) { - flowComponents.children.push(...compList.pubFlow); + flowComponents.push(...compList.pubFlow.map(item => ({ ...item, isFlow: true }))); } - // 如果有复合组件,添加到筛选结果中 - if (flowComponents.children.length > 0) { - filteredComponents = [...filteredComponents, flowComponents]; + // 合并相同标签的组件 + 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 (filteredComponents.length === 0) { + if (resultComponents.length === 0) { return (
暂无组件数据 @@ -240,10 +277,32 @@ const Market: React.FC = () => { ); } + // 将组件添加到工程中 + 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 ( - {filteredComponents.map((category, index) => { + {resultComponents.map((category: componentItemType, index) => { // 确保category有children属性 if (!category || !category.children || category.children.length === 0) { return null; @@ -261,17 +320,26 @@ const Market: React.FC = () => { } > {category.children.map((component, compIndex) => ( - <> -
+
+
- {component.label} + {component.label || component.flowName}
{/*两种状态 未添加的是primary 已添加的是secondary*/} - + { + component.isAdd ? ( + + ) : ( + + ) + } +
- +
))} ); @@ -280,12 +348,51 @@ const Market: React.FC = () => { ); }, [compList, firstLevelCategory, secondLevelCategory]); - useEffect(() => { + // 给账号下的组件列表(本地存储中的组件列表)增加一个是否添加至工程的初始状态 + 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}`)); - setCompList(componentData); + addInitState(componentData); + }; + + useEffect(() => { + getCompList(); }, []); + // 监听 Redux 中 projectComponentData 的变化,更新组件列表状态 + useEffect(() => { + getCompList(); + }, [projectComponentData]); + return (
{/* 头部搜索区域 */} @@ -300,7 +407,11 @@ const Market: React.FC = () => { style={{ marginRight: 16 }} />
- +
diff --git a/src/pages/ideContainer/rightSideBar.tsx b/src/pages/ideContainer/rightSideBar.tsx index 588484a..9478952 100644 --- a/src/pages/ideContainer/rightSideBar.tsx +++ b/src/pages/ideContainer/rightSideBar.tsx @@ -7,7 +7,11 @@ import Market from './market'; const TabPane = Tabs.TabPane; -const RightSideBar: React.FC = () => { +interface RightSideBarProps { + updateProjectComp: () => void; +} + +const RightSideBar: React.FC = ({ updateProjectComp }) => { const [activeTab, setActiveTab] = useState('1'); const [isExpanded, setIsExpanded] = useState(false); const resizeBoxRef1 = useRef(null); // 引用第一个 ResizeBox 容器 @@ -25,7 +29,7 @@ const RightSideBar: React.FC = () => { // 当 isExpanded 或 activeTab 状态改变时,直接更新对应元素的样式 useEffect(() => { - const width = isExpanded ? 350 : 0; + const width = isExpanded ? 550 : 0; if (activeTab === '1' && resizeBoxRef1.current) { resizeBoxRef1.current.style.width = `${width}px`; @@ -69,7 +73,7 @@ const RightSideBar: React.FC = () => { className={styles['right-resize-box']} directions={['left']} style={{ - width: isExpanded ? 350 : 0, + width: isExpanded ? 550 : 0, maxWidth: '100%', minWidth: 0 }} @@ -92,13 +96,13 @@ const RightSideBar: React.FC = () => { className={styles['right-resize-box']} directions={['left']} style={{ - width: isExpanded ? 350 : 0, + width: isExpanded ? 550 : 0, maxWidth: '100%', minWidth: 0 }} onMoving={handleResize} > - + } diff --git a/src/pages/login/form.tsx b/src/pages/login/form.tsx index 26d4d42..9f0a9d8 100644 --- a/src/pages/login/form.tsx +++ b/src/pages/login/form.tsx @@ -84,7 +84,6 @@ export default function LoginForm() { className={styles['login-form']} layout="vertical" ref={formRef} - initialValues={{ username: 'admin', password: 'admin' }} > { selectedKeys={[]} // 移除选中样式 style={{ background: 'transparent' }} // 移除背景色 onSelect={(value, info) => { - if (info.node.props.dataRef.children) return; + if (info.node.props.dataRef.hasOwnProperty('children')) return; onSelect(info.node?.props?.dataRef || null); }} > - {renderTreeNode(compList)} + {renderTreeNode({ projectCompDto: compList.projectCompDto, projectFlowDto: compList.projectFlowDto })}