diff --git a/frontend/src/components/layout/index.tsx b/frontend/src/components/layout/index.tsx
index e0533852d0..e3486d5d5e 100644
--- a/frontend/src/components/layout/index.tsx
+++ b/frontend/src/components/layout/index.tsx
@@ -4,7 +4,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, Suspense } from 'react';
import type { MenuProps } from 'antd';
import { Layout, Menu } from 'antd';
import { MenuFoldOutlined } from '@ant-design/icons';
@@ -155,19 +155,21 @@ const AppLayout: React.FC = () => {
-
- {flattenRouteList.map((route) => (
-
- ))}
-
-
-
-
+ loading}>
+
+ {flattenRouteList.map((route) => (
+
+ ))}
+
+
+
+
+
diff --git a/frontend/src/locale/i18n.ts b/frontend/src/locale/i18n.ts
index c8bb2f0047..59dd83f004 100644
--- a/frontend/src/locale/i18n.ts
+++ b/frontend/src/locale/i18n.ts
@@ -7,28 +7,17 @@ import i18n from 'i18next';
import { initReactI18next } from "react-i18next";
import en from './en_US.json';
import zh from './zh_CN.json';
-import coreEn from '@fit-elsa/elsa-core/locales/en.json';
-import coreZh from '@fit-elsa/elsa-core/locales/zh.json';
-import reactEn from '@fit-elsa/elsa-react/locales/en.json';
-import reactZh from '@fit-elsa/elsa-react/locales/zh.json';
-
-const mergeTranslations = (...translationObjects) => {
- // 从右向左合并(右侧优先级更高)
- return translationObjects
- .filter(obj => obj) // 过滤掉假值(undefined/null
- .reduce((merged, current) => ({ ...merged, ...current }), {});
-};
const resources = {
en: {
- translation: mergeTranslations(coreEn, reactEn, en) // 优先级顺序: en > reactEn > coreEn
+ translation: en
},
zh: {
- translation: mergeTranslations(coreZh, reactZh, zh) // 优先级顺序: zh > reactZh > coreZh
+ translation: zh
}
};
-const getCookie = (cname) => {
+const getCookie = (cname: string) => {
const name = `${cname}=`;
const ca = document.cookie.split(';');
for (let i = 0; i < ca.length; i++) {
@@ -49,6 +38,4 @@ i18n.use(initReactI18next).init({
returnNull: false
});
-
-
-export default i18n;
+export default i18n;
\ No newline at end of file
diff --git a/frontend/src/pages/aippIndex/index.tsx b/frontend/src/pages/aippIndex/index.tsx
index 5c1aa0bb53..1e183d8fe7 100644
--- a/frontend/src/pages/aippIndex/index.tsx
+++ b/frontend/src/pages/aippIndex/index.tsx
@@ -4,12 +4,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import React, { useCallback, useEffect, useRef, useState } from 'react';
+import React, { useCallback, useEffect, useRef, useState, lazy, Suspense } from 'react';
import { Spin } from 'antd';
import { useParams } from 'react-router-dom';
import AddFlow from '../addFlow';
import ConfigForm from '../configForm';
-import CommonChat from '../chatPreview/chatComminPage';
+const CommonChat = lazy(() => import('../chatPreview/chatComminPage'));
import ChoreographyHead from '../components/header';
import { getAppInfo, updateFormInfo } from '@/shared/http/aipp';
import { debounce, getCurrentTime, getUiD, setSpaClassName, getAppConfig } from '@/shared/utils/common';
@@ -215,12 +215,14 @@ const AippIndex = () => {
onChangeShowConfig={handleChangeShowConfig}
/>
)}
-
+ loading}>
+
+
diff --git a/frontend/src/pages/chatPreview/components/chat-details.tsx b/frontend/src/pages/chatPreview/components/chat-details.tsx
index 3c1a8ddbfb..ab298ea7e4 100644
--- a/frontend/src/pages/chatPreview/components/chat-details.tsx
+++ b/frontend/src/pages/chatPreview/components/chat-details.tsx
@@ -11,7 +11,6 @@ import { CreateAppIcon } from '@/assets/icon';
import { useAppDispatch, useAppSelector } from '@/store/hook';
import { findConfigValue } from '@/shared/utils/common';
import { convertImgPath } from '@/common/util';
-import EditModal from '@/pages/components/edit-modal';
import knowledgeBase from '@/assets/images/knowledge/knowledge-base.png';
import robot2 from '@/assets/images/ai/demo.png';
import '../styles/chat-details.scss';
@@ -103,7 +102,6 @@ const ChatDetail = ({ showMask = false }) => {
)) : }
-
)}>;
};
diff --git a/frontend/src/router/route.ts b/frontend/src/router/route.ts
index 11e7481825..9a9dcfd988 100644
--- a/frontend/src/router/route.ts
+++ b/frontend/src/router/route.ts
@@ -5,22 +5,23 @@
*--------------------------------------------------------------------------------------------*/
import type { MenuProps } from 'antd';
-import { ReactElement } from 'react';
+import { ReactElement, lazy } from 'react';
import { Icons } from '../components/icons/index';
-import IntelligentForm from '../pages/intelligent-form';
-import Plugin from '../pages/plugin';
-import ChatHome from '../pages/chatEngineHome/index';
-import ChatRunning from '../pages/chatRunning/index';
-import AppDetail from '../pages/appDetail';
-import AippIndex from '../pages/aippIndex';
-import AddFlow from '../pages/addFlow';
-import FlowDetail from '../pages/detailFlow';
-import Apps from '../pages/apps';
-import AppDev from '../pages/appDev/index';
-import PlugeDetail from '../pages/plugin/detail/plugin-list';
-import PlugeFlowDetail from '../pages/plugin/detail/plugin-flow-detail';
-import ViewReport from '../pages/appDetail/evaluate/task/viewReport';
-import HttpTool from '../pages/httpTool';
+const IntelligentForm = lazy(()=> import('../pages/intelligent-form'));
+const Plugin = lazy(()=> import('../pages/plugin'));
+const ChatHome = lazy(()=> import('../pages/chatEngineHome/index'));
+const ChatRunning = lazy(()=> import('../pages/chatRunning/index'));
+const AppDetail = lazy(()=> import('../pages/appDetail'));
+const AippIndex = lazy(() => import('../pages/aippIndex'));
+const AddFlow = lazy(()=> import('../pages/addFlow'));
+const FlowDetail = lazy(()=> import('../pages/detailFlow'));
+const Apps = lazy(()=> import('../pages/apps'));
+const AppDev = lazy(()=> import('../pages/appDev/index'));
+const PlugeDetail = lazy(()=> import('../pages/plugin/detail/plugin-list'));
+const PlugeFlowDetail = lazy(()=> import('../pages/plugin/detail/plugin-flow-detail'));
+const ViewReport = lazy(()=> import('../pages/appDetail/evaluate/task/viewReport'));
+const HttpTool = lazy(()=> import('../pages/httpTool'));
+
import i18n from '../locale/i18n';
export type MenuItem = Required['items'][number] & {
diff --git a/frontend/src/shared/utils/common.ts b/frontend/src/shared/utils/common.ts
index 6772759193..812a751ee6 100644
--- a/frontend/src/shared/utils/common.ts
+++ b/frontend/src/shared/utils/common.ts
@@ -2,7 +2,6 @@ import { useLocation } from 'react-router-dom';
import { useCallback, useMemo, useState } from 'react';
import { pick, find, filter } from 'lodash';
import { Message } from '@/shared/utils/message';
-import { createGraphOperator } from '@fit-elsa/elsa-react';
import { storage } from '../storage';
import i18n from '@/locale/i18n';
import { getAppCategories } from "@/shared/http/aipp";
@@ -450,3 +449,126 @@ export const getAppConfig = (appInfo) => {
export const generateUniqueName = () => {
return 'guest-' + nanoid(16);
}
+
+// ==================== GraphOperator ====================
+
+// 数据类型常量
+const DATA_TYPES = {
+ STRING: 'String',
+ INTEGER: 'Integer',
+ BOOLEAN: 'Boolean',
+ NUMBER: 'Number',
+ OBJECT: 'Object',
+ ARRAY: 'Array',
+};
+
+// 来源类型常量
+const FROM_TYPE = {
+ EXPAND: 'Expand',
+ INPUT: 'Input',
+ REFERENCE: 'Reference',
+};
+
+/**
+ * 将配置数据转换为结构体
+ * @param config 配置数据
+ * @return {{}|*} 结构体
+ */
+const configToStruct = (config: any) => {
+ if (config.type === DATA_TYPES.ARRAY) {
+ return config.value.map(v => configToStruct(v));
+ } else if (config.type === DATA_TYPES.OBJECT) {
+ const obj = {};
+ config.value.forEach((item: any) => {
+ obj[item.name] = configToStruct(item);
+ });
+ return obj;
+ } else {
+ return Object.prototype.hasOwnProperty.call(config, 'value') ? config.value : config;
+ }
+};
+
+/**
+ * 创建画布操纵器
+ * @param graphString 画布字符串
+ * @return {{}} 画布操纵器对象
+ */
+export const createGraphOperator = (graphString: string) => {
+ const graph = JSON.parse(graphString);
+ const shapes = graph.pages[0].shapes;
+
+ const getInputParams = (shape: any) => {
+ if (shape.type === 'startNodeStart') {
+ return shape.flowMeta.inputParams;
+ } else if (shape.type === 'endNodeEnd') {
+ return shape.flowMeta.callback.converter.entity.inputParams;
+ } else {
+ return shape.flowMeta.jober.converter.entity.inputParams;
+ }
+ };
+
+ const getConfigByKeys = (keys: string[]) => {
+ if (!Array.isArray(keys)) {
+ throw new Error('Expected keys to be an array');
+ }
+
+ if (keys.length === 0) {
+ return null;
+ }
+
+ const tmpKeys = [...keys];
+ const shapeId = tmpKeys.shift();
+ const shape = getShapeById(shapeId);
+ const inputParams = getInputParams(shape);
+ if (!inputParams) {
+ throw new Error('Expected inputParams exists');
+ }
+ let config = {type: DATA_TYPES.OBJECT, value: inputParams};
+ while (tmpKeys.length > 0 && config && config.value) {
+ const key = tmpKeys.shift();
+ config = config.value.find(v => v.name === key);
+ }
+ return config;
+ };
+
+ const getShapeById = (shapeId: string) => {
+ return shapes.find((shape) => shape.id === shapeId);
+ };
+
+ return {
+ /**
+ * 获取配置信息
+ * @param keys 键值数组
+ * @return {{}|*|null} 配置信息
+ */
+ getConfig: (keys: string[]) => {
+ const config = getConfigByKeys(keys);
+ return config ? configToStruct(config) : null;
+ },
+
+ /**
+ * 获取画布中开始节点的入参信息
+ * @return {array} 开始节点入参信息
+ */
+ getStartNodeInputParams: (): any[] => {
+ return shapes.filter(shape => shape.type === 'startNodeStart').map(startNode => startNode.flowMeta.inputParams);
+ },
+
+ /**
+ * 根据节点类型获取对应节点id列表
+ * @param type 节点类型
+ * @returns {array} 对应节点id列表
+ */
+ getShapeIdsByType: (type: string): string[] => {
+ return shapes.filter((shape) => shape.type === type).map((shape) => shape.id);
+ },
+
+ /**
+ * 获取画布数据
+ * @return {string} 画布数据
+ */
+ getGraph: (): string => {
+ return JSON.stringify(graph);
+ }
+ };
+};