feat(i18n): 统一国际化系统架构,支持插件独立翻译 (#301)
* feat(i18n): 统一国际化系统架构,支持插件独立翻译 ## 主要改动 ### 核心架构 - 增强 LocaleService,支持插件命名空间翻译扩展 - 新增 editor-runtime/i18n 模块,提供 createPluginLocale/createPluginTranslator - 新增 editor-core/tokens.ts,定义 LocaleServiceToken 等服务令牌 - 改进 PluginAPI 类型安全,使用 ServiceToken<T> 替代 any ### 编辑器本地化 - 扩展 en.ts/zh.ts 翻译文件,覆盖所有 UI 组件 - 新增 es.ts 西班牙语支持 - 重构 40+ 组件使用 useLocale() hook ### 插件本地化系统 - behavior-tree-editor: 新增 locales/ 和 useBTLocale hook - material-editor: 新增 locales/ 和 useMaterialLocale hook - particle-editor: 新增 locales/ 和 useParticleLocale hook - tilemap-editor: 新增 locales/ 和 useTilemapLocale hook - ui-editor: 新增 locales/ 和 useUILocale hook ### 类型安全改进 - 修复 Debug 工具使用公共接口替代 as any - 修复 ChunkStreamingSystem 添加 forEachChunk 公共方法 - 修复 blueprint-editor 移除不必要的向后兼容代码 * fix(behavior-tree-editor): 使用 ServiceToken 模式修复服务解析 - 创建 BehaviorTreeServiceToken 遵循"谁定义接口,谁导出Token"原则 - 使用 ServiceToken.id (symbol) 注册服务到 ServiceContainer - 更新 PluginSDKRegistry.resolveService 支持 ServiceToken 检测 - BehaviorTreeEditorPanel 现在使用类型安全的 PluginAPI.resolve * fix(behavior-tree-editor): 使用 ServiceContainer.resolve 获取类注册的服务 * fix: 修复多个包的依赖和类型问题 - core: EntityDataCollector.getEntityDetails 使用 HierarchySystem 获取父实体 - ui-editor: 添加 @esengine/editor-runtime 依赖 - tilemap-editor: 添加 @esengine/editor-runtime 依赖 - particle-editor: 添加 @esengine/editor-runtime 依赖
This commit is contained in:
@@ -45,10 +45,19 @@ export enum PanelPosition {
|
||||
export interface PanelDescriptor {
|
||||
/** 面板ID | Panel ID */
|
||||
id: string;
|
||||
/** 面板标题 | Panel title */
|
||||
/**
|
||||
* 面板标题 | Panel title
|
||||
* 作为默认/英文标题,当 titleKey 未设置或翻译缺失时使用
|
||||
* Used as default/English title when titleKey is not set or translation is missing
|
||||
*/
|
||||
title: string;
|
||||
/** 面板中文标题 | Panel title in Chinese */
|
||||
titleZh?: string;
|
||||
/**
|
||||
* 面板标题翻译键 | Panel title translation key
|
||||
* 设置后会根据当前语言自动翻译
|
||||
* When set, title will be automatically translated based on current locale
|
||||
* @example 'panel.behaviorTreeEditor'
|
||||
*/
|
||||
titleKey?: string;
|
||||
/** 面板图标 | Panel icon */
|
||||
icon?: string;
|
||||
/** 面板位置 | Panel position */
|
||||
|
||||
@@ -4,16 +4,90 @@ import { createLogger } from '@esengine/ecs-framework';
|
||||
|
||||
const logger = createLogger('LocaleService');
|
||||
|
||||
export type Locale = 'en' | 'zh';
|
||||
/**
|
||||
* 支持的语言类型
|
||||
* Supported locale types
|
||||
*
|
||||
* - en: English
|
||||
* - zh: 简体中文 (Simplified Chinese)
|
||||
* - es: Español (Spanish)
|
||||
*/
|
||||
export type Locale = 'en' | 'zh' | 'es';
|
||||
|
||||
/**
|
||||
* 语言显示信息
|
||||
* Locale display information
|
||||
*/
|
||||
export interface LocaleInfo {
|
||||
code: Locale;
|
||||
name: string;
|
||||
nativeName: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支持的语言列表
|
||||
* List of supported locales
|
||||
*/
|
||||
export const SUPPORTED_LOCALES: readonly LocaleInfo[] = [
|
||||
{ code: 'en', name: 'English', nativeName: 'English' },
|
||||
{ code: 'zh', name: 'Chinese', nativeName: '简体中文' },
|
||||
{ code: 'es', name: 'Spanish', nativeName: 'Español' }
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* 翻译值类型
|
||||
* Translation value type
|
||||
*/
|
||||
export interface Translations {
|
||||
[key: string]: string | Translations;
|
||||
}
|
||||
|
||||
/**
|
||||
* 国际化服务
|
||||
* 插件翻译包
|
||||
* Plugin translation bundle
|
||||
*
|
||||
* 管理编辑器的多语言支持
|
||||
* 用于插件注册自己的翻译
|
||||
* Used for plugins to register their own translations
|
||||
*/
|
||||
export interface PluginTranslations {
|
||||
en: Translations;
|
||||
zh: Translations;
|
||||
es?: Translations;
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻译参数类型
|
||||
* Translation parameters type
|
||||
*/
|
||||
export type TranslationParams = Record<string, string | number>;
|
||||
|
||||
/**
|
||||
* 国际化服务
|
||||
* Internationalization service
|
||||
*
|
||||
* 管理编辑器的多语言支持,提供翻译、语言切换和事件通知功能。
|
||||
* Manages editor's multi-language support, provides translation, locale switching and event notification.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // 获取服务 | Get service
|
||||
* const localeService = Core.services.resolve(LocaleService);
|
||||
*
|
||||
* // 翻译文本 | Translate text
|
||||
* localeService.t('common.save'); // "Save" or "保存"
|
||||
*
|
||||
* // 带参数的翻译 | Translation with parameters
|
||||
* localeService.t('scene.savedSuccess', { name: 'MyScene' }); // "Scene saved: MyScene"
|
||||
*
|
||||
* // 切换语言 | Switch locale
|
||||
* localeService.setLocale('zh');
|
||||
*
|
||||
* // 插件注册翻译 | Plugin register translations
|
||||
* localeService.extendTranslations('behaviorTree', {
|
||||
* en: { title: 'Behavior Tree Editor', ... },
|
||||
* zh: { title: '行为树编辑器', ... }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
@Injectable()
|
||||
export class LocaleService implements IService {
|
||||
@@ -29,22 +103,125 @@ export class LocaleService implements IService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册语言包
|
||||
* 注册核心语言包(覆盖式)
|
||||
* Register core translations (overwrites existing)
|
||||
*
|
||||
* 用于编辑器核心初始化时注册基础翻译
|
||||
* Used for editor core to register base translations during initialization
|
||||
*
|
||||
* @param locale - 语言代码 | Locale code
|
||||
* @param translations - 翻译对象 | Translation object
|
||||
*/
|
||||
public registerTranslations(locale: Locale, translations: Translations): void {
|
||||
this.translations.set(locale, translations);
|
||||
logger.info(`Registered translations for locale: ${locale}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 扩展语言包(合并式)
|
||||
* Extend translations (merges with existing)
|
||||
*
|
||||
* 用于插件注册自己的翻译,会合并到现有翻译中
|
||||
* Used for plugins to register their translations, merges with existing
|
||||
*
|
||||
* @param namespace - 命名空间,如 'behaviorTree' | Namespace, e.g. 'behaviorTree'
|
||||
* @param pluginTranslations - 插件翻译包 | Plugin translation bundle
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // 在插件的 editorModule.install() 中调用
|
||||
* // Call in plugin's editorModule.install()
|
||||
* localeService.extendTranslations('behaviorTree', {
|
||||
* en: {
|
||||
* title: 'Behavior Tree Editor',
|
||||
* nodePalette: 'Node Palette',
|
||||
* // ...
|
||||
* },
|
||||
* zh: {
|
||||
* title: '行为树编辑器',
|
||||
* nodePalette: '节点面板',
|
||||
* // ...
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* // 然后在组件中使用
|
||||
* // Then use in components
|
||||
* t('behaviorTree.title') // "Behavior Tree Editor" or "行为树编辑器"
|
||||
* ```
|
||||
*/
|
||||
public extendTranslations(namespace: string, pluginTranslations: PluginTranslations): void {
|
||||
const locales: Locale[] = ['en', 'zh', 'es'];
|
||||
|
||||
for (const locale of locales) {
|
||||
const existing = this.translations.get(locale) || {};
|
||||
const pluginTrans = pluginTranslations[locale];
|
||||
|
||||
if (pluginTrans) {
|
||||
// 深度合并到命名空间下 | Deep merge under namespace
|
||||
const merged = {
|
||||
...existing,
|
||||
[namespace]: this.deepMerge(
|
||||
(existing[namespace] as Translations) || {},
|
||||
pluginTrans
|
||||
)
|
||||
};
|
||||
this.translations.set(locale, merged);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(`Extended translations for namespace: ${namespace}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 深度合并两个翻译对象
|
||||
* Deep merge two translation objects
|
||||
*/
|
||||
private deepMerge(target: Translations, source: Translations): Translations {
|
||||
const result: Translations = { ...target };
|
||||
|
||||
for (const key of Object.keys(source)) {
|
||||
const sourceValue = source[key];
|
||||
const targetValue = target[key];
|
||||
|
||||
if (
|
||||
typeof sourceValue === 'object' &&
|
||||
sourceValue !== null &&
|
||||
typeof targetValue === 'object' &&
|
||||
targetValue !== null
|
||||
) {
|
||||
result[key] = this.deepMerge(
|
||||
targetValue as Translations,
|
||||
sourceValue as Translations
|
||||
);
|
||||
} else {
|
||||
result[key] = sourceValue;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前语言
|
||||
* Get current locale
|
||||
*/
|
||||
public getCurrentLocale(): Locale {
|
||||
return this.currentLocale;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支持的语言列表
|
||||
* Get list of supported locales
|
||||
*/
|
||||
public getSupportedLocales(): readonly LocaleInfo[] {
|
||||
return SUPPORTED_LOCALES;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前语言
|
||||
* Set current locale
|
||||
*
|
||||
* @param locale - 目标语言代码 | Target locale code
|
||||
*/
|
||||
public setLocale(locale: Locale): void {
|
||||
if (!this.translations.has(locale)) {
|
||||
@@ -62,11 +239,28 @@ export class LocaleService implements IService {
|
||||
|
||||
/**
|
||||
* 翻译文本
|
||||
* Translate text
|
||||
*
|
||||
* @param key - 翻译键,支持点分隔的路径如 "menu.file.save"
|
||||
* @param fallback - 如果找不到翻译时的回退文本
|
||||
* @param key - 翻译键,支持点分隔的路径 | Translation key, supports dot-separated paths
|
||||
* @param params - 可选的参数对象,用于替换模板中的占位符 {{key}} | Optional params for placeholder substitution
|
||||
* @param fallback - 如果找不到翻译时的回退文本 | Fallback text if translation not found
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // 简单翻译 | Simple translation
|
||||
* t('common.save') // "Save"
|
||||
*
|
||||
* // 带参数替换 | With parameter substitution
|
||||
* t('scene.savedSuccess', { name: 'MyScene' }) // "Scene saved: MyScene"
|
||||
*
|
||||
* // 插件翻译 | Plugin translation
|
||||
* t('behaviorTree.title') // "Behavior Tree Editor"
|
||||
*
|
||||
* // 带回退文本 | With fallback
|
||||
* t('unknown.key', undefined, 'Default Text') // "Default Text"
|
||||
* ```
|
||||
*/
|
||||
public t(key: string, fallback?: string): string {
|
||||
public t(key: string, params?: TranslationParams, fallback?: string): string {
|
||||
const translations = this.translations.get(this.currentLocale);
|
||||
if (!translations) {
|
||||
return fallback || key;
|
||||
@@ -74,6 +268,12 @@ export class LocaleService implements IService {
|
||||
|
||||
const value = this.getNestedValue(translations, key);
|
||||
if (typeof value === 'string') {
|
||||
// 支持参数替换 {{key}} | Support parameter substitution {{key}}
|
||||
if (params) {
|
||||
return value.replace(/\{\{(\w+)\}\}/g, (_, paramKey) => {
|
||||
return String(params[paramKey] ?? `{{${paramKey}}}`);
|
||||
});
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -82,6 +282,10 @@ export class LocaleService implements IService {
|
||||
|
||||
/**
|
||||
* 监听语言变化
|
||||
* Listen to locale changes
|
||||
*
|
||||
* @param listener - 回调函数 | Callback function
|
||||
* @returns 取消订阅函数 | Unsubscribe function
|
||||
*/
|
||||
public onChange(listener: (locale: Locale) => void): () => void {
|
||||
this.changeListeners.add(listener);
|
||||
@@ -91,12 +295,30 @@ export class LocaleService implements IService {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查翻译键是否存在
|
||||
* Check if a translation key exists
|
||||
*
|
||||
* @param key - 翻译键 | Translation key
|
||||
* @param locale - 可选的语言代码,默认使用当前语言 | Optional locale, defaults to current
|
||||
*/
|
||||
public hasKey(key: string, locale?: Locale): boolean {
|
||||
const targetLocale = locale || this.currentLocale;
|
||||
const translations = this.translations.get(targetLocale);
|
||||
if (!translations) {
|
||||
return false;
|
||||
}
|
||||
const value = this.getNestedValue(translations, key);
|
||||
return typeof value === 'string';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取嵌套对象的值
|
||||
* Get nested object value
|
||||
*/
|
||||
private getNestedValue(obj: Translations, path: string): string | Translations | undefined {
|
||||
const keys = path.split('.');
|
||||
let current: any = obj;
|
||||
let current: string | Translations | undefined = obj;
|
||||
|
||||
for (const key of keys) {
|
||||
if (current && typeof current === 'object' && key in current) {
|
||||
@@ -111,11 +333,12 @@ export class LocaleService implements IService {
|
||||
|
||||
/**
|
||||
* 从 localStorage 加载保存的语言设置
|
||||
* Load saved locale from localStorage
|
||||
*/
|
||||
private loadSavedLocale(): Locale | null {
|
||||
try {
|
||||
const saved = localStorage.getItem('editor-locale');
|
||||
if (saved === 'en' || saved === 'zh') {
|
||||
if (saved === 'en' || saved === 'zh' || saved === 'es') {
|
||||
return saved;
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -126,6 +349,7 @@ export class LocaleService implements IService {
|
||||
|
||||
/**
|
||||
* 保存语言设置到 localStorage
|
||||
* Save locale to localStorage
|
||||
*/
|
||||
private saveLocale(locale: Locale): void {
|
||||
try {
|
||||
|
||||
@@ -2,44 +2,83 @@ import { Injectable, IService } from '@esengine/ecs-framework';
|
||||
|
||||
export type SettingType = 'string' | 'number' | 'boolean' | 'select' | 'color' | 'range' | 'pluginList' | 'collisionMatrix' | 'moduleList';
|
||||
|
||||
/**
|
||||
* Localizable text - can be a plain string or a translation key (prefixed with '$')
|
||||
* 可本地化文本 - 可以是普通字符串或翻译键(以 '$' 为前缀)
|
||||
*
|
||||
* @example
|
||||
* // Plain text (not recommended for user-facing strings)
|
||||
* title: 'Appearance'
|
||||
*
|
||||
* // Translation key (recommended)
|
||||
* title: '$pluginSettings.appearance.title'
|
||||
*/
|
||||
export type LocalizableText = string;
|
||||
|
||||
/**
|
||||
* Check if text is a translation key (starts with '$')
|
||||
* 检查文本是否为翻译键(以 '$' 开头)
|
||||
*/
|
||||
export function isTranslationKey(text: string): boolean {
|
||||
return text.startsWith('$');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actual translation key (without '$' prefix)
|
||||
* 获取实际的翻译键(去掉 '$' 前缀)
|
||||
*/
|
||||
export function getTranslationKey(text: string): string {
|
||||
return text.startsWith('$') ? text.slice(1) : text;
|
||||
}
|
||||
|
||||
export interface SettingOption {
|
||||
label: string;
|
||||
label: LocalizableText;
|
||||
value: any;
|
||||
}
|
||||
|
||||
export interface SettingValidator {
|
||||
validate: (value: any) => boolean;
|
||||
errorMessage: string;
|
||||
errorMessage: LocalizableText;
|
||||
}
|
||||
|
||||
export interface SettingDescriptor {
|
||||
key: string;
|
||||
label: string;
|
||||
/** Label text or translation key (prefixed with '$') | 标签文本或翻译键(以 '$' 为前缀) */
|
||||
label: LocalizableText;
|
||||
type: SettingType;
|
||||
defaultValue: any;
|
||||
description?: string;
|
||||
placeholder?: string;
|
||||
/** Description text or translation key (prefixed with '$') | 描述文本或翻译键(以 '$' 为前缀) */
|
||||
description?: LocalizableText;
|
||||
/** Placeholder text or translation key (prefixed with '$') | 占位符文本或翻译键(以 '$' 为前缀) */
|
||||
placeholder?: LocalizableText;
|
||||
options?: SettingOption[];
|
||||
validator?: SettingValidator;
|
||||
min?: number;
|
||||
max?: number;
|
||||
step?: number;
|
||||
/** 自定义渲染器组件(用于 collisionMatrix 等复杂类型) */
|
||||
/**
|
||||
* Custom renderer component (for complex types like collisionMatrix)
|
||||
* 自定义渲染器组件(用于 collisionMatrix 等复杂类型)
|
||||
*/
|
||||
customRenderer?: React.ComponentType<any>;
|
||||
}
|
||||
|
||||
export interface SettingSection {
|
||||
id: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
/** Title text or translation key (prefixed with '$') | 标题文本或翻译键(以 '$' 为前缀) */
|
||||
title: LocalizableText;
|
||||
/** Description text or translation key (prefixed with '$') | 描述文本或翻译键(以 '$' 为前缀) */
|
||||
description?: LocalizableText;
|
||||
icon?: string;
|
||||
settings: SettingDescriptor[];
|
||||
}
|
||||
|
||||
export interface SettingCategory {
|
||||
id: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
/** Title text or translation key (prefixed with '$') | 标题文本或翻译键(以 '$' 为前缀) */
|
||||
title: LocalizableText;
|
||||
/** Description text or translation key (prefixed with '$') | 描述文本或翻译键(以 '$' 为前缀) */
|
||||
description?: LocalizableText;
|
||||
sections: SettingSection[];
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
* Plugin-based editor framework for ECS Framework
|
||||
*/
|
||||
|
||||
// Service Tokens | 服务令牌
|
||||
export * from './tokens';
|
||||
|
||||
// 配置 | Configuration
|
||||
export * from './Config';
|
||||
|
||||
|
||||
157
packages/editor-core/src/tokens.ts
Normal file
157
packages/editor-core/src/tokens.ts
Normal file
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* Editor Core 服务令牌
|
||||
* Editor Core service tokens
|
||||
*
|
||||
* 定义 editor-core 模块导出的服务令牌和接口。
|
||||
* Defines service tokens and interfaces exported by editor-core module.
|
||||
*
|
||||
* 遵循 "谁定义接口,谁导出 Token" 的规范。
|
||||
* Follows the "who defines interface, who exports token" principle.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* // 消费方导入 Token | Consumer imports Token
|
||||
* import { LocaleServiceToken, MessageHubToken, EntityStoreServiceToken } from '@esengine/editor-core';
|
||||
*
|
||||
* // 获取服务 | Get service
|
||||
* const localeService = context.services.get(LocaleServiceToken);
|
||||
* const messageHub = context.services.get(MessageHubToken);
|
||||
* ```
|
||||
*/
|
||||
|
||||
import { createServiceToken } from '@esengine/engine-core';
|
||||
import type { LocaleService, Locale, TranslationParams, PluginTranslations } from './Services/LocaleService';
|
||||
import type { MessageHub, MessageHandler, RequestHandler } from './Services/MessageHub';
|
||||
import type { EntityStoreService, EntityTreeNode } from './Services/EntityStoreService';
|
||||
|
||||
// ============================================================================
|
||||
// LocaleService Token
|
||||
// 国际化服务令牌
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* LocaleService 接口
|
||||
* LocaleService interface
|
||||
*
|
||||
* 提供类型安全的服务访问接口。
|
||||
* Provides type-safe service access interface.
|
||||
*/
|
||||
export interface ILocaleService {
|
||||
/** 获取当前语言 | Get current locale */
|
||||
getLocale(): Locale;
|
||||
/** 设置当前语言 | Set current locale */
|
||||
setLocale(locale: Locale): void;
|
||||
/** 翻译文本 | Translate text */
|
||||
t(key: string, params?: TranslationParams, fallback?: string): string;
|
||||
/** 扩展翻译 | Extend translations */
|
||||
extendTranslations(namespace: string, translations: PluginTranslations): void;
|
||||
/** 监听语言变化 | Listen to locale changes */
|
||||
onLocaleChange(listener: (locale: Locale) => void): () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* 国际化服务令牌
|
||||
* Localization service token
|
||||
*
|
||||
* 用于注册和获取国际化服务。
|
||||
* For registering and getting localization service.
|
||||
*/
|
||||
export const LocaleServiceToken = createServiceToken<ILocaleService>('localeService');
|
||||
|
||||
// ============================================================================
|
||||
// MessageHub Token
|
||||
// 消息总线令牌
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* MessageHub 服务接口
|
||||
* MessageHub service interface
|
||||
*
|
||||
* 提供类型安全的消息通信接口。
|
||||
* Provides type-safe message communication interface.
|
||||
*/
|
||||
export interface IMessageHubService {
|
||||
/** 订阅消息 | Subscribe to message */
|
||||
subscribe<T = unknown>(topic: string, handler: MessageHandler<T>): () => void;
|
||||
/** 订阅一次性消息 | Subscribe to one-time message */
|
||||
subscribeOnce<T = unknown>(topic: string, handler: MessageHandler<T>): () => void;
|
||||
/** 发布消息 | Publish message */
|
||||
publish<T = unknown>(topic: string, data?: T): Promise<void>;
|
||||
/** 注册请求处理器 | Register request handler */
|
||||
registerRequest<TRequest = unknown, TResponse = unknown>(
|
||||
topic: string,
|
||||
handler: RequestHandler<TRequest, TResponse>
|
||||
): () => void;
|
||||
/** 发送请求 | Send request */
|
||||
request<TRequest = unknown, TResponse = unknown>(
|
||||
topic: string,
|
||||
data?: TRequest,
|
||||
timeout?: number
|
||||
): Promise<TResponse>;
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息总线服务令牌
|
||||
* Message hub service token
|
||||
*
|
||||
* 用于注册和获取消息总线服务。
|
||||
* For registering and getting message hub service.
|
||||
*/
|
||||
export const MessageHubToken = createServiceToken<IMessageHubService>('messageHub');
|
||||
|
||||
// ============================================================================
|
||||
// EntityStoreService Token
|
||||
// 实体存储服务令牌
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* EntityStoreService 接口
|
||||
* EntityStoreService interface
|
||||
*
|
||||
* 提供类型安全的实体存储服务访问接口。
|
||||
* Provides type-safe entity store service access interface.
|
||||
*/
|
||||
export interface IEntityStoreService {
|
||||
/** 添加实体 | Add entity */
|
||||
addEntity(entity: unknown, parent?: unknown): void;
|
||||
/** 移除实体 | Remove entity */
|
||||
removeEntity(entity: unknown): void;
|
||||
/** 选择实体 | Select entity */
|
||||
selectEntity(entity: unknown | null): void;
|
||||
/** 获取选中的实体 | Get selected entity */
|
||||
getSelectedEntity(): unknown | null;
|
||||
/** 获取所有实体 | Get all entities */
|
||||
getAllEntities(): unknown[];
|
||||
/** 获取根实体 | Get root entities */
|
||||
getRootEntities(): unknown[];
|
||||
/** 根据ID获取实体 | Get entity by ID */
|
||||
getEntity(id: number): unknown | undefined;
|
||||
/** 清空实体 | Clear all entities */
|
||||
clear(): void;
|
||||
/** 构建实体树 | Build entity tree */
|
||||
buildEntityTree(): EntityTreeNode[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 实体存储服务令牌
|
||||
* Entity store service token
|
||||
*
|
||||
* 用于注册和获取实体存储服务。
|
||||
* For registering and getting entity store service.
|
||||
*/
|
||||
export const EntityStoreServiceToken = createServiceToken<IEntityStoreService>('entityStoreService');
|
||||
|
||||
// ============================================================================
|
||||
// Re-export types for convenience
|
||||
// 重新导出类型方便使用
|
||||
// ============================================================================
|
||||
|
||||
export type { Locale, TranslationParams, PluginTranslations } from './Services/LocaleService';
|
||||
export type { MessageHandler, RequestHandler } from './Services/MessageHub';
|
||||
export type { EntityTreeNode } from './Services/EntityStoreService';
|
||||
|
||||
// Re-export classes for direct use (backwards compatibility)
|
||||
// 重新导出类以供直接使用(向后兼容)
|
||||
export { LocaleService } from './Services/LocaleService';
|
||||
export { MessageHub } from './Services/MessageHub';
|
||||
export { EntityStoreService } from './Services/EntityStoreService';
|
||||
Reference in New Issue
Block a user