import { useCallback } from 'react'; import { message } from 'antd'; import { useRecoilState } from 'recoil'; import { ComponentInfo, ComponentDetailInfo, AssetInfo, ComponentConfig, CreateComponentQuery, UpdateComponentQuery, CopyComponentQuery, RemoveComponentGroupQuery, CreateStateQuery, UpdateStateQuery, RemoveStateQuery, CreateViewpointQuery, UpdateViewpointQuery, RemoveViewpointQuery, GetAnimationListQuery, CreateAnimationListQuery, UpdateAnimationQuery, loopHandle, StateInfo, ViewpointInfo, IVector3, CopyComponentsQuery, } from '@easytwin/core'; import { ComponentApi, StateApi, ViewpointApi } from '@/server'; import { useParams } from 'react-router-dom'; import { _sceneId, _componenterTreeList, _componenterFilteredTreeList, _componenterSearchQuery, _componenterRemovedList, _currentComponentDetail, _componentSelectList, _componentStateList, _componentStateSelectKey, _componenterViewpointList, _componenterViewpointSelectKey, _componenterAnimationList, _componenterAnimationSelectKey, } from '..'; import { BatchModelPrams } from '../../components'; export const useComponenter = () => { const [sceneId] = useRecoilState(_sceneId); /** * get tree */ const [componentList, setComponenterTreeList] = useRecoilState(_componenterTreeList); const getComponenterTreeList = useCallback(async () => { if (!sceneId) return; const list = await ComponentApi.getTree({ sceneId }); setComponenterTreeList(list); return list; }, [sceneId, setComponenterTreeList]); /** * filter tree */ const [searchQuery] = useRecoilState(_componenterSearchQuery); const [, setComponenterFilteredTreeList] = useRecoilState(_componenterFilteredTreeList); const getComponenterFilteredTreeList = useCallback(async () => { if (!sceneId) return; if (!searchQuery.name && !searchQuery.tag) { setComponenterFilteredTreeList(undefined); } else { const list = await ComponentApi.filterTree({ sceneId, name: searchQuery.name, tagId: searchQuery.tag?.id, }); setComponenterFilteredTreeList(list); } }, [sceneId, searchQuery, setComponenterFilteredTreeList]); /** * CRUD */ const [selectComponents, setSelectComponents] = useRecoilState(_componentSelectList); const [componenter, setComponenterDetail] = useRecoilState(_currentComponentDetail); const [, setStateList] = useRecoilState(_componentStateList); const [, setStateSelectKey] = useRecoilState(_componentStateSelectKey); const [, setViewpointList] = useRecoilState(_componenterViewpointList); const [, setViewpointSelectKey] = useRecoilState(_componenterViewpointSelectKey); const [, setAnimationList] = useRecoilState(_componenterAnimationList); const [, setAnimationSelectKey] = useRecoilState(_componenterAnimationSelectKey); const [, setRemovedList] = useRecoilState(_componenterRemovedList); const getComponenterDetail = useCallback( async (id?: string) => { if (!id || !sceneId) return setComponenterDetail(undefined); const data: ComponentDetailInfo = await ComponentApi.getDetail({ id, sceneId }); if (data) { setComponenterDetail(data); setStateList(data.stateConfig); setStateSelectKey(data.stateConfig[0]?.id); setViewpointList(data.viewpointConfig); setViewpointSelectKey(undefined); setAnimationList(data.animationConfig); setAnimationSelectKey(data.animationConfig[0]?.id); } return data; }, [ setAnimationList, setAnimationSelectKey, setComponenterDetail, setStateList, setStateSelectKey, setViewpointList, setViewpointSelectKey, sceneId, ], ); const createComponent = useCallback( async (query: CreateComponentQuery) => { const detail = await ComponentApi.createLight(query); if (detail) setSelectComponents([detail]); message.success('创建成功!'); return detail; }, [setSelectComponents], ); const createComponenterByLocalModel = useCallback( async (file: File): Promise => { if (!sceneId) return message.error('场景id不存在'); return ComponentApi.createByModel({ sceneId, modelFile: file, }); }, [sceneId], ); const createComponenterByLocalModelList = useCallback( async (fileList: File[]) => { const detailList: ComponentInfo[] = []; await loopHandle(fileList, async (file) => { const detail = await createComponenterByLocalModel(file); if (detail) detailList.push(detail); }); setSelectComponents(detailList); return detailList; }, [createComponenterByLocalModel, setSelectComponents], ); const createComponenterByAsset = useCallback( async (asset: AssetInfo) => { // if (!sceneId) return message.error('场景id不存在'); // const detail = await ComponentApi.createTemplateGroup({ // sceneId, // pid: componenter?.pid ?? componenter?.id, // asset, // }); // if (detail) setSelectComponents([detail]); // message.success('创建成功!'); // return detail; }, [sceneId, componenter, setSelectComponents], ); const createComponenterAssetChild = useCallback( async (pid: string, config: ComponentConfig) => { // if (!projectId) return message.error('项目id不存在'); // const detail = await ComponentApi.createTemplateChild({ // projectId, // pid, // config, // }); // message.success('创建成功!'); // return detail; }, [sceneId], ); const createComponenterGroup = useCallback(async () => { if (!sceneId) return message.error('项目id不存在'); const detail = await ComponentApi.createGroup({ objIds: selectComponents.map((item) => item.id), sceneId, }); if (detail) setSelectComponents([detail]); await getComponenterTreeList(); message.success('创建成功!'); }, [sceneId, selectComponents, setSelectComponents, getComponenterTreeList]); const updateComponenter = useCallback( async (query: Partial, showOkMsg: boolean = true) => { if (!sceneId) { message.error('场景id不存在'); return ''; } const { id } = query; const _id = id || (componenter && componenter.id); if (!_id) { message.error('未选中元件'); return ''; } await ComponentApi.updateComponenter({ ...query, id: _id, sceneId, }); if (showOkMsg) { message.success('修改成功!'); } await getComponenterTreeList(); return getComponenterDetail(_id); }, [getComponenterTreeList, sceneId, componenter], ); const updateComponenterInLayer = useCallback( async (query: { id: string; visible?: boolean; locked?: boolean }) => { const { id, visible, locked } = query; await ComponentApi.updateComponenterInLayer({ id, visible, locked, }); await getComponenterTreeList(); return getComponenterDetail(id); }, [getComponenterTreeList], ); const copyComponenter = useCallback( async (query: CopyComponentsQuery) => { await ComponentApi.copy(query); message.success('复制成功!'); await getComponenterTreeList(); }, [getComponenterTreeList], ); const removeComponent = useCallback( async ({ ids }: { ids: string[] }) => { if (!sceneId) { return; } await ComponentApi.remove({ ids, sceneId, }); setRemovedList(componentList?.filter((d) => ids.includes(d.id)) || []); setComponenterDetail(undefined); message.success('删除成功!'); getComponenterTreeList(); }, [getComponenterTreeList, setComponenterDetail, setRemovedList, componentList, sceneId], ); const removeComponentGroup = useCallback( async (query: RemoveComponentGroupQuery) => { await ComponentApi.removeGroup(query); getComponenterTreeList(); }, [getComponenterTreeList], ); const createComponentByModelUrl = useCallback( async (modelUrl: string): Promise => { if (!sceneId) return message.error('场景id不存在'); const component = await ComponentApi.createByModelUrl({ sceneId, modelUrl, }); component && setSelectComponents([component]); return component; }, [sceneId], ); const createComponentByBatchModelGroup = useCallback( async (batchModelPrams: BatchModelPrams): Promise => { if (!sceneId) return message.error('场景id不存在'); return ComponentApi.createByBatchModelGroup({ sceneId, config: batchModelPrams, }); }, [sceneId], ); const createComponentByBatchModel = useCallback( async ( batchModelPrams: BatchModelPrams & { positions: IVector3[]; parentObjId: string }, ): Promise => { if (!sceneId) return message.error('场景id不存在'); const { parentObjId, ...config } = batchModelPrams; return ComponentApi.createByBatchModel({ sceneId, parentObjId, config, }); }, [sceneId], ); return { getComponenterTreeList, getComponenterFilteredTreeList, getComponenterDetail, createComponent, createComponenterByLocalModel, createComponenterByLocalModelList, createComponenterByAsset, createComponenterAssetChild, createComponenterGroup, updateComponenter, updateComponenterInLayer, copyComponenter, removeComponent, removeComponentGroup, // createComponentByModelUrl, createComponentByBatchModelGroup, createComponentByBatchModel, }; }; export const useComponenterState = () => { const [stateList, setStateList] = useRecoilState(_componentStateList); const [, setSelectKey] = useRecoilState(_componentStateSelectKey); const createState = useCallback( async (query: CreateStateQuery) => { const data = await StateApi.create(query).catch(message.error); if (data) { message.success('创建成功!'); setStateList([...stateList, data]); setSelectKey(data.id); } else { message.error('创建失败!'); } return data; }, [setSelectKey, stateList, setStateList], ); const updateState = useCallback( async (query: UpdateStateQuery, showOkMsg: boolean = false) => { const data = await StateApi.update(query).catch(message.error); if (data) { const { id, name, config, rank } = query; showOkMsg && message.success('更新成功!'); setStateList( stateList.map((item) => { if (item.id === id) { const result = { name, rank, config, }; if (!name) delete result.name; if (!rank) delete result.rank; if (!config) delete result.config; return { ...item, ...result, } as StateInfo; } return item; }), ); } else { message.error('更新失败!'); } return data; }, [setStateList, stateList], ); const removeState = useCallback( async (query: RemoveStateQuery) => { const data = await StateApi.remove(query).catch(message.error); if (data) { message.success('删除成功!'); setStateList(stateList.filter((state) => state.id !== query.id)); setSelectKey(stateList[0].id); } else { message.error('删除失败!'); } return data; }, [setSelectKey, setStateList, stateList], ); return { createState, updateState, removeState, }; }; export const useComponenterViewpoint = () => { const [viewpointList, setViewpointList] = useRecoilState(_componenterViewpointList); const [, setSelectKey] = useRecoilState(_componenterViewpointSelectKey); const createViewpoint = useCallback( async (query: CreateViewpointQuery) => { const data = await ViewpointApi.create(query).catch(message.error); if (data) { message.success('创建成功!'); setViewpointList([...viewpointList, data]); setSelectKey(data.id); } else { message.error('创建失败!'); } return data; }, [setSelectKey, viewpointList, setViewpointList], ); const updateViewpoint = useCallback( async (query: UpdateViewpointQuery, showOkMsg: boolean = false) => { const data = await ViewpointApi.update(query).catch(message.error); if (data) { const { id, name, config, rank } = query; showOkMsg && message.success('更新成功!'); setViewpointList( viewpointList.map((item) => { if (item.id === id) { const result = { name, rank, config, }; if (!name) delete result.name; if (!rank) delete result.rank; if (!config) delete result.config; return { ...item, ...result, } as ViewpointInfo; } return item; }), ); } else { message.error('更新失败!'); } return data; }, [viewpointList, setViewpointList], ); const removeViewpoint = useCallback( async (query: RemoveViewpointQuery) => { const data = await ViewpointApi.remove(query).catch(message.error); if (data) { message.success('删除成功!'); setViewpointList(viewpointList.filter((state) => state.id !== query.id)); setSelectKey(viewpointList[0].id); } else { message.error('删除失败!'); } return data; }, [viewpointList, setViewpointList, setSelectKey], ); return { createViewpoint, updateViewpoint, removeViewpoint, }; };