@skyfox2000/webui 1.5.12 → 1.5.13
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.
- package/lib/assets/modules/{baseLayout-CRSIlLKU.js → baseLayout-RbSDyZ-4.js} +3 -3
- package/lib/assets/modules/{file-upload-CrA5-gqr.js → file-upload-CBaDznKX.js} +1 -1
- package/lib/assets/modules/{index-Doi0zREW.js → index-BfdvI5gq.js} +2 -2
- package/lib/assets/modules/{index-CA_H2eOk.js → index-D6F_78jm.js} +1 -1
- package/lib/assets/modules/{index-CW7dVG4Z.js → index-DAtpSCmI.js} +2 -2
- package/lib/assets/modules/{menuTabs-DRoP9rnS.js → menuTabs-B2-8ewds.js} +3 -3
- package/lib/assets/modules/{toolIcon-CghIoh0a.js → toolIcon-BDDaZK7c.js} +1 -1
- package/lib/assets/modules/{upload-template-D6r6X3vP.js → upload-template-CfrQxGl8.js} +891 -876
- package/lib/assets/modules/{uploadList-CIGuBEpz.js → uploadList-CaL2Nk6S.js} +4 -4
- package/lib/es/AceEditor/index.js +3 -3
- package/lib/es/BasicLayout/index.js +2 -2
- package/lib/es/Error403/index.js +1 -1
- package/lib/es/Error404/index.js +1 -1
- package/lib/es/ExcelForm/index.js +4 -4
- package/lib/es/MenuLayout/index.js +2 -2
- package/lib/es/TemplateFile/index.js +4 -4
- package/lib/es/UploadForm/index.js +4 -4
- package/lib/locales/default.d.ts +123 -123
- package/lib/webui.es.js +13 -13
- package/package.json +1 -1
- package/src/components/layout/header/index.vue +1 -1
- package/src/locales/default.ts +126 -126
- package/src/locales/en-US.json +8 -2
- package/src/locales/index.ts +60 -40
package/src/locales/default.ts
CHANGED
|
@@ -228,134 +228,134 @@ export const defaultLocale = {
|
|
|
228
228
|
"pleaseInput": "请输入{0}"
|
|
229
229
|
}
|
|
230
230
|
},
|
|
231
|
+
},
|
|
231
232
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
},
|
|
241
|
-
"hostInfo": {
|
|
242
|
-
"loading": "站点配置加载中……"
|
|
243
|
-
},
|
|
244
|
-
"appInfo": {
|
|
245
|
-
"loadAppListFailed": "加载应用列表失败"
|
|
246
|
-
}
|
|
233
|
+
// 状态存储相关
|
|
234
|
+
"stores": {
|
|
235
|
+
"userInfo": {
|
|
236
|
+
"tokenParseFailed": "Token解析失败",
|
|
237
|
+
"exiting": "正在退出...",
|
|
238
|
+
"logoutSuccess": "已退出登录",
|
|
239
|
+
"authInfoFailed": "获取授权信息失败",
|
|
240
|
+
"userInfoParseFailed": "用户信息解析失败"
|
|
247
241
|
},
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
},
|
|
274
|
-
"
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
"
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
"
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
"
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
"
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
"
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
"
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
"
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
"
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
242
|
+
"hostInfo": {
|
|
243
|
+
"loading": "站点配置加载中……"
|
|
244
|
+
},
|
|
245
|
+
"appInfo": {
|
|
246
|
+
"loadAppListFailed": "加载应用列表失败"
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
|
|
250
|
+
// 工具函数相关
|
|
251
|
+
"utils": {
|
|
252
|
+
"exportTable": {
|
|
253
|
+
"exportFailed": "导出失败",
|
|
254
|
+
"fileExportFailed": "文件导出失败,请稍后重试"
|
|
255
|
+
},
|
|
256
|
+
"formValidate": {
|
|
257
|
+
"required": "不能为空",
|
|
258
|
+
"numberType": "必须是数字",
|
|
259
|
+
"enum": "必须是{enum}中的一个",
|
|
260
|
+
"stringLen": "长度必须为{len}",
|
|
261
|
+
"stringMin": "长度不能小于{min}",
|
|
262
|
+
"stringMax": "长度不能大于{max}",
|
|
263
|
+
"stringRange": "长度必须在{min}和{max}之间",
|
|
264
|
+
"numberLen": "必须为{len}",
|
|
265
|
+
"numberMin": "不能小于{min}",
|
|
266
|
+
"numberMax": "不能大于{max}",
|
|
267
|
+
"numberRange": "必须在{min}和{max}之间",
|
|
268
|
+
"arrayLen": "长度必须为{len}",
|
|
269
|
+
"arrayMin": "长度不能小于{min}",
|
|
270
|
+
"arrayMax": "长度不能大于{max}",
|
|
271
|
+
"arrayRange": "长度必须在{min}和{max}之间",
|
|
272
|
+
"formatValidationError": "格式化验证消息出错",
|
|
273
|
+
"processValidationError": "处理验证规则出错"
|
|
274
|
+
},
|
|
275
|
+
"fileUpload": {
|
|
276
|
+
"pleaseSelectFile": "请选择上传的文件!",
|
|
277
|
+
"allUploadSuccess": "全部文件上传成功!",
|
|
278
|
+
"partialUploadFailed": "上传结束,部分文件上传失败!",
|
|
279
|
+
"saveUploadSuccess": "保存上传成功的文件!",
|
|
280
|
+
"partialUploadFailedCancel": "上传结束,部分文件上传失败,取消保存!",
|
|
281
|
+
"allUploadFailed": "上传结束,所有文件上传失败!",
|
|
282
|
+
"fileUploadSuccess": "文件上传成功!",
|
|
283
|
+
"fileUploadFailed": "上传文件失败!"
|
|
284
|
+
},
|
|
285
|
+
"data": {
|
|
286
|
+
"executeSuccess": "执行成功!",
|
|
287
|
+
"noDataToSave": "错误!无保存数据!",
|
|
288
|
+
"saveSuccess": "保存成功!",
|
|
289
|
+
"conditionalDeleteForbidden": "错误!禁止无条件删除数据!",
|
|
290
|
+
"deleteSuccess": "删除成功!",
|
|
291
|
+
"urlNotSet": "URL未设置: {urlKey}"
|
|
292
|
+
},
|
|
293
|
+
"download": {
|
|
294
|
+
"downloadFailed": "下载文件失败!",
|
|
295
|
+
"fileDownloadFailed": "文件下载失败,请稍后重试",
|
|
296
|
+
"fileTypeNotSupported": "文件类型不支持预览",
|
|
297
|
+
"filePreviewFailed": "文件预览失败!"
|
|
298
|
+
},
|
|
299
|
+
"formExcel": {
|
|
300
|
+
"excelNoSheets": "Excel文件不包含工作表",
|
|
301
|
+
"excelInsufficientData": "Excel文件不包含足够的数据",
|
|
302
|
+
"validationError": "验证表格数据时发生错误",
|
|
303
|
+
"missingDuplicateFields": "表头缺少重复检测所需字段",
|
|
304
|
+
"fileNotExcel": "上传的文件不是Excel文件",
|
|
305
|
+
"processFailed": "Excel文件处理失败",
|
|
306
|
+
"validationSuccess": "数据验证成功",
|
|
307
|
+
"duplicateValidationPending": "待验证重复数据",
|
|
308
|
+
"validationFailed": "数据验证失败",
|
|
309
|
+
"validationPassed": "数据验证通过",
|
|
310
|
+
"duplicateDetected": "检测到重复数据",
|
|
311
|
+
"duplicateCheckPassed": "重复性检验通过"
|
|
312
|
+
},
|
|
313
|
+
"options": {
|
|
314
|
+
"notConfigured": "未配置选项数据!",
|
|
315
|
+
"outFieldsFormatError": "outFields 格式错误:{sourceKey},必须是 ${index} 或者 ${index}.${key}"
|
|
316
|
+
},
|
|
317
|
+
"excelPreview": {
|
|
318
|
+
"previewUrlNotConfigured": "预览URL或Excel控制器未配置",
|
|
319
|
+
"fileLoadFailed": "文件加载失败",
|
|
320
|
+
"csvProcessingFailed": "CSV格式处理失败",
|
|
321
|
+
"previewFile": "预览文件",
|
|
322
|
+
"previewFileXlsx": "预览文件.xlsx",
|
|
323
|
+
"previewFileCsv": "preview.csv",
|
|
324
|
+
"unsupportedRawFormat": "不支持的原始文件格式",
|
|
325
|
+
"unsupportedFileFormat": "不支持的文件格式",
|
|
326
|
+
"dataEmpty": "数据为空",
|
|
327
|
+
"excelProcessingFailed": "Excel处理失败"
|
|
328
|
+
},
|
|
329
|
+
"tools": {
|
|
330
|
+
"noClickHandler": "未配置点击处理事件!",
|
|
331
|
+
"refreshTable": "刷新表格",
|
|
332
|
+
"expandSearch": "展开搜索栏",
|
|
333
|
+
"collapseSearch": "折叠搜索栏",
|
|
334
|
+
"rowHeight": "行高调整",
|
|
335
|
+
"templateManagement": "模板管理",
|
|
336
|
+
"showCheckbox": "显示多选框",
|
|
337
|
+
"hideCheckbox": "隐藏多选框",
|
|
338
|
+
"expandRows": "展开记录行",
|
|
339
|
+
"collapseRows": "折叠记录行",
|
|
340
|
+
"exportExcel": "导出Excel",
|
|
341
|
+
"exportAllRecords": "全部记录",
|
|
342
|
+
"exportSelectedRecords": "选中的记录",
|
|
343
|
+
"exportPDF": "导出PDF",
|
|
344
|
+
"tableHeaderSettings": "表头设置",
|
|
345
|
+
"setFullscreen": "设置全屏",
|
|
346
|
+
"exitFullscreen": "取消全屏"
|
|
347
|
+
},
|
|
348
|
+
"iconLoader": {
|
|
349
|
+
"networkError": "网络异常,无法加载图标库!"
|
|
350
|
+
},
|
|
351
|
+
"formCsv": {
|
|
352
|
+
"csvToExcelFailed": "CSV转Excel失败",
|
|
353
|
+
"csvProcessFailed": "CSV文件处理失败",
|
|
354
|
+
"unknownError": "未知错误"
|
|
355
|
+
},
|
|
356
|
+
"microOpenapis": {
|
|
357
|
+
"interfaceNotConfigured": "未配置{method}接口!",
|
|
358
|
+
"apiCallTimeout": "API调用超时: {method}"
|
|
359
359
|
}
|
|
360
360
|
}
|
|
361
361
|
}
|
package/src/locales/en-US.json
CHANGED
|
@@ -254,7 +254,8 @@
|
|
|
254
254
|
"noDataToSave": "Error! No data to save!",
|
|
255
255
|
"saveSuccess": "Save successful!",
|
|
256
256
|
"conditionalDeleteForbidden": "Error! Unconditional data deletion is forbidden!",
|
|
257
|
-
"deleteSuccess": "Delete successful!"
|
|
257
|
+
"deleteSuccess": "Delete successful!",
|
|
258
|
+
"urlNotSet": "URL not set: {urlKey}"
|
|
258
259
|
},
|
|
259
260
|
"download": {
|
|
260
261
|
"downloadFailed": "File download failed!",
|
|
@@ -277,7 +278,8 @@
|
|
|
277
278
|
"duplicateCheckPassed": "Duplicate check passed"
|
|
278
279
|
},
|
|
279
280
|
"options": {
|
|
280
|
-
"notConfigured": "Options data not configured!"
|
|
281
|
+
"notConfigured": "Options data not configured!",
|
|
282
|
+
"outFieldsFormatError": "outFields format error: {sourceKey}, must be ${index} or ${index}.${key}"
|
|
281
283
|
},
|
|
282
284
|
"form": {
|
|
283
285
|
"submitValidationFailed": "Validation failed when submitting form!",
|
|
@@ -314,6 +316,10 @@
|
|
|
314
316
|
"csvToExcelFailed": "CSV to Excel conversion failed",
|
|
315
317
|
"csvProcessFailed": "CSV file processing failed",
|
|
316
318
|
"unknownError": "Unknown error"
|
|
319
|
+
},
|
|
320
|
+
"microOpenapis": {
|
|
321
|
+
"interfaceNotConfigured": "{method} interface not configured!",
|
|
322
|
+
"apiCallTimeout": "API call timeout: {method}"
|
|
317
323
|
}
|
|
318
324
|
}
|
|
319
325
|
}
|
package/src/locales/index.ts
CHANGED
|
@@ -89,7 +89,11 @@ async function loadLocaleFromCloud(locale: string): Promise<LocaleMessages> {
|
|
|
89
89
|
const cloudMessages = await response.json();
|
|
90
90
|
return cloudMessages;
|
|
91
91
|
} catch (error) {
|
|
92
|
-
|
|
92
|
+
// 只有在网络错误等真正异常情况下才记录错误(但仍不显示给用户)
|
|
93
|
+
// fetch的网络错误通常是TypeError,而HTTP错误状态码不会触发catch
|
|
94
|
+
if (error instanceof TypeError) {
|
|
95
|
+
console.error(`Error loading locale ${locale}:`, error);
|
|
96
|
+
}
|
|
93
97
|
// 如果加载失败,返回空对象
|
|
94
98
|
return {};
|
|
95
99
|
}
|
|
@@ -201,55 +205,71 @@ export function getI18nMessages(
|
|
|
201
205
|
return loadedMessages;
|
|
202
206
|
}
|
|
203
207
|
|
|
208
|
+
/**
|
|
209
|
+
* 优化的深拷贝函数 - 避免JSON.parse/stringify的性能问题
|
|
210
|
+
*/
|
|
211
|
+
function deepClone<T>(obj: T): T {
|
|
212
|
+
if (obj === null || typeof obj !== 'object') {
|
|
213
|
+
return obj;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (obj instanceof Date) {
|
|
217
|
+
return new Date(obj.getTime()) as unknown as T;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (obj instanceof Array) {
|
|
221
|
+
return obj.map(item => deepClone(item)) as unknown as T;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (typeof obj === 'object') {
|
|
225
|
+
const cloned = {} as T;
|
|
226
|
+
for (const key in obj) {
|
|
227
|
+
if (obj.hasOwnProperty(key)) {
|
|
228
|
+
cloned[key] = deepClone(obj[key]);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return cloned;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return obj;
|
|
235
|
+
}
|
|
236
|
+
|
|
204
237
|
/**
|
|
205
238
|
* 加载语言包 - 使用缓存优先策略
|
|
206
|
-
* 实现合并逻辑:
|
|
207
|
-
*
|
|
239
|
+
* 实现合并逻辑:defaultLocale作为基础,缓存和云端进行合并
|
|
240
|
+
* 确保异步加载完成后再继续执行
|
|
208
241
|
*/
|
|
209
242
|
async function loadLocale(locale: string): Promise<void> {
|
|
210
|
-
//
|
|
243
|
+
// 1. 首先加载defaultLocale作为基础
|
|
244
|
+
const baseMessages = deepClone(defaultLocale);
|
|
245
|
+
|
|
246
|
+
// 2. 获取本地缓存(如果有)
|
|
211
247
|
const cachedMessages = getCachedLocale(locale);
|
|
212
248
|
|
|
213
|
-
//
|
|
214
|
-
let
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
249
|
+
// 3. 同步加载云端语言包(必须等待完成)
|
|
250
|
+
let cloudMessages: LocaleMessages = {};
|
|
251
|
+
try {
|
|
252
|
+
cloudMessages = await loadLocaleFromCloud(locale);
|
|
253
|
+
} catch (error) {
|
|
254
|
+
// 加载失败时使用空对象,不报错
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// 4. 合并策略:defaultLocale + 缓存 + 云端
|
|
258
|
+
// 优先级:云端 > 缓存 > defaultLocale
|
|
259
|
+
let finalMessages = baseMessages;
|
|
260
|
+
|
|
261
|
+
if (cachedMessages && Object.keys(cachedMessages).length > 0) {
|
|
262
|
+
finalMessages = deepMerge(finalMessages, cachedMessages);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (cloudMessages && Object.keys(cloudMessages).length > 0) {
|
|
266
|
+
finalMessages = deepMerge(finalMessages, cloudMessages);
|
|
229
267
|
}
|
|
230
268
|
|
|
231
|
-
//
|
|
269
|
+
// 5. 设置到内存和缓存
|
|
232
270
|
loadedMessages[locale] = finalMessages;
|
|
233
271
|
i18n.global.setLocaleMessage(locale, finalMessages);
|
|
234
272
|
cacheLocale(locale, finalMessages);
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
// 强制加载更新:无论是否有缓存,都强制加载最新语言包
|
|
238
|
-
try {
|
|
239
|
-
// 强制加载最新语言包并直接更新缓存和内存
|
|
240
|
-
const freshMessages = await loadLocaleFromCloud(locale);
|
|
241
|
-
|
|
242
|
-
// 合并逻辑:低defaultLocale + loadLocaleFromCloud高,确保创建新对象
|
|
243
|
-
const updatedMessages = deepMerge(JSON.parse(JSON.stringify(defaultLocale)), freshMessages);
|
|
244
|
-
|
|
245
|
-
loadedMessages[locale] = updatedMessages;
|
|
246
|
-
i18n.global.setLocaleMessage(locale, updatedMessages);
|
|
247
|
-
cacheLocale(locale, updatedMessages);
|
|
248
|
-
|
|
249
|
-
} catch (error) {
|
|
250
|
-
// 加载失败时跳过,不报错
|
|
251
|
-
|
|
252
|
-
}
|
|
253
273
|
}
|
|
254
274
|
/**
|
|
255
275
|
* 初始化语言 - 使用缓存优先+异步后台加载策略
|
|
@@ -327,7 +347,7 @@ export function $t(key: string, params?: Record<string, any>): string {
|
|
|
327
347
|
const result = i18n.global.t(key, params);
|
|
328
348
|
// 如果返回的是翻译键本身,说明没有找到翻译
|
|
329
349
|
if (result === key) {
|
|
330
|
-
|
|
350
|
+
|
|
331
351
|
|
|
332
352
|
// 检查当前messages是否为空
|
|
333
353
|
const currentMessages = i18n.global.getLocaleMessage(i18n.global.locale.value);
|