diff --git a/framework/elsa/fit-elsa-react/src/i18n.js b/framework/elsa/fit-elsa-react/src/i18n.js
index 0791388a0..38bfe1fa1 100644
--- a/framework/elsa/fit-elsa-react/src/i18n.js
+++ b/framework/elsa/fit-elsa-react/src/i18n.js
@@ -8,19 +8,25 @@ 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';
+
+const mergeTranslations = (local, core) => {
+ return { ...core, ...local }; // core 的翻译作为基础,本地翻译优先级更高
+};
const resources = {
en: {
- translation: en,
+ translation: mergeTranslations(en, coreEn),
},
zh: {
- translation: zh,
+ translation: mergeTranslations(zh, coreZh),
},
};
i18n.use(initReactI18next).init({
resources,
- fallbackLng: 'zh-cn',
+ fallbackLng: 'zh',
interpolation: {
escapeValue: false,
},
diff --git a/framework/elsa/fit-elsa/core/defaultGraph.js b/framework/elsa/fit-elsa/core/defaultGraph.js
index 6cf5b0ba7..e1d00e0a2 100644
--- a/framework/elsa/fit-elsa/core/defaultGraph.js
+++ b/framework/elsa/fit-elsa/core/defaultGraph.js
@@ -9,12 +9,14 @@ import ElsaEditor from '../editor/default/elsa-editor.js';
import {EVENT_TYPE} from '../common/const.js';
import {elsaCKEditor} from '../editor/default/elsaCKEditor.js';
import {editorCommand} from './commands.js';
+import i18n from '../i18n/i18n.js';
/**
* @inheritDoc
*/
const defaultGraph = (div, title) => {
const self = graph(div, title);
+ self.i18n = i18n;
self.editor = null;
const initialize = self.initialize;
diff --git a/framework/elsa/fit-elsa/core/drawers/interactDrawer.js b/framework/elsa/fit-elsa/core/drawers/interactDrawer.js
index e636b2777..bed1a6180 100644
--- a/framework/elsa/fit-elsa/core/drawers/interactDrawer.js
+++ b/framework/elsa/fit-elsa/core/drawers/interactDrawer.js
@@ -93,11 +93,13 @@ const interactDrawer = (graph, page, div) => {
* @param {string} options.icon SVG 图标。
* @param {string} options.className CSS 类名。
* @param {Function} [options.onClick] 点击事件回调。
+ * @param {string} [options.tooltip] 工具说明。
* @returns {{ getComponent: Function, update: Function }}
*/
- const createBaseTool = ({icon, className, onClick}) => {
+ const createBaseTool = ({icon, className, onClick, tooltip}) => {
const button = graph.createDom('div', 'div', className, page.id);
button.innerHTML = icon;
+ button.title = tooltip;
Object.assign(button.style, {
display: 'flex',
width: '22px',
@@ -134,6 +136,7 @@ const interactDrawer = (graph, page, div) => {
page.fitScreen(PAGE_FIT_SCREEN_SCALE_MIN, PAGE_FIT_SCREEN_SCALE_MAX);
e.stopPropagation();
},
+ tooltip: graph.i18n.t('displayAllNodes'),
});
};
@@ -151,6 +154,7 @@ const interactDrawer = (graph, page, div) => {
tool.update(); // 触发更新
e.stopPropagation();
},
+ tooltip: graph.i18n.t('handMode'),
});
/**
@@ -178,6 +182,7 @@ const interactDrawer = (graph, page, div) => {
page.reorganizeNodes(PAGE_REORGANIZE_SCREEN_SCALE);
e.stopPropagation() // 阻止事件冒泡
},
+ tooltip: graph.i18n.t('reorganizeNodes'),
});
};
@@ -189,7 +194,7 @@ const interactDrawer = (graph, page, div) => {
const zoomTool = () => {
const me = {};
- const createZoomIn = () => {
+ const createZoomOut = () => {
const button = graph.createDom(div, 'div', 'barToolsZoomIn', page.id);
button.innerHTML = ``;
button.style.display = 'flex';
@@ -201,6 +206,7 @@ const interactDrawer = (graph, page, div) => {
button.onclick = () => {
me.zoomTo(page.scaleX - 0.1);
};
+ button.title = graph.i18n.t('zoomOut');
return button;
};
@@ -234,7 +240,7 @@ const interactDrawer = (graph, page, div) => {
return button;
};
- const createZoomOut = () => {
+ const createZoomIn = () => {
const button = graph.createDom(div, 'div', 'barToolsZoomOut', page.id);
button.innerHTML = ``;
button.style.display = 'flex';
@@ -246,6 +252,7 @@ const interactDrawer = (graph, page, div) => {
button.onclick = () => {
me.zoomTo(page.scaleX + 0.1);
};
+ button.title = graph.i18n.t('zoomIn');
return button;
};
@@ -255,15 +262,15 @@ const interactDrawer = (graph, page, div) => {
zoomWrapper.style.width = 'fit-content';
zoomWrapper.style.height = 'fit-content';
- const zoomIn = createZoomIn();
+ const zoomOut = createZoomOut();
const zoomSlider = createZoomSlider();
const zoomText = createZoomText();
- const zoomOut = createZoomOut();
+ const zoomIn = createZoomIn();
- zoomWrapper.appendChild(zoomIn);
+ zoomWrapper.appendChild(zoomOut);
zoomWrapper.appendChild(zoomSlider);
zoomWrapper.appendChild(zoomText);
- zoomWrapper.appendChild(zoomOut);
+ zoomWrapper.appendChild(zoomIn);
/**
* 获取缩放工具组件
diff --git a/framework/elsa/fit-elsa/i18n/en.json b/framework/elsa/fit-elsa/i18n/en.json
new file mode 100644
index 000000000..6d9cd7784
--- /dev/null
+++ b/framework/elsa/fit-elsa/i18n/en.json
@@ -0,0 +1,7 @@
+{
+ "displayAllNodes": "Display all nodes",
+ "handMode": "Hand mode",
+ "reorganizeNodes": "Organize nodes",
+ "zoomOut": "Zoom Out",
+ "zoomIn": "Zoom In"
+}
\ No newline at end of file
diff --git a/framework/elsa/fit-elsa/i18n/i18n.js b/framework/elsa/fit-elsa/i18n/i18n.js
new file mode 100644
index 000000000..d36716a77
--- /dev/null
+++ b/framework/elsa/fit-elsa/i18n/i18n.js
@@ -0,0 +1,30 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
+ * This file is a part of the ModelEngine Project.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import i18n from 'i18next';
+import en from './en.json';
+import zh from './zh.json';
+
+const resources = {
+ en: {
+ translation: en,
+ },
+ zh: {
+ translation: zh,
+ },
+};
+
+i18n.init({
+ resources,
+ lng: 'zh',
+ fallbackLng: 'zh',
+ interpolation: {
+ escapeValue: false,
+ },
+ returnNull: false,
+});
+
+export default i18n;
diff --git a/framework/elsa/fit-elsa/i18n/zh.json b/framework/elsa/fit-elsa/i18n/zh.json
new file mode 100644
index 000000000..b574476e9
--- /dev/null
+++ b/framework/elsa/fit-elsa/i18n/zh.json
@@ -0,0 +1,7 @@
+{
+ "displayAllNodes": "显示所有节点",
+ "handMode": "手模式",
+ "reorganizeNodes": "整理节点",
+ "zoomOut": "缩小",
+ "zoomIn": "放大"
+}
\ No newline at end of file
diff --git a/framework/elsa/fit-elsa/package.json b/framework/elsa/fit-elsa/package.json
index 456ed94ab..eb2c8a341 100644
--- a/framework/elsa/fit-elsa/package.json
+++ b/framework/elsa/fit-elsa/package.json
@@ -27,7 +27,8 @@
"testEnvironment": "jsdom"
},
"dependencies": {
- "@dagrejs/dagre": "^1.1.4"
+ "@dagrejs/dagre": "^1.1.4",
+ "i18next": "^21.6.0"
},
"devDependencies": {
"@babel/core": "^7.23.0",
@@ -47,5 +48,10 @@
"video.js": "^8.9.0",
"webpack": "5.94.0",
"webpack-cli": "5.1.4"
+ },
+ "exports": {
+ ".": "./build/elsa.js",
+ "./locales/en.json": "./i18n/en.json",
+ "./locales/zh.json": "./i18n/zh.json"
}
}