@flexem/fc-gui 3.0.0-alpha.141 → 3.0.0-alpha.143

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -40,9 +40,10 @@ export declare class TextStateElement {
40
40
  private clearFlickerInterval;
41
41
  /**
42
42
  * 获取显示文本
43
- * 如果配置了文本库,则根据状态ID和当前语种ID从文本库中获取对应语种的文本
44
- * 如果是多语种自定义文本,则根据当前语种ID获取对应语种的文本
45
- * 否则返回默认文本
43
+ * 支持三种格式:
44
+ * 1. 新格式:textData.cultures 在顶层(与 content 并列)
45
+ * 2. 中间格式:textData.content 为 { cultures: {...} }(已废弃,向下兼容)
46
+ * 3. 旧格式:textData.content 为字符串
46
47
  */
47
48
  private getDisplayText;
48
49
  }
@@ -31,7 +31,7 @@ export class TextStateElement {
31
31
  return;
32
32
  }
33
33
  // 获取显示文本(支持文本库)
34
- const content = this.getDisplayText(stateId, textState.text.content);
34
+ const content = this.getDisplayText(stateId, textState.text);
35
35
  if (content === '' || content == null) {
36
36
  this.removeForeignObjectlement();
37
37
  return;
@@ -152,24 +152,41 @@ export class TextStateElement {
152
152
  }
153
153
  /**
154
154
  * 获取显示文本
155
- * 如果配置了文本库,则根据状态ID和当前语种ID从文本库中获取对应语种的文本
156
- * 如果是多语种自定义文本,则根据当前语种ID获取对应语种的文本
157
- * 否则返回默认文本
155
+ * 支持三种格式:
156
+ * 1. 新格式:textData.cultures 在顶层(与 content 并列)
157
+ * 2. 中间格式:textData.content 为 { cultures: {...} }(已废弃,向下兼容)
158
+ * 3. 旧格式:textData.content 为字符串
158
159
  */
159
- getDisplayText(stateId, defaultContent) {
160
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
161
- // 如果 defaultContent 是多语种对象,优先使用(覆盖文本库)
162
- if (defaultContent && typeof defaultContent === 'object' && defaultContent.cultures) {
160
+ getDisplayText(stateId, textData) {
161
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
162
+ const getTargetLanguage = () => {
163
+ var _a, _b, _c, _d, _e, _f;
163
164
  const currentLanguageId = (_c = (_b = (_a = this.guiContext) === null || _a === void 0 ? void 0 : _a.getCurrentLanguageId) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : null;
164
165
  const defaultLanguage = ((_d = this.languageService) === null || _d === void 0 ? void 0 : _d.getDefaultLanguage()) || 'zh-CN';
165
- let targetLanguage;
166
166
  if (currentLanguageId === null || currentLanguageId === undefined) {
167
- targetLanguage = defaultLanguage;
167
+ return defaultLanguage;
168
+ }
169
+ return ((_f = (_e = this.guiContext) === null || _e === void 0 ? void 0 : _e.getLanguageCultureById) === null || _f === void 0 ? void 0 : _f.call(_e, currentLanguageId)) || defaultLanguage;
170
+ };
171
+ const defaultContent = textData === null || textData === void 0 ? void 0 : textData.content;
172
+ // 新格式:cultures 在 text 顶层
173
+ if (textData && textData.cultures && typeof textData.cultures === 'object') {
174
+ const targetLanguage = getTargetLanguage();
175
+ if (textData.cultures[targetLanguage]) {
176
+ return textData.cultures[targetLanguage];
177
+ }
178
+ else if (this.allowEmpty) {
179
+ return '';
168
180
  }
169
181
  else {
170
- const currentLanguage = (_f = (_e = this.guiContext) === null || _e === void 0 ? void 0 : _e.getLanguageCultureById) === null || _f === void 0 ? void 0 : _f.call(_e, currentLanguageId);
171
- targetLanguage = currentLanguage || defaultLanguage;
182
+ const language = ((_c = (_b = (_a = window.abp) === null || _a === void 0 ? void 0 : _a.localization) === null || _b === void 0 ? void 0 : _b.currentLanguage) === null || _c === void 0 ? void 0 : _c.name) || 'zh-Hans';
183
+ const isChinese = language === 'zh-Hans' || language === 'zh';
184
+ return isChinese ? '文本' : 'Text';
172
185
  }
186
+ }
187
+ // 中间格式(兼容):content 为 { cultures: {...} }
188
+ if (defaultContent && typeof defaultContent === 'object' && defaultContent.cultures) {
189
+ const targetLanguage = getTargetLanguage();
173
190
  if (defaultContent.cultures[targetLanguage]) {
174
191
  return defaultContent.cultures[targetLanguage];
175
192
  }
@@ -177,7 +194,7 @@ export class TextStateElement {
177
194
  return '';
178
195
  }
179
196
  else {
180
- const language = ((_j = (_h = (_g = window.abp) === null || _g === void 0 ? void 0 : _g.localization) === null || _h === void 0 ? void 0 : _h.currentLanguage) === null || _j === void 0 ? void 0 : _j.name) || 'zh-Hans';
197
+ const language = ((_f = (_e = (_d = window.abp) === null || _d === void 0 ? void 0 : _d.localization) === null || _e === void 0 ? void 0 : _e.currentLanguage) === null || _f === void 0 ? void 0 : _f.name) || 'zh-Hans';
181
198
  const isChinese = language === 'zh-Hans' || language === 'zh';
182
199
  return isChinese ? '文本' : 'Text';
183
200
  }
@@ -193,17 +210,17 @@ export class TextStateElement {
193
210
  const textEntry = textLibraryData.data.find(entry => entry.value === stateId.toString());
194
211
  if (textEntry) {
195
212
  // 获取当前语种ID
196
- const currentLanguageId = (_m = (_l = (_k = this.guiContext) === null || _k === void 0 ? void 0 : _k.getCurrentLanguageId) === null || _l === void 0 ? void 0 : _l.call(_k)) !== null && _m !== void 0 ? _m : null;
213
+ const currentLanguageId = (_j = (_h = (_g = this.guiContext) === null || _g === void 0 ? void 0 : _g.getCurrentLanguageId) === null || _h === void 0 ? void 0 : _h.call(_g)) !== null && _j !== void 0 ? _j : null;
197
214
  // 确定要使用的语种代码(culture)
198
215
  let targetLanguage;
199
- const defaultLanguage = ((_o = this.languageService) === null || _o === void 0 ? void 0 : _o.getDefaultLanguage()) || 'zh-CN';
216
+ const defaultLanguage = ((_k = this.languageService) === null || _k === void 0 ? void 0 : _k.getDefaultLanguage()) || 'zh-CN';
200
217
  if (currentLanguageId === null || currentLanguageId === undefined) {
201
218
  // 设备未设置当前语种,使用默认语种
202
219
  targetLanguage = defaultLanguage;
203
220
  }
204
221
  else {
205
222
  // 设备已设置当前语种,获取对应的语种代码
206
- const currentLanguage = (_q = (_p = this.guiContext) === null || _p === void 0 ? void 0 : _p.getLanguageCultureById) === null || _q === void 0 ? void 0 : _q.call(_p, currentLanguageId);
223
+ const currentLanguage = (_m = (_l = this.guiContext) === null || _l === void 0 ? void 0 : _l.getLanguageCultureById) === null || _m === void 0 ? void 0 : _m.call(_l, currentLanguageId);
207
224
  if (currentLanguage) {
208
225
  // 直接使用设备设置的语种,不再fallback
209
226
  targetLanguage = currentLanguage;
@@ -92,7 +92,7 @@ export class HyperlinkElement extends ConditionalDynamicDisplayElement {
92
92
  * 否则返回默认文本
93
93
  */
94
94
  getDisplayText() {
95
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
95
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
96
96
  // 检查是否使用文本库
97
97
  if (this.model.textLibrary && this.model.textLibrary.labelType === 'textLibrary') {
98
98
  const textLibraryId = this.model.textLibrary.selectedTextLibraryItem;
@@ -137,37 +137,30 @@ export class HyperlinkElement extends ConditionalDynamicDisplayElement {
137
137
  return '';
138
138
  }
139
139
  // 处理自定义文本(支持多语种)
140
- if (this.model.text) {
141
- // 检查是否为多语种格式
142
- if (typeof this.model.text === 'object' && this.model.text.cultures) {
143
- // 新格式:多语种对象
144
- // 获取当前语种ID
145
- const currentLanguageId = (_j = (_h = (_g = this.guiContext) === null || _g === void 0 ? void 0 : _g.getCurrentLanguageId) === null || _h === void 0 ? void 0 : _h.call(_g)) !== null && _j !== void 0 ? _j : null;
146
- // 确定要使用的语种代码(culture)
147
- let targetLanguage;
148
- const defaultLanguage = ((_k = this.languageService) === null || _k === void 0 ? void 0 : _k.getDefaultLanguage()) || 'zh-CN';
140
+ if (this.model.text || this.model.textCultures) {
141
+ // 获取目标语种(公共逻辑)
142
+ const getTargetLanguage = () => {
143
+ var _a, _b, _c, _d, _e, _f;
144
+ const currentLanguageId = (_c = (_b = (_a = this.guiContext) === null || _a === void 0 ? void 0 : _a.getCurrentLanguageId) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : null;
145
+ const defaultLanguage = ((_d = this.languageService) === null || _d === void 0 ? void 0 : _d.getDefaultLanguage()) || 'zh-CN';
149
146
  if (currentLanguageId === null || currentLanguageId === undefined) {
150
- // 设备未设置当前语种,使用默认语种
151
- targetLanguage = defaultLanguage;
152
- }
153
- else {
154
- // 设备已设置当前语种,获取对应的语种代码
155
- const currentLanguage = (_m = (_l = this.guiContext) === null || _l === void 0 ? void 0 : _l.getLanguageCultureById) === null || _m === void 0 ? void 0 : _m.call(_l, currentLanguageId);
156
- if (currentLanguage) {
157
- targetLanguage = currentLanguage;
158
- }
159
- else {
160
- targetLanguage = defaultLanguage;
161
- }
147
+ return defaultLanguage;
162
148
  }
163
- // 返回对应语种的文本,如果没有则根据当前语言环境显示默认文本
164
- // 获取当前语言环境
165
- const language = ((_q = (_p = (_o = window.abp) === null || _o === void 0 ? void 0 : _o.localization) === null || _p === void 0 ? void 0 : _p.currentLanguage) === null || _q === void 0 ? void 0 : _q.name) || 'zh-Hans';
166
- const isChinese = language === 'zh-Hans' || language === 'zh';
167
- return this.model.text.cultures[targetLanguage] || (isChinese ? '超链接' : 'Hyperlink');
149
+ return ((_f = (_e = this.guiContext) === null || _e === void 0 ? void 0 : _e.getLanguageCultureById) === null || _f === void 0 ? void 0 : _f.call(_e, currentLanguageId)) || defaultLanguage;
150
+ };
151
+ const language = ((_j = (_h = (_g = window.abp) === null || _g === void 0 ? void 0 : _g.localization) === null || _h === void 0 ? void 0 : _h.currentLanguage) === null || _j === void 0 ? void 0 : _j.name) || 'zh-Hans';
152
+ const isChinese = language === 'zh-Hans' || language === 'zh';
153
+ const fallback = isChinese ? '超链接' : 'Hyperlink';
154
+ // 新格式:textCultures 在顶层(与 text 字段并列)
155
+ if (this.model.textCultures && typeof this.model.textCultures === 'object') {
156
+ return this.model.textCultures[getTargetLanguage()] || fallback;
157
+ }
158
+ // 中间格式(兼容):text 为 { cultures: {...} }
159
+ if (typeof this.model.text === 'object' && this.model.text.cultures) {
160
+ return this.model.text.cultures[getTargetLanguage()] || fallback;
168
161
  }
169
- else if (typeof this.model.text === 'string') {
170
- // 旧格式:字符串
162
+ // 旧格式:字符串
163
+ if (typeof this.model.text === 'string') {
171
164
  return this.model.text;
172
165
  }
173
166
  }
@@ -84,7 +84,7 @@ export class TextElement extends ConditionalDynamicDisplayElement {
84
84
  * 否则返回默认文本
85
85
  */
86
86
  getDisplayText() {
87
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
87
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
88
88
  // 检查是否使用文本库
89
89
  if (this.model.textLibrary && this.model.textLibrary.labelType === 'textLibrary') {
90
90
  const textLibraryId = this.model.textLibrary.selectedTextLibraryItem;
@@ -129,37 +129,30 @@ export class TextElement extends ConditionalDynamicDisplayElement {
129
129
  return '';
130
130
  }
131
131
  // 处理自定义文本(支持多语种)
132
- if (this.model.text) {
133
- // 检查是否为多语种格式
134
- if (typeof this.model.text === 'object' && this.model.text.cultures) {
135
- // 新格式:多语种对象
136
- // 获取当前语种ID
137
- const currentLanguageId = (_j = (_h = (_g = this.guiContext) === null || _g === void 0 ? void 0 : _g.getCurrentLanguageId) === null || _h === void 0 ? void 0 : _h.call(_g)) !== null && _j !== void 0 ? _j : null;
138
- // 确定要使用的语种代码(culture)
139
- let targetLanguage;
140
- const defaultLanguage = ((_k = this.languageService) === null || _k === void 0 ? void 0 : _k.getDefaultLanguage()) || 'zh-CN';
132
+ if (this.model.text || this.model.textCultures) {
133
+ // 获取目标语种(公共逻辑)
134
+ const getTargetLanguage = () => {
135
+ var _a, _b, _c, _d, _e, _f;
136
+ const currentLanguageId = (_c = (_b = (_a = this.guiContext) === null || _a === void 0 ? void 0 : _a.getCurrentLanguageId) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : null;
137
+ const defaultLanguage = ((_d = this.languageService) === null || _d === void 0 ? void 0 : _d.getDefaultLanguage()) || 'zh-CN';
141
138
  if (currentLanguageId === null || currentLanguageId === undefined) {
142
- // 设备未设置当前语种,使用默认语种
143
- targetLanguage = defaultLanguage;
144
- }
145
- else {
146
- // 设备已设置当前语种,获取对应的语种代码
147
- const currentLanguage = (_m = (_l = this.guiContext) === null || _l === void 0 ? void 0 : _l.getLanguageCultureById) === null || _m === void 0 ? void 0 : _m.call(_l, currentLanguageId);
148
- if (currentLanguage) {
149
- targetLanguage = currentLanguage;
150
- }
151
- else {
152
- targetLanguage = defaultLanguage;
153
- }
139
+ return defaultLanguage;
154
140
  }
155
- // 返回对应语种的文本,如果没有则根据当前语言环境显示默认文本
156
- // 获取当前语言环境
157
- const language = ((_q = (_p = (_o = window.abp) === null || _o === void 0 ? void 0 : _o.localization) === null || _p === void 0 ? void 0 : _p.currentLanguage) === null || _q === void 0 ? void 0 : _q.name) || 'zh-Hans';
158
- const isChinese = language === 'zh-Hans' || language === 'zh';
159
- return this.model.text.cultures[targetLanguage] || (isChinese ? '文本' : 'Text');
141
+ return ((_f = (_e = this.guiContext) === null || _e === void 0 ? void 0 : _e.getLanguageCultureById) === null || _f === void 0 ? void 0 : _f.call(_e, currentLanguageId)) || defaultLanguage;
142
+ };
143
+ const language = ((_j = (_h = (_g = window.abp) === null || _g === void 0 ? void 0 : _g.localization) === null || _h === void 0 ? void 0 : _h.currentLanguage) === null || _j === void 0 ? void 0 : _j.name) || 'zh-Hans';
144
+ const isChinese = language === 'zh-Hans' || language === 'zh';
145
+ const fallback = isChinese ? '文本' : 'Text';
146
+ // 新格式:textCultures 在顶层(与 text 字段并列)
147
+ if (this.model.textCultures && typeof this.model.textCultures === 'object') {
148
+ return this.model.textCultures[getTargetLanguage()] || fallback;
149
+ }
150
+ // 中间格式(兼容):text 为 { cultures: {...} }
151
+ if (typeof this.model.text === 'object' && this.model.text.cultures) {
152
+ return this.model.text.cultures[getTargetLanguage()] || fallback;
160
153
  }
161
- else if (typeof this.model.text === 'string') {
162
- // 旧格式:字符串
154
+ // 旧格式:字符串
155
+ if (typeof this.model.text === 'string') {
163
156
  return this.model.text;
164
157
  }
165
158
  }
@@ -19,6 +19,9 @@ export declare class VideoElement extends ConditionalDisplayElement {
19
19
  private refreshTimer;
20
20
  private isFullscreen;
21
21
  private videoUrl;
22
+ private visibilityChangeHandler;
23
+ private timeUpdateWatchdog;
24
+ private lastTimeUpdate;
22
25
  constructor(element: HTMLElement, injector: Injector, permissionChecker: PermissionChecker, variableCommunicator: VariableCommunicator, variableStore: VariableStore, videoService: VideoService, guiSize: Size, svgRootClass: string, signalRAppId: string);
23
26
  dispose(): void;
24
27
  hide(): void;
@@ -27,5 +30,8 @@ export declare class VideoElement extends ConditionalDisplayElement {
27
30
  private initVideo;
28
31
  private addVideoAddressToolTip;
29
32
  private setAndroidVideo;
33
+ private initVisibilityHandler;
34
+ private startTimeUpdateWatchdog;
35
+ private clearTimeUpdateWatchdog;
30
36
  private setIosVideo;
31
37
  }
@@ -12,8 +12,10 @@ export class VideoElement extends ConditionalDisplayElement {
12
12
  this.svgRootClass = svgRootClass;
13
13
  this.videoId = '';
14
14
  this.isFullscreen = false;
15
+ this.lastTimeUpdate = 0;
15
16
  this.isMobileMode = DisplayMode.Mobile === injector.get(GlobalSettings).displayMode;
16
17
  this.localization = injector.get(LOCALIZATION);
18
+ this.initVisibilityHandler();
17
19
  this.init();
18
20
  }
19
21
  dispose() {
@@ -23,6 +25,10 @@ export class VideoElement extends ConditionalDisplayElement {
23
25
  $('div.' + this.svgRootClass + ' video').each(function () {
24
26
  $(this).remove();
25
27
  });
28
+ if (this.visibilityChangeHandler) {
29
+ document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
30
+ }
31
+ this.clearTimeUpdateWatchdog();
26
32
  }
27
33
  hide() {
28
34
  super.hide();
@@ -121,6 +127,7 @@ export class VideoElement extends ConditionalDisplayElement {
121
127
  this.videoPlayer.play();
122
128
  });
123
129
  }
130
+ this.startTimeUpdateWatchdog(videoId);
124
131
  }
125
132
  catch (err) {
126
133
  console.log(err);
@@ -206,6 +213,37 @@ export class VideoElement extends ConditionalDisplayElement {
206
213
  }
207
214
  });
208
215
  }
216
+ initVisibilityHandler() {
217
+ this.visibilityChangeHandler = () => {
218
+ if (!document.hidden && this.videoUrl && this.videoId) {
219
+ this.initVideo(this.videoUrl, this.videoId);
220
+ }
221
+ };
222
+ document.addEventListener('visibilitychange', this.visibilityChangeHandler);
223
+ }
224
+ startTimeUpdateWatchdog(videoId) {
225
+ this.clearTimeUpdateWatchdog();
226
+ this.lastTimeUpdate = Date.now();
227
+ const videoEl = document.getElementById(videoId);
228
+ if (videoEl && videoEl.tagName === 'VIDEO') {
229
+ videoEl.addEventListener('timeupdate', () => {
230
+ this.lastTimeUpdate = Date.now();
231
+ });
232
+ }
233
+ this.timeUpdateWatchdog = setInterval(() => {
234
+ if (document.hidden)
235
+ return;
236
+ if (Date.now() - this.lastTimeUpdate > 30000) {
237
+ this.initVideo(this.videoUrl, this.videoId);
238
+ }
239
+ }, 30000);
240
+ }
241
+ clearTimeUpdateWatchdog() {
242
+ if (this.timeUpdateWatchdog) {
243
+ clearInterval(this.timeUpdateWatchdog);
244
+ this.timeUpdateWatchdog = null;
245
+ }
246
+ }
209
247
  setIosVideo(videoUrl, videoId) {
210
248
  const video = $('#' + this.videoId);
211
249
  video.on('webkitendfullscreen', () => {
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"VideoElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-display-element","name":"ConditionalDisplayElement","line":15,"character":34},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":27,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":28,"character":18},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":29,"character":27},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":30,"character":30},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":31,"character":23},{"__symbolic":"reference","module":"../../service","name":"VideoService","line":32,"character":39},{"__symbolic":"reference","module":"../../model","name":"Size","line":33,"character":34},{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","name":"string"}]}],"dispose":[{"__symbolic":"method"}],"hide":[{"__symbolic":"method"}],"show":[{"__symbolic":"method"}],"init":[{"__symbolic":"method"}],"initVideo":[{"__symbolic":"method"}],"addVideoAddressToolTip":[{"__symbolic":"method"}],"setAndroidVideo":[{"__symbolic":"method"}],"setIosVideo":[{"__symbolic":"method"}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"VideoElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-display-element","name":"ConditionalDisplayElement","line":15,"character":34},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":30,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":31,"character":18},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":32,"character":27},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":33,"character":30},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":34,"character":23},{"__symbolic":"reference","module":"../../service","name":"VideoService","line":35,"character":39},{"__symbolic":"reference","module":"../../model","name":"Size","line":36,"character":34},{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","name":"string"}]}],"dispose":[{"__symbolic":"method"}],"hide":[{"__symbolic":"method"}],"show":[{"__symbolic":"method"}],"init":[{"__symbolic":"method"}],"initVideo":[{"__symbolic":"method"}],"addVideoAddressToolTip":[{"__symbolic":"method"}],"setAndroidVideo":[{"__symbolic":"method"}],"initVisibilityHandler":[{"__symbolic":"method"}],"startTimeUpdateWatchdog":[{"__symbolic":"method"}],"clearTimeUpdateWatchdog":[{"__symbolic":"method"}],"setIosVideo":[{"__symbolic":"method"}]}}}}]
@@ -24,6 +24,7 @@ export declare class ViewOperationElement extends ConditionalEnableElement {
24
24
  private readonly logger;
25
25
  private readonly viewService;
26
26
  private graphStateElement?;
27
+ private textElementModal?;
27
28
  private languageChangeSubscription?;
28
29
  private touchedScreenX;
29
30
  private touchedScreenY;
@@ -2,6 +2,7 @@ import { LOGGER_SERVICE_TOKEN } from '../../logger';
2
2
  import * as d3 from 'd3-selection';
3
3
  import { drag } from 'd3-drag';
4
4
  import { ViewOperationType } from '../../model';
5
+ import { TextElementModal } from '../shared/text/text-element';
5
6
  import { ConditionalEnableElement } from '../base/conditional-enable-element';
6
7
  import { GraphStateElement } from '../shared/graph/graph-state-element';
7
8
  import { AlertModalComponent } from '../../modal/alert/alert-modal.component';
@@ -33,12 +34,11 @@ export class ViewOperationElement extends ConditionalEnableElement {
33
34
  const height = this.model.size.height;
34
35
  this.initGraph(width, height);
35
36
  this.rootElement.append('rect').attr('id', 'StateFrame').attr('width', width).attr('height', height).attr('fill', 'transparent');
36
- // 初始化文本显示
37
- const $dateTimeText = this.$element.find('text').last();
38
- const fontStyle = this.model.label.font.fontStyle;
39
- $dateTimeText.css('font', fontStyle + ',msyh');
40
- // 设置初始文本内容(支持文本库)
41
- this.updateTextContent($dateTimeText);
37
+ // 移除模板中原有的 SVG <text> 元素,改用 TextElementModal(foreignObject)渲染,支持换行
38
+ this.$element.find('text').last().remove();
39
+ const font = Object.assign(Object.assign({}, this.model.label.font), { fontFamily: this.model.label.font.fontFamily || 'msyh' });
40
+ this.textElementModal = new TextElementModal(this.getDisplayText(), font, width, height);
41
+ this.$element.append(this.textElementModal.Element);
42
42
  this.switchToState(0);
43
43
  this.rootElement.on('mousedown', () => {
44
44
  if (!this.isInitialized) {
@@ -212,24 +212,23 @@ export class ViewOperationElement extends ConditionalEnableElement {
212
212
  subscribeLanguageChange() {
213
213
  if (this.guiContext && this.guiContext.languageChanged$) {
214
214
  this.languageChangeSubscription = this.guiContext.languageChanged$.subscribe(() => {
215
- // 更新文本内容
216
- const $dateTimeText = this.$element.find('text').last();
217
- this.updateTextContent($dateTimeText);
215
+ this.updateTextContent();
218
216
  });
219
217
  }
220
218
  }
221
219
  /**
222
220
  * 更新文本内容(支持文本库和语种切换)
223
221
  */
224
- updateTextContent($textElement) {
225
- const displayText = this.getDisplayText();
226
- $textElement.text(displayText);
222
+ updateTextContent() {
223
+ if (this.textElementModal) {
224
+ this.textElementModal.updateText(this.getDisplayText());
225
+ }
227
226
  }
228
227
  /**
229
228
  * 获取显示文本
230
229
  */
231
230
  getDisplayText() {
232
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
231
+ var _a, _b, _c, _d, _e, _f;
233
232
  // 检查是否使用文本库
234
233
  if (this.model.textLibrary && this.model.textLibrary.labelType === 'textLibrary') {
235
234
  const textLibraryId = this.model.textLibrary.selectedTextLibraryItem;
@@ -274,35 +273,30 @@ export class ViewOperationElement extends ConditionalEnableElement {
274
273
  return '';
275
274
  }
276
275
  // 处理自定义文本(支持多语种)
277
- if (this.model.label && this.model.label.content) {
278
- // 检查是否为多语种格式
279
- if (typeof this.model.label.content === 'object' && this.model.label.content.cultures) {
280
- // 新格式:多语种对象
281
- // 获取当前语种ID
282
- const currentLanguageId = (_j = (_h = (_g = this.guiContext) === null || _g === void 0 ? void 0 : _g.getCurrentLanguageId) === null || _h === void 0 ? void 0 : _h.call(_g)) !== null && _j !== void 0 ? _j : null;
283
- // 确定要使用的语种代码(culture)
284
- let targetLanguage;
285
- const defaultLanguage = ((_k = this.languageService) === null || _k === void 0 ? void 0 : _k.getDefaultLanguage()) || 'zh-CN';
276
+ if (this.model.label) {
277
+ // 获取目标语种(公共逻辑)
278
+ const getTargetLanguage = () => {
279
+ var _a, _b, _c, _d, _e, _f;
280
+ const currentLanguageId = (_c = (_b = (_a = this.guiContext) === null || _a === void 0 ? void 0 : _a.getCurrentLanguageId) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : null;
281
+ const defaultLanguage = ((_d = this.languageService) === null || _d === void 0 ? void 0 : _d.getDefaultLanguage()) || 'zh-CN';
286
282
  if (currentLanguageId === null || currentLanguageId === undefined) {
287
- // 设备未设置当前语种,使用默认语种
288
- targetLanguage = defaultLanguage;
289
- }
290
- else {
291
- // 设备已设置当前语种,获取对应的语种代码
292
- const currentLanguage = (_m = (_l = this.guiContext) === null || _l === void 0 ? void 0 : _l.getLanguageCultureById) === null || _m === void 0 ? void 0 : _m.call(_l, currentLanguageId);
293
- if (currentLanguage) {
294
- targetLanguage = currentLanguage;
295
- }
296
- else {
297
- targetLanguage = defaultLanguage;
298
- }
283
+ return defaultLanguage;
299
284
  }
300
- // toggle-view 找不到语种内容时默认为空字符串
301
- return this.model.label.content.cultures[targetLanguage] || '';
285
+ return ((_f = (_e = this.guiContext) === null || _e === void 0 ? void 0 : _e.getLanguageCultureById) === null || _f === void 0 ? void 0 : _f.call(_e, currentLanguageId)) || defaultLanguage;
286
+ };
287
+ // 新格式:cultures 在 label 顶层
288
+ if (this.model.label.cultures && typeof this.model.label.cultures === 'object') {
289
+ return this.model.label.cultures[getTargetLanguage()] || '';
302
290
  }
303
- else if (typeof this.model.label.content === 'string') {
291
+ if (this.model.label.content) {
292
+ // 中间格式(兼容):content 为 { cultures: {...} }
293
+ if (typeof this.model.label.content === 'object' && this.model.label.content.cultures) {
294
+ return this.model.label.content.cultures[getTargetLanguage()] || '';
295
+ }
304
296
  // 旧格式:字符串
305
- return this.model.label.content;
297
+ if (typeof this.model.label.content === 'string') {
298
+ return this.model.label.content;
299
+ }
306
300
  }
307
301
  }
308
302
  return '';
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"ViewOperationElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-enable-element","name":"ConditionalEnableElement","line":22,"character":42},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":34,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":34,"character":48},{"__symbolic":"reference","module":"ngx-bootstrap/modal","name":"BsModalService","line":35,"character":39},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":36,"character":30},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":37,"character":23},{"__symbolic":"reference","module":"../../config","name":"GraphStore","line":38,"character":37},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":39,"character":27},{"__symbolic":"reference","module":"../../service","name":"OperationRecordService","line":40,"character":49},{"__symbolic":"reference","module":"../../security","name":"SecurityChecker","line":41,"character":42},{"__symbolic":"reference","module":"../../localization","name":"Localization","line":42,"character":22},{"__symbolic":"reference","module":"../../view/popup-view.service","name":"PopupViewService","line":43,"character":43},{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","module":"@angular/core","name":"ElementRef","line":45,"character":29},{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","module":"../../service","name":"TextLibraryService","line":47,"character":46},{"__symbolic":"reference","module":"../../service","name":"LanguageService","line":48,"character":43},{"__symbolic":"reference","module":"../../gui/gui-context","name":"GuiContext","line":49,"character":38}]}],"initElement":[{"__symbolic":"method"}],"switchToState":[{"__symbolic":"method"}],"initGraph":[{"__symbolic":"method"}],"checkElementPassword":[{"__symbolic":"method"}],"executeViewOperation":[{"__symbolic":"method"}],"toggleView":[{"__symbolic":"method"}],"popView":[{"__symbolic":"method"}],"closeView":[{"__symbolic":"method"}],"moveView":[{"__symbolic":"method"}],"recordViewOperation":[{"__symbolic":"method"}],"subscribeLanguageChange":[{"__symbolic":"method"}],"updateTextContent":[{"__symbolic":"method"}],"getDisplayText":[{"__symbolic":"method"}],"dispose":[{"__symbolic":"method"}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"ViewOperationElement":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../base/conditional-enable-element","name":"ConditionalEnableElement","line":23,"character":42},"members":{"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"error","message":"Could not resolve type","line":36,"character":25,"context":{"typeName":"HTMLElement"}},{"__symbolic":"reference","module":"@angular/core","name":"Injector","line":36,"character":48},{"__symbolic":"reference","module":"ngx-bootstrap/modal","name":"BsModalService","line":37,"character":39},{"__symbolic":"reference","module":"../../communication","name":"VariableCommunicator","line":38,"character":30},{"__symbolic":"reference","module":"../../config","name":"VariableStore","line":39,"character":23},{"__symbolic":"reference","module":"../../config","name":"GraphStore","line":40,"character":37},{"__symbolic":"reference","module":"../../service","name":"PermissionChecker","line":41,"character":27},{"__symbolic":"reference","module":"../../service","name":"OperationRecordService","line":42,"character":49},{"__symbolic":"reference","module":"../../security","name":"SecurityChecker","line":43,"character":42},{"__symbolic":"reference","module":"../../localization","name":"Localization","line":44,"character":22},{"__symbolic":"reference","module":"../../view/popup-view.service","name":"PopupViewService","line":45,"character":43},{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","module":"@angular/core","name":"ElementRef","line":47,"character":29},{"__symbolic":"reference","name":"string"},{"__symbolic":"reference","module":"../../service","name":"TextLibraryService","line":49,"character":46},{"__symbolic":"reference","module":"../../service","name":"LanguageService","line":50,"character":43},{"__symbolic":"reference","module":"../../gui/gui-context","name":"GuiContext","line":51,"character":38}]}],"initElement":[{"__symbolic":"method"}],"switchToState":[{"__symbolic":"method"}],"initGraph":[{"__symbolic":"method"}],"checkElementPassword":[{"__symbolic":"method"}],"executeViewOperation":[{"__symbolic":"method"}],"toggleView":[{"__symbolic":"method"}],"popView":[{"__symbolic":"method"}],"closeView":[{"__symbolic":"method"}],"moveView":[{"__symbolic":"method"}],"recordViewOperation":[{"__symbolic":"method"}],"subscribeLanguageChange":[{"__symbolic":"method"}],"updateTextContent":[{"__symbolic":"method"}],"getDisplayText":[{"__symbolic":"method"}],"dispose":[{"__symbolic":"method"}]}}}}]
@@ -2,4 +2,7 @@ import { Font } from './font';
2
2
  export interface Text {
3
3
  content: string;
4
4
  font: Font;
5
+ cultures?: {
6
+ [languageCode: string]: string;
7
+ };
5
8
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "main": "bundles/fc-gui.umd.js",
3
- "version": "3.0.0-alpha.141",
3
+ "version": "3.0.0-alpha.143",
4
4
  "module": "public_api.js",
5
5
  "typings": "public_api.d.ts",
6
6
  "license": "UNLICENSED",