yh-i18n 2.2.23 → 2.3.1
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/excelTool.ts +22 -35
- package/index.d.ts +2 -2
- package/index.js +21 -6
- package/lang/baseEnUS.js +1 -0
- package/lang/baseFa.js +27 -0
- package/lang/baseTh.js +1 -0
- package/lang/baseTr.js +1 -0
- package/lang/baseVi.js +1 -0
- package/lang/baseZhCn.js +1 -0
- package/lang/fa.js +310 -0
- package/list.vue +104 -113
- package/package.json +2 -2
package/excelTool.ts
CHANGED
|
@@ -5,33 +5,6 @@ import http from '@/libs/api.request';
|
|
|
5
5
|
import {useI18nStore} from './index';
|
|
6
6
|
|
|
7
7
|
const verificationCode = 'lkyhtranslateexcel';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* 解析翻译内容,将 JSON 字符串解析并合并到 item 对象中
|
|
11
|
-
* @param item 翻译项对象
|
|
12
|
-
* @param localKeys 本地语言键列表
|
|
13
|
-
* @returns 处理后的翻译项对象
|
|
14
|
-
*/
|
|
15
|
-
export function parseTranslateContent(item: any, localKeys: string[]): any {
|
|
16
|
-
try {
|
|
17
|
-
let content = JSON.parse(item.content);
|
|
18
|
-
let keys = Object.keys(content);
|
|
19
|
-
|
|
20
|
-
keys.forEach((key) => {
|
|
21
|
-
let val = content[key];
|
|
22
|
-
item[key] = val;
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
localKeys.forEach((k) => {
|
|
26
|
-
if (!keys.includes(k)) {
|
|
27
|
-
item[k] = '';
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
} catch (error) {
|
|
31
|
-
console.error('解析翻译内容失败:', error);
|
|
32
|
-
}
|
|
33
|
-
return item;
|
|
34
|
-
}
|
|
35
8
|
export async function exportExcel(total) {
|
|
36
9
|
const loading = ElLoading.service({
|
|
37
10
|
lock: true,
|
|
@@ -51,7 +24,23 @@ export async function exportExcel(total) {
|
|
|
51
24
|
.then((res) => {
|
|
52
25
|
let localKeys = i18nStore.localList.map((item) => item.value);
|
|
53
26
|
let {records} = res.data.data;
|
|
54
|
-
records = records.map((item) =>
|
|
27
|
+
records = records.map((item) => {
|
|
28
|
+
try {
|
|
29
|
+
let content = JSON.parse(item.content);
|
|
30
|
+
let keys = Object.keys(content);
|
|
31
|
+
|
|
32
|
+
keys.forEach((key) => {
|
|
33
|
+
let val = content[key];
|
|
34
|
+
item[key] = val;
|
|
35
|
+
});
|
|
36
|
+
localKeys.forEach((k) => {
|
|
37
|
+
if (!keys.includes(k)) {
|
|
38
|
+
item[k] = '';
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
} catch (error) {}
|
|
42
|
+
return item;
|
|
43
|
+
});
|
|
55
44
|
return records;
|
|
56
45
|
});
|
|
57
46
|
loading.setText('正在序列化表格数据……');
|
|
@@ -74,6 +63,7 @@ export async function exportExcel(total) {
|
|
|
74
63
|
th: '泰语',
|
|
75
64
|
vi: '越南语',
|
|
76
65
|
tr: '土耳其语',
|
|
66
|
+
fa_IR: '波斯语',
|
|
77
67
|
};
|
|
78
68
|
Config.i18nList.forEach((item) => {
|
|
79
69
|
columns.push({
|
|
@@ -88,8 +78,8 @@ export async function exportExcel(total) {
|
|
|
88
78
|
sheet.addRow(title);
|
|
89
79
|
sheet.addRows(
|
|
90
80
|
records.map((item) => {
|
|
91
|
-
let {
|
|
92
|
-
let row = [
|
|
81
|
+
let {adTranslateId, key} = item;
|
|
82
|
+
let row = [adTranslateId, key];
|
|
93
83
|
Config.i18nList.forEach((valKey) => {
|
|
94
84
|
row.push(item[valKey]);
|
|
95
85
|
});
|
|
@@ -212,7 +202,6 @@ export async function importExcel(e, getDataList) {
|
|
|
212
202
|
message: '您选择的文件不是系统导出的文件',
|
|
213
203
|
type: 'warning',
|
|
214
204
|
});
|
|
215
|
-
e.target.value = '';
|
|
216
205
|
return false;
|
|
217
206
|
}
|
|
218
207
|
const loading = ElLoading.service({
|
|
@@ -227,14 +216,14 @@ export async function importExcel(e, getDataList) {
|
|
|
227
216
|
let dataList: any[] = [];
|
|
228
217
|
sheet.getRows(2, len)?.forEach((row) => {
|
|
229
218
|
let id = row.getCell(1).value;
|
|
230
|
-
let
|
|
219
|
+
let key = row.getCell(2).value;
|
|
231
220
|
let content: any = {};
|
|
232
221
|
Config.i18nList.forEach((item, index) => {
|
|
233
222
|
content[item] = row.getCell(index + 3).value;
|
|
234
223
|
});
|
|
235
224
|
dataList.push({
|
|
236
225
|
id,
|
|
237
|
-
|
|
226
|
+
key,
|
|
238
227
|
content: JSON.stringify(content),
|
|
239
228
|
});
|
|
240
229
|
});
|
|
@@ -262,8 +251,6 @@ export async function importExcel(e, getDataList) {
|
|
|
262
251
|
getDataList();
|
|
263
252
|
} catch (error) {
|
|
264
253
|
ElMessage.error('导入保存翻译数据遇到错误:', error.message);
|
|
265
|
-
} finally {
|
|
266
|
-
e.target.value = '';
|
|
267
254
|
}
|
|
268
255
|
}
|
|
269
256
|
}
|
package/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ import {StoreDefinition} from 'pinia';
|
|
|
9
9
|
* vi 越南语(越南)
|
|
10
10
|
* tr 土耳其语(土耳其)
|
|
11
11
|
*/
|
|
12
|
-
type I18nList = 'zh_CN' | 'en_US' | 'th' | 'vi' | 'tr';
|
|
12
|
+
type I18nList = 'zh_CN' | 'en_US' | 'th' | 'vi' | 'tr' | 'fa_IR';
|
|
13
13
|
|
|
14
14
|
declare global {
|
|
15
15
|
interface Window {
|
|
@@ -21,7 +21,7 @@ declare global {
|
|
|
21
21
|
export const i18n: I18n;
|
|
22
22
|
|
|
23
23
|
/** 自定义的翻译函数,这个函数包装了 t 函数,在翻译的前提下,可以帮忙手机键 */
|
|
24
|
-
export const ct: (key: string, args
|
|
24
|
+
export const ct: (key: string, args: any[]) => void;
|
|
25
25
|
|
|
26
26
|
/** 国际化相关 Pinia Store 实例 */
|
|
27
27
|
export const useI18nStore: StoreDefinition;
|
package/index.js
CHANGED
|
@@ -10,12 +10,14 @@ import enUSBase from "./lang/baseEnUS.js";
|
|
|
10
10
|
import thBase from "./lang/baseTh.js";
|
|
11
11
|
import viBase from "./lang/baseVi.js";
|
|
12
12
|
import trBase from "./lang/baseTr.js";
|
|
13
|
+
import faBase from "./lang/baseFa.js"
|
|
13
14
|
// vxe table
|
|
14
15
|
import zhCNVXETable from "./lang/zh.js";
|
|
15
16
|
import enUSVXETable from "./lang/en.js";
|
|
16
17
|
import thVXETable from "./lang/th.js";
|
|
17
18
|
import viVXETable from "./lang/vi.js";
|
|
18
19
|
import trVXETable from "./lang/tr.js";
|
|
20
|
+
import faVXETable from "./lang/fa.js"
|
|
19
21
|
|
|
20
22
|
// element-plus
|
|
21
23
|
import el_zh_CN from "element-plus/dist/locale/zh-cn.mjs";
|
|
@@ -23,6 +25,7 @@ import el_en_US from "element-plus/dist/locale/en.mjs";
|
|
|
23
25
|
import el_th from "element-plus/dist/locale/th.mjs";
|
|
24
26
|
import el_vi from "element-plus/dist/locale/vi.mjs";
|
|
25
27
|
import el_tr from "element-plus/dist/locale/tr.mjs";
|
|
28
|
+
import el_fa from "element-plus/dist/locale/fa.mjs";
|
|
26
29
|
|
|
27
30
|
// 自动根据浏览器系统语言设置语言
|
|
28
31
|
let navLang = navigator.language.replace("-", "_");
|
|
@@ -47,15 +50,15 @@ Object.keys(zhCNBase).forEach((key) => {
|
|
|
47
50
|
|
|
48
51
|
const unHandle = [];
|
|
49
52
|
|
|
50
|
-
function addTranslate (
|
|
51
|
-
if (
|
|
53
|
+
function addTranslate (key) {
|
|
54
|
+
if (key && key.indexOf("vxe") === -1) {
|
|
52
55
|
try {
|
|
53
56
|
axios.request({
|
|
54
57
|
url: "/translate/insert",
|
|
55
58
|
method: "POST",
|
|
56
59
|
data: {
|
|
57
|
-
|
|
58
|
-
content: `{"zh_CN":"${
|
|
60
|
+
key,
|
|
61
|
+
content: `{"zh_CN":"${key}"}`,
|
|
59
62
|
},
|
|
60
63
|
});
|
|
61
64
|
} catch (error) {
|
|
@@ -84,7 +87,7 @@ function recursionAddTranslate () {
|
|
|
84
87
|
}
|
|
85
88
|
}
|
|
86
89
|
|
|
87
|
-
export const ct = (key, args
|
|
90
|
+
export const ct = (key, args) => {
|
|
88
91
|
if (key && window.translateReady && window.translateCollect) {
|
|
89
92
|
// 将 键的处理全部放入队列中,避免挤兑正常逻辑的运算资源
|
|
90
93
|
if (!keySet.has(key) && !unHandle.includes(key)) {
|
|
@@ -119,6 +122,7 @@ export const useI18nStore = defineStore("i18nStore", () => {
|
|
|
119
122
|
th: "ไทย",
|
|
120
123
|
vi: "Việt nam",
|
|
121
124
|
tr: "Türkçe",
|
|
125
|
+
fa_IR: "فارسی",
|
|
122
126
|
});
|
|
123
127
|
|
|
124
128
|
const localList = reactive([]);
|
|
@@ -155,6 +159,12 @@ export const useI18nStore = defineStore("i18nStore", () => {
|
|
|
155
159
|
value: "tr",
|
|
156
160
|
});
|
|
157
161
|
break;
|
|
162
|
+
case "fa_IR":
|
|
163
|
+
localList.push({
|
|
164
|
+
label: "فارسی",
|
|
165
|
+
value: "fa_IR",
|
|
166
|
+
});
|
|
167
|
+
break;
|
|
158
168
|
}
|
|
159
169
|
});
|
|
160
170
|
}
|
|
@@ -175,6 +185,8 @@ export const useI18nStore = defineStore("i18nStore", () => {
|
|
|
175
185
|
return el_vi;
|
|
176
186
|
case "tr":
|
|
177
187
|
return el_tr;
|
|
188
|
+
case "fa_IR":
|
|
189
|
+
return el_fa;
|
|
178
190
|
}
|
|
179
191
|
});
|
|
180
192
|
|
|
@@ -197,6 +209,7 @@ async function getRemoteMessage (list) {
|
|
|
197
209
|
th: {},
|
|
198
210
|
vi: {},
|
|
199
211
|
tr: {},
|
|
212
|
+
fa_IR: {},
|
|
200
213
|
};
|
|
201
214
|
let {
|
|
202
215
|
data: { data },
|
|
@@ -257,7 +270,9 @@ function createLocalMessage (list) {
|
|
|
257
270
|
case "tr":
|
|
258
271
|
messages["tr"] = Object.assign(trBase, trVXETable);
|
|
259
272
|
break;
|
|
260
|
-
|
|
273
|
+
case "fa_IR":
|
|
274
|
+
messages["fa_IR"] = Object.assign(faBase, faVXETable);
|
|
275
|
+
break;
|
|
261
276
|
default:
|
|
262
277
|
break;
|
|
263
278
|
}
|
package/lang/baseEnUS.js
CHANGED
package/lang/baseFa.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
翻译键名: "کلید ترجمه",
|
|
3
|
+
翻译管理: "مدیریت ترجمه",
|
|
4
|
+
键入以筛选键名: "برای فیلتر کردن کلید تایپ کنید",
|
|
5
|
+
搜索: "جستجو",
|
|
6
|
+
新增: "جدید",
|
|
7
|
+
批量删除: "حذف گروهی",
|
|
8
|
+
重置: "بازنشانی",
|
|
9
|
+
编辑: "ویرایش",
|
|
10
|
+
删除: "حذف",
|
|
11
|
+
操作: "عملیات",
|
|
12
|
+
导出: "صادرات",
|
|
13
|
+
导入: "واردات",
|
|
14
|
+
翻译键值: "مقدار ترجمه",
|
|
15
|
+
新增翻译: "افزودن ترجمه",
|
|
16
|
+
编辑翻译: "ویرایش ترجمه",
|
|
17
|
+
请输入翻译键值: "لطفاً مقدار ترجمه را وارد کنید",
|
|
18
|
+
上一个: "قبلی",
|
|
19
|
+
下一个: "بعدی",
|
|
20
|
+
取消: "لغو",
|
|
21
|
+
中文简体: "چینی ساده شده",
|
|
22
|
+
English: "انگلیسی",
|
|
23
|
+
ไทย: "تایلندی",
|
|
24
|
+
"Việt nam": "ویتنامی",
|
|
25
|
+
Türkçe: "ترکی",
|
|
26
|
+
"فارسی": "فارسی",
|
|
27
|
+
};
|
package/lang/baseTh.js
CHANGED
package/lang/baseTr.js
CHANGED
package/lang/baseVi.js
CHANGED
package/lang/baseZhCn.js
CHANGED
package/lang/fa.js
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
vxe: {
|
|
3
|
+
loading: {
|
|
4
|
+
text: "در حال بارگذاری...",
|
|
5
|
+
},
|
|
6
|
+
error: {
|
|
7
|
+
groupFixed: "اگر از سرستون گروهی استفاده میشود، ستون ثابت باید به صورت گروهی تنظیم شود",
|
|
8
|
+
groupMouseRange: 'سرستون گروهی نمیتواند با "{0}" همزمان استفاده شود، که ممکن است باعث خطا شود',
|
|
9
|
+
groupTag: 'سرستون گروهی باید از "{0}" به جای "{1}" استفاده کند، که ممکن است باعث خطا شود',
|
|
10
|
+
scrollErrProp: 'پس از فعال کردن اسکرول مجازی، پارامتر "{0}" پشتیبانی نمیشود',
|
|
11
|
+
errConflicts: 'پارامتر "{0}" با "{1}" تداخل دارد',
|
|
12
|
+
unableInsert: "نمیتوان در موقعیت مشخصی درج کرد، لطفاً بررسی کنید که آیا پارامترها صحیح هستند",
|
|
13
|
+
useErr: 'هنگام نصب ماژول "{0}" خطایی رخ داد، ممکن است ترتیب نادرست باشد، ماژولهای وابسته باید قبل از Table نصب شوند',
|
|
14
|
+
barUnableLink: "نوار ابزار نمیتواند به جدول متصل شود",
|
|
15
|
+
expandContent: 'اسلات ردیف باز شده باید "content" باشد، لطفاً بررسی کنید که آیا صحیح است',
|
|
16
|
+
reqModule: 'ماژول "{0}" وجود ندارد',
|
|
17
|
+
reqProp: 'پارامتر ضروری "{0}" وجود ندارد، که ممکن است باعث خطا شود',
|
|
18
|
+
emptyProp: 'پارامتر "{0}" نمیتواند خالی باشد',
|
|
19
|
+
errProp: 'پارامتر "{0}" پشتیبانی نمیشود، ممکن است "{1}" باشد',
|
|
20
|
+
colRepet: 'column.{0}="{1}" تکرار شده است، که ممکن است باعث عدم کارکرد برخی توابع شود',
|
|
21
|
+
notFunc: 'متد "{0}" وجود ندارد',
|
|
22
|
+
notSlot: 'اسلات "{0}" وجود ندارد',
|
|
23
|
+
noTree: 'ساختار درختی "{0}" را پشتیبانی نمیکند',
|
|
24
|
+
notProp: 'پارامتر "{0}" پشتیبانی نمیشود',
|
|
25
|
+
coverProp: 'پارامتر "{1}" از "{0}" بازنویسی شده است، که ممکن است باعث خطا شود',
|
|
26
|
+
delFunc: 'متد "{0}" منسوخ شده است، لطفاً از "{1}" استفاده کنید',
|
|
27
|
+
delProp: 'پارامتر "{0}" منسوخ شده است، لطفاً از "{1}" استفاده کنید',
|
|
28
|
+
delEvent: 'رویداد "{0}" منسوخ شده است، لطفاً از "{1}" استفاده کنید',
|
|
29
|
+
removeProp: 'پارامتر "{0}" منسوخ شده و توصیه نمیشود,这可能会导致出现错误',
|
|
30
|
+
errFormat: 'محتوای قالببندی سراسری باید با "VXETable.formats" تعریف شود، روش اتصال "formatter={0}" دیگر توصیه نمیشود',
|
|
31
|
+
notType: 'نوع فایل "{0}" پشتیبانی نمیشود',
|
|
32
|
+
notExp: "این مرورگر از قابلیت وارد کردن/صادر کردن پشتیبانی نمیکند",
|
|
33
|
+
impFields: "وارد کردن ناموفق بود، لطفاً بررسی کنید که نام فیلدها و فرمت داده صحیح هستند",
|
|
34
|
+
treeNotImp: "جدول درختی از وارد کردن پشتیبانی نمیکند",
|
|
35
|
+
},
|
|
36
|
+
renderer: {
|
|
37
|
+
search: "جستجو",
|
|
38
|
+
cases: {
|
|
39
|
+
equal: "مساوی",
|
|
40
|
+
unequal: "نامساوی",
|
|
41
|
+
gt: "بزرگتر از",
|
|
42
|
+
ge: "بزرگتر یا مساوی",
|
|
43
|
+
lt: "کوچکتر از",
|
|
44
|
+
le: "کوچکتر یا مساوی",
|
|
45
|
+
begin: "شروع با",
|
|
46
|
+
notbegin: "شروع نشود با",
|
|
47
|
+
endin: "پایان با",
|
|
48
|
+
notendin: "پایان نشود با",
|
|
49
|
+
include: "شامل",
|
|
50
|
+
exclude: "شامل نشود",
|
|
51
|
+
between: "بین",
|
|
52
|
+
custom: "فیلتر سفارشی",
|
|
53
|
+
insensitive: "بدون حساسیت به حروف",
|
|
54
|
+
isSensitive: "حساس به حروف",
|
|
55
|
+
},
|
|
56
|
+
combination: {
|
|
57
|
+
menus: {
|
|
58
|
+
clearSort: "پاک کردن مرتبسازی",
|
|
59
|
+
sortAsc: "صعودی",
|
|
60
|
+
sortDesc: "نزولی",
|
|
61
|
+
fixedColumn: "ستون ثابت",
|
|
62
|
+
fixedGroup: "گروه ثابت",
|
|
63
|
+
cancelFixed: "لغو ثابت",
|
|
64
|
+
fixedLeft: "ثابت چپ",
|
|
65
|
+
fixedRight: "ثابت راست",
|
|
66
|
+
clearFilter: "پاک کردن فیلتر",
|
|
67
|
+
textOption: "فیلتر متنی",
|
|
68
|
+
numberOption: "فیلتر عددی",
|
|
69
|
+
},
|
|
70
|
+
popup: {
|
|
71
|
+
title: "روش فیلتر سفارشی",
|
|
72
|
+
currColumnTitle: "ستون فعلی:",
|
|
73
|
+
and: "و",
|
|
74
|
+
or: "یا",
|
|
75
|
+
describeHtml: "از ? برای نمایندگی یک کاراکتر استفاده کنید<br/>از * برای نمایندگی چندین کاراکتر دلخواه استفاده کنید",
|
|
76
|
+
},
|
|
77
|
+
empty: "(خالی)",
|
|
78
|
+
notData: "موردی یافت نشد",
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
pro: {
|
|
82
|
+
area: {
|
|
83
|
+
mergeErr: "نمیتوان این عملیات را روی سلول ادغام شده انجام داد",
|
|
84
|
+
multiErr: "نمیتوان این عملیات را روی ناحیه انتخاب چندگانه انجام داد",
|
|
85
|
+
extendErr: "اگر ناحیه گسترش یافته شامل سلولهای ادغام شده باشد، تمام سلولهای ادغام شده باید اندازه یکسانی داشته باشند",
|
|
86
|
+
pasteMultiErr: "نمیتوان چسباند، برای انجام این عملیات ناحیه کپی شده و ناحیه چسبانده شده باید اندازه یکسانی داشته باشند",
|
|
87
|
+
},
|
|
88
|
+
fnr: {
|
|
89
|
+
title: "جستجو و جایگزینی",
|
|
90
|
+
findLabel: "جستجو",
|
|
91
|
+
replaceLabel: "جایگزینی",
|
|
92
|
+
findTitle: "جستجوی محتوا:",
|
|
93
|
+
replaceTitle: "جایگزینی با:",
|
|
94
|
+
tabs: {
|
|
95
|
+
find: "جستجو",
|
|
96
|
+
replace: "جایگزینی",
|
|
97
|
+
},
|
|
98
|
+
filter: {
|
|
99
|
+
re: "عبارت منظم",
|
|
100
|
+
whole: "تطبیق کل کلمه",
|
|
101
|
+
sensitive: "حساس به حروف",
|
|
102
|
+
},
|
|
103
|
+
btns: {
|
|
104
|
+
findNext: "جستجوی بعدی",
|
|
105
|
+
findAll: "جستجوی همه",
|
|
106
|
+
replace: "جایگزینی",
|
|
107
|
+
replaceAll: "جایگزینی همه",
|
|
108
|
+
cancel: "لغو",
|
|
109
|
+
},
|
|
110
|
+
header: {
|
|
111
|
+
seq: "#",
|
|
112
|
+
cell: "سلول",
|
|
113
|
+
value: "مقدار",
|
|
114
|
+
},
|
|
115
|
+
empty: "(تهی)",
|
|
116
|
+
reError: "عبارت منظم نامعتبر",
|
|
117
|
+
recordCount: "{0} سلول یافت شد",
|
|
118
|
+
notCell: "سلول منطبقی یافت نشد",
|
|
119
|
+
replaceSuccess: "با موفقیت {0} سلول جایگزین شد",
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
table: {
|
|
123
|
+
emptyText: "دادهای موجود نیست",
|
|
124
|
+
allTitle: "انتخاب همه/لغو",
|
|
125
|
+
seqTitle: "#",
|
|
126
|
+
confirmFilter: "فیلتر",
|
|
127
|
+
resetFilter: "بازنشانی",
|
|
128
|
+
allFilter: "همه",
|
|
129
|
+
sortAsc: "صعودی:کمترین به بیشترین",
|
|
130
|
+
sortDesc: "نزولی:بیشترین به کمترین",
|
|
131
|
+
filter: "فعال کردن فیلتر برای ستون انتخاب شده",
|
|
132
|
+
impSuccess: "با موفقیت {0} رکورد وارد شد",
|
|
133
|
+
expLoading: "در حال صدور...",
|
|
134
|
+
expSuccess: "صدور با موفقیت انجام شد",
|
|
135
|
+
expFilename: "صدور_{0}",
|
|
136
|
+
expOriginFilename: "صدور_منبع_{0}",
|
|
137
|
+
customTitle: "تنظیمات ستون",
|
|
138
|
+
customAll: "همه",
|
|
139
|
+
customConfirm: "تایید",
|
|
140
|
+
customRestore: "بازیابی",
|
|
141
|
+
},
|
|
142
|
+
grid: {
|
|
143
|
+
selectOneRecord: "لطفاً حداقل یک رکورد انتخاب کنید!",
|
|
144
|
+
deleteSelectRecord: "آیا مطمئن هستید که میخواهید رکوردهای انتخاب شده را حذف کنید؟",
|
|
145
|
+
removeSelectRecord: "آیا مطمئن هستید که میخواهید رکوردهای انتخاب شده را جابجا کنید؟",
|
|
146
|
+
dataUnchanged: "دادهها تغییر نکردهاند!",
|
|
147
|
+
delSuccess: "رکوردهای انتخاب شده با موفقیت حذف شدند!",
|
|
148
|
+
saveSuccess: "ذخیره با موفقیت انجام شد!",
|
|
149
|
+
operError: "خطایی رخ داد، عملیات ناموفق بود!",
|
|
150
|
+
},
|
|
151
|
+
select: {
|
|
152
|
+
search: "جستجو",
|
|
153
|
+
loadingText: "در حال بارگذاری",
|
|
154
|
+
emptyText: "دادهای موجود نیست",
|
|
155
|
+
},
|
|
156
|
+
pager: {
|
|
157
|
+
goto: "برو به",
|
|
158
|
+
pagesize: "{0} مورد/صفحه",
|
|
159
|
+
total: "مجموع {0} رکورد",
|
|
160
|
+
pageClassifier: "صفحه",
|
|
161
|
+
prevPage: "صفحه قبل",
|
|
162
|
+
nextPage: "صفحه بعد",
|
|
163
|
+
prevJump: "پرش به بالا",
|
|
164
|
+
nextJump: "پرش به پایین",
|
|
165
|
+
},
|
|
166
|
+
alert: {
|
|
167
|
+
title: "پیام هشدار",
|
|
168
|
+
},
|
|
169
|
+
button: {
|
|
170
|
+
confirm: "تایید",
|
|
171
|
+
cancel: "لغو",
|
|
172
|
+
},
|
|
173
|
+
import: {
|
|
174
|
+
modes: {
|
|
175
|
+
covering: "بازنویسی",
|
|
176
|
+
insert: "درج",
|
|
177
|
+
},
|
|
178
|
+
impTitle: "وارد کردن دادهها",
|
|
179
|
+
impFile: "نام فایل",
|
|
180
|
+
impSelect: "انتخاب فایل",
|
|
181
|
+
impType: "نوع فایل",
|
|
182
|
+
impOpts: "تنظیمات پارامتر",
|
|
183
|
+
impConfirm: "وارد کردن",
|
|
184
|
+
impCancel: "لغو",
|
|
185
|
+
},
|
|
186
|
+
export: {
|
|
187
|
+
types: {
|
|
188
|
+
csv: "CSV (جدا شده با کاما)(*.csv)",
|
|
189
|
+
html: "صفحه وب(*.html)",
|
|
190
|
+
xml: "داده XML(*.xml)",
|
|
191
|
+
txt: "فایل متنی (جدا شده با تب)(*.txt)",
|
|
192
|
+
xls: "کتاب کار Excel 97-2003(*.xls)",
|
|
193
|
+
xlsx: "کتاب کار Excel(*.xlsx)",
|
|
194
|
+
pdf: "PDF (*.pdf)",
|
|
195
|
+
},
|
|
196
|
+
modes: {
|
|
197
|
+
current: "دادههای فعلی (دادههای صفحه فعلی)",
|
|
198
|
+
selected: "دادههای انتخاب شده (دادههای انتخاب شده در صفحه فعلی)",
|
|
199
|
+
all: "تمام دادهها (شامل دادههای تمام صفحات)",
|
|
200
|
+
},
|
|
201
|
+
printTitle: "چاپ دادهها",
|
|
202
|
+
expTitle: "صدور دادهها",
|
|
203
|
+
expName: "نام فایل",
|
|
204
|
+
expNamePlaceholder: "لطفاً نام فایل را وارد کنید",
|
|
205
|
+
expSheetName: "عنوان",
|
|
206
|
+
expSheetNamePlaceholder: "لطفاً عنوان را وارد کنید",
|
|
207
|
+
expType: "نوع ذخیره",
|
|
208
|
+
expMode: "انتخاب دادهها",
|
|
209
|
+
expCurrentColumn: "تمام فیلدها",
|
|
210
|
+
expColumn: "انتخاب فیلدها",
|
|
211
|
+
expOpts: "تنظیمات پارامتر",
|
|
212
|
+
expOptHeader: "سرستون",
|
|
213
|
+
expHeaderTitle: "آیا سرستون نیاز است",
|
|
214
|
+
expOptFooter: "پاصفحه",
|
|
215
|
+
expFooterTitle: "آیا پاصفحه نیاز است",
|
|
216
|
+
expOptColgroup: "سرستون گروهی",
|
|
217
|
+
expColgroupTitle: "در صورت وجود، از سرستون با ساختار گروهی پشتیبانی میکند",
|
|
218
|
+
expOptMerge: "ادغام",
|
|
219
|
+
expMergeTitle: "در صورت وجود، از سلولهای با ساختار ادغام شده پشتیبانی میکند",
|
|
220
|
+
expOptAllExpand: "باز کردن سطوح",
|
|
221
|
+
expAllExpandTitle: "در صورت وجود، از باز کردن تمام دادههای با ساختار سلسله مراتبی پشتیبانی میکند",
|
|
222
|
+
expOptUseStyle: "سبک",
|
|
223
|
+
expUseStyleTitle: "در صورت وجود، از سلولهای دارای سبک پشتیبانی میکند",
|
|
224
|
+
expOptOriginal: "دادههای منبع",
|
|
225
|
+
expOriginalTitle: "اگر دادههای منبع باشند، از وارد کردن به جدول پشتیبانی میکنند",
|
|
226
|
+
expPrint: "چاپ",
|
|
227
|
+
expConfirm: "صدور",
|
|
228
|
+
expCancel: "لغو",
|
|
229
|
+
},
|
|
230
|
+
modal: {
|
|
231
|
+
zoomIn: "بیشینهسازی",
|
|
232
|
+
zoomOut: "بازیابی",
|
|
233
|
+
close: "بستن",
|
|
234
|
+
},
|
|
235
|
+
form: {
|
|
236
|
+
folding: "جمع کردن",
|
|
237
|
+
unfolding: "باز کردن",
|
|
238
|
+
},
|
|
239
|
+
toolbar: {
|
|
240
|
+
import: "وارد کردن",
|
|
241
|
+
export: "صدور",
|
|
242
|
+
print: "چاپ",
|
|
243
|
+
refresh: "بازنشانی",
|
|
244
|
+
zoomIn: "تمام صفحه",
|
|
245
|
+
zoomOut: "بازیابی",
|
|
246
|
+
custom: "تنظیمات ستون",
|
|
247
|
+
customAll: "همه",
|
|
248
|
+
customConfirm: "تایید",
|
|
249
|
+
customRestore: "بازیابی",
|
|
250
|
+
},
|
|
251
|
+
input: {
|
|
252
|
+
date: {
|
|
253
|
+
m1: "۰۱ ژانویه",
|
|
254
|
+
m2: "۰۲ فوریه",
|
|
255
|
+
m3: "۰۳ مارس",
|
|
256
|
+
m4: "۰۴ آوریل",
|
|
257
|
+
m5: "۰۵ مه",
|
|
258
|
+
m6: "۰۶ ژوئن",
|
|
259
|
+
m7: "۰۷ ژوئیه",
|
|
260
|
+
m8: "۰۸ اوت",
|
|
261
|
+
m9: "۰۹ سپتامبر",
|
|
262
|
+
m10: "۱۰ اکتبر",
|
|
263
|
+
m11: "۱۱ نوامبر",
|
|
264
|
+
m12: "۱۲ دسامبر",
|
|
265
|
+
quarterLabel: "{0} سال",
|
|
266
|
+
monthLabel: "{0} سال",
|
|
267
|
+
dayLabel: "{0} سال {1}",
|
|
268
|
+
labelFormat: {
|
|
269
|
+
date: "yyyy-MM-dd",
|
|
270
|
+
time: "HH:mm:ss",
|
|
271
|
+
datetime: "yyyy-MM-dd HH:mm:ss",
|
|
272
|
+
week: "هفته WW از سال yyyy",
|
|
273
|
+
month: "yyyy-MM",
|
|
274
|
+
quarter: "فصل q از سال yyyy",
|
|
275
|
+
year: "yyyy",
|
|
276
|
+
},
|
|
277
|
+
weeks: {
|
|
278
|
+
w: "هفته",
|
|
279
|
+
w0: "یکشنبه",
|
|
280
|
+
w1: "دوشنبه",
|
|
281
|
+
w2: "سهشنبه",
|
|
282
|
+
w3: "چهارشنبه",
|
|
283
|
+
w4: "پنجشنبه",
|
|
284
|
+
w5: "جمعه",
|
|
285
|
+
w6: "شنبه",
|
|
286
|
+
},
|
|
287
|
+
months: {
|
|
288
|
+
m0: "ژانویه",
|
|
289
|
+
m1: "فوریه",
|
|
290
|
+
m2: "مارس",
|
|
291
|
+
m3: "آوریل",
|
|
292
|
+
m4: "مه",
|
|
293
|
+
m5: "ژوئن",
|
|
294
|
+
m6: "ژوئیه",
|
|
295
|
+
m7: "اوت",
|
|
296
|
+
m8: "سپتامبر",
|
|
297
|
+
m9: "اکتبر",
|
|
298
|
+
m10: "نوامبر",
|
|
299
|
+
m11: "دسامبر",
|
|
300
|
+
},
|
|
301
|
+
quarters: {
|
|
302
|
+
q1: "فصل اول",
|
|
303
|
+
q2: "فصل دوم",
|
|
304
|
+
q3: "فصل سوم",
|
|
305
|
+
q4: "فصل چهارم",
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
},
|
|
310
|
+
};
|
package/list.vue
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<el-form inline>
|
|
6
6
|
<el-form-item :label="ct('翻译键名')">
|
|
7
7
|
<el-input
|
|
8
|
-
v-model="listForm.
|
|
8
|
+
v-model="listForm.key"
|
|
9
9
|
@keyup.enter.stop.prevent="getDataList(true)"
|
|
10
10
|
:placeholder="ct('键入以筛选键名')"></el-input>
|
|
11
11
|
</el-form-item>
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
ref="i18nList"
|
|
49
49
|
stripe
|
|
50
50
|
:data="dataList"
|
|
51
|
-
row-key="
|
|
51
|
+
row-key="adTranslateId"
|
|
52
52
|
@row-click="rowClickHandler">
|
|
53
53
|
<el-table-column
|
|
54
54
|
type="selection"
|
|
@@ -76,13 +76,13 @@
|
|
|
76
76
|
<el-button
|
|
77
77
|
link
|
|
78
78
|
type="danger"
|
|
79
|
-
@click="delOne(row.
|
|
79
|
+
@click="delOne(row.adTranslateId)">
|
|
80
80
|
{{ ct('删除') }}
|
|
81
81
|
</el-button>
|
|
82
82
|
</template>
|
|
83
83
|
</el-table-column>
|
|
84
84
|
<el-table-column
|
|
85
|
-
prop="
|
|
85
|
+
prop="key"
|
|
86
86
|
min-width="140"
|
|
87
87
|
fixed="left"
|
|
88
88
|
:label="ct('翻译键名')"></el-table-column>
|
|
@@ -105,9 +105,8 @@
|
|
|
105
105
|
class="form-drawer"
|
|
106
106
|
v-model="formShow"
|
|
107
107
|
@close="cancelForm"
|
|
108
|
-
:close-on-click-modal="false"
|
|
109
108
|
draggable
|
|
110
|
-
:title="formData.
|
|
109
|
+
:title="formData.adTranslateId ? ct('编辑翻译') : ct('新增翻译')">
|
|
111
110
|
<vxe-form
|
|
112
111
|
title-align="right"
|
|
113
112
|
title-width="100px"
|
|
@@ -115,14 +114,14 @@
|
|
|
115
114
|
title-colon
|
|
116
115
|
:data="formData"
|
|
117
116
|
:items="formItems"
|
|
118
|
-
:rules="
|
|
117
|
+
:rules="fromRules"></vxe-form>
|
|
119
118
|
<template #footer>
|
|
120
119
|
<div class="yh-i18n-form-actions">
|
|
121
120
|
<el-button
|
|
122
121
|
@click="prevOne"
|
|
123
122
|
text
|
|
124
123
|
:disabled="!isNaN(formDataIndex) && formDataIndex <= 0">
|
|
125
|
-
{{ ct('上一个') }}
|
|
124
|
+
{{ ct('上一个') }}(←)
|
|
126
125
|
</el-button>
|
|
127
126
|
<el-button
|
|
128
127
|
type="primary"
|
|
@@ -133,44 +132,25 @@
|
|
|
133
132
|
<el-button
|
|
134
133
|
type="primary"
|
|
135
134
|
@click="saveOne">
|
|
136
|
-
{{ ct('保存') }}
|
|
135
|
+
{{ ct('保存') }}
|
|
137
136
|
</el-button>
|
|
138
137
|
<el-button
|
|
139
138
|
@click="nextOne"
|
|
140
139
|
text
|
|
141
|
-
:disabled="!isNaN(formDataIndex) && formDataIndex >= dataList.
|
|
142
|
-
{{ ct('下一个') }}
|
|
140
|
+
:disabled="!isNaN(formDataIndex) && formDataIndex >= dataList.leng - 1">
|
|
141
|
+
{{ ct('下一个') }}(→)
|
|
143
142
|
</el-button>
|
|
144
143
|
</div>
|
|
145
144
|
</template>
|
|
146
145
|
</el-dialog>
|
|
147
146
|
</template>
|
|
148
147
|
<script setup lang="ts">
|
|
149
|
-
import {reactive, ref, onMounted,
|
|
148
|
+
import {reactive, ref, onMounted, watch} from 'vue';
|
|
150
149
|
import {ElLoadingService, ElMessage, ElMessageBox} from 'element-plus';
|
|
151
150
|
import {useI18nStore, ct} from 'yh-i18n';
|
|
152
151
|
import http from '@/libs/api.request';
|
|
153
152
|
import {VxeFormInstance, VxeFormPropTypes} from 'vxe-table';
|
|
154
|
-
import {exportExcel, importExcel
|
|
155
|
-
|
|
156
|
-
interface TranslateItem {
|
|
157
|
-
id?: string;
|
|
158
|
-
name: string;
|
|
159
|
-
content: string;
|
|
160
|
-
[key: string]: any;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
interface ListColumn {
|
|
164
|
-
field: string;
|
|
165
|
-
title: string;
|
|
166
|
-
minWidth: string;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
interface SaveData {
|
|
170
|
-
name: string;
|
|
171
|
-
content: Record<string, string> | string;
|
|
172
|
-
id?: string;
|
|
173
|
-
}
|
|
153
|
+
import {exportExcel, importExcel} from './excelTool';
|
|
174
154
|
const i18nStore = useI18nStore();
|
|
175
155
|
const vxeFormRef = ref<VxeFormInstance>();
|
|
176
156
|
|
|
@@ -180,15 +160,15 @@ const deleteUrl = '/translate/deleteTranslate';
|
|
|
180
160
|
|
|
181
161
|
const i18nList = ref();
|
|
182
162
|
const listForm = reactive({
|
|
183
|
-
|
|
163
|
+
key: '',
|
|
184
164
|
pageNum: 1,
|
|
185
165
|
pageSize: 10,
|
|
186
166
|
total: 0,
|
|
187
167
|
});
|
|
188
|
-
const listColumns = reactive<
|
|
189
|
-
const dataList = ref<
|
|
168
|
+
const listColumns = reactive<any>([]);
|
|
169
|
+
const dataList = ref<any>([]);
|
|
190
170
|
function getDataList(isReset = false) {
|
|
191
|
-
let {
|
|
171
|
+
let {key, pageNum, pageSize} = listForm;
|
|
192
172
|
if (isReset) {
|
|
193
173
|
pageNum = 1;
|
|
194
174
|
}
|
|
@@ -200,7 +180,7 @@ function getDataList(isReset = false) {
|
|
|
200
180
|
url: '/translate/select',
|
|
201
181
|
method: 'post',
|
|
202
182
|
data: {
|
|
203
|
-
|
|
183
|
+
key,
|
|
204
184
|
pageNum,
|
|
205
185
|
pageSize,
|
|
206
186
|
},
|
|
@@ -208,14 +188,26 @@ function getDataList(isReset = false) {
|
|
|
208
188
|
.then((res) => {
|
|
209
189
|
let localKeys = i18nStore.localList.map((item) => item.value);
|
|
210
190
|
let {records, total} = res.data.data;
|
|
211
|
-
records = records.map((item) =>
|
|
191
|
+
records = records.map((item) => {
|
|
192
|
+
try {
|
|
193
|
+
let content = JSON.parse(item.content);
|
|
194
|
+
let keys = Object.keys(content);
|
|
195
|
+
|
|
196
|
+
keys.forEach((key) => {
|
|
197
|
+
let val = content[key];
|
|
198
|
+
item[key] = val;
|
|
199
|
+
});
|
|
200
|
+
localKeys.forEach((k) => {
|
|
201
|
+
if (!keys.includes(k)) {
|
|
202
|
+
item[k] = '';
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
} catch (error) {}
|
|
206
|
+
return item;
|
|
207
|
+
});
|
|
212
208
|
dataList.value = records;
|
|
213
209
|
listForm.total = total;
|
|
214
210
|
})
|
|
215
|
-
.catch((error) => {
|
|
216
|
-
ElMessage.error('获取数据失败');
|
|
217
|
-
console.error('获取列表数据失败:', error);
|
|
218
|
-
})
|
|
219
211
|
.finally(() => {
|
|
220
212
|
loading.close();
|
|
221
213
|
});
|
|
@@ -239,25 +231,22 @@ function rowClickHandler(row) {
|
|
|
239
231
|
}
|
|
240
232
|
|
|
241
233
|
function resetList() {
|
|
242
|
-
listForm.
|
|
234
|
+
listForm.key = '';
|
|
243
235
|
listForm.pageNum = 1;
|
|
244
236
|
listForm.total = 0;
|
|
245
237
|
getDataList();
|
|
246
238
|
}
|
|
247
239
|
|
|
248
240
|
const langList = Object.keys(i18nStore.langList);
|
|
249
|
-
const formDataIndex = ref
|
|
250
|
-
const formData = reactive<
|
|
251
|
-
name: '',
|
|
252
|
-
content: '',
|
|
253
|
-
});
|
|
241
|
+
const formDataIndex = ref();
|
|
242
|
+
const formData = reactive<any>({});
|
|
254
243
|
const formShow = ref(false);
|
|
255
|
-
|
|
244
|
+
let inputs: HTMLInputElement[] = [];
|
|
256
245
|
function cancelForm() {
|
|
257
246
|
vxeFormRef?.value?.reset();
|
|
258
247
|
vxeFormRef?.value?.clearValidate();
|
|
259
248
|
formDataIndex.value = void 0;
|
|
260
|
-
formData.id =
|
|
249
|
+
formData.id = null;
|
|
261
250
|
formShow.value = false;
|
|
262
251
|
}
|
|
263
252
|
|
|
@@ -266,7 +255,7 @@ function addOne() {
|
|
|
266
255
|
}
|
|
267
256
|
|
|
268
257
|
function prevOne() {
|
|
269
|
-
if (formDataIndex.value
|
|
258
|
+
if (formDataIndex.value > 0) {
|
|
270
259
|
let index = formDataIndex.value - 1;
|
|
271
260
|
let item = dataList.value[index];
|
|
272
261
|
editOne(item, index);
|
|
@@ -275,13 +264,6 @@ function prevOne() {
|
|
|
275
264
|
|
|
276
265
|
function editOne(item, index) {
|
|
277
266
|
formDataIndex.value = index;
|
|
278
|
-
// 先清空表单数据,除了 id
|
|
279
|
-
for (const key in formData) {
|
|
280
|
-
if (key !== 'id') {
|
|
281
|
-
delete formData[key];
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
// 然后将新项目的数据复制到表单
|
|
285
267
|
for (const key in item) {
|
|
286
268
|
if (Object.prototype.hasOwnProperty.call(item, key)) {
|
|
287
269
|
const val = item[key];
|
|
@@ -296,7 +278,7 @@ function editOne(item, index) {
|
|
|
296
278
|
}
|
|
297
279
|
|
|
298
280
|
function nextOne() {
|
|
299
|
-
if (formDataIndex.value
|
|
281
|
+
if (formDataIndex.value < dataList.value.length - 1) {
|
|
300
282
|
let index = formDataIndex.value + 1;
|
|
301
283
|
let item = dataList.value[index];
|
|
302
284
|
editOne(item, index);
|
|
@@ -304,18 +286,18 @@ function nextOne() {
|
|
|
304
286
|
}
|
|
305
287
|
|
|
306
288
|
function saveOne() {
|
|
307
|
-
let isAdd =
|
|
289
|
+
let isAdd = !!formData.adTranslateId;
|
|
308
290
|
let url = updateUrl;
|
|
309
291
|
vxeFormRef?.value?.validate().then((errMap) => {
|
|
310
292
|
if (!errMap) {
|
|
311
|
-
let data:
|
|
312
|
-
|
|
293
|
+
let data: any = {
|
|
294
|
+
key: formData.key,
|
|
313
295
|
content: {},
|
|
314
296
|
};
|
|
315
297
|
if (isAdd) {
|
|
316
298
|
url = insertUrl;
|
|
317
299
|
} else {
|
|
318
|
-
data.id = formData.
|
|
300
|
+
data.id = formData.adTranslateId;
|
|
319
301
|
}
|
|
320
302
|
for (const key in formData) {
|
|
321
303
|
if (key !== 'key' && langList.includes(key)) {
|
|
@@ -333,16 +315,13 @@ function saveOne() {
|
|
|
333
315
|
.then((res) => {
|
|
334
316
|
if (res?.data?.status === 200) {
|
|
335
317
|
ElMessage.success(res.data.msg);
|
|
336
|
-
if (isAdd) {
|
|
337
|
-
|
|
338
|
-
|
|
318
|
+
if (!isAdd) {
|
|
319
|
+
dataList.value[formDataIndex.value] = {
|
|
320
|
+
...formData,
|
|
321
|
+
};
|
|
322
|
+
nextOne();
|
|
339
323
|
} else {
|
|
340
|
-
|
|
341
|
-
dataList.value[formDataIndex.value] = {
|
|
342
|
-
...formData,
|
|
343
|
-
};
|
|
344
|
-
nextOne();
|
|
345
|
-
}
|
|
324
|
+
cancelForm();
|
|
346
325
|
}
|
|
347
326
|
} else {
|
|
348
327
|
ElMessage.error(res.data.msg);
|
|
@@ -375,8 +354,7 @@ function delOne(id) {
|
|
|
375
354
|
|
|
376
355
|
function delMore() {
|
|
377
356
|
ElMessageBox.confirm('确认删除选中的翻译记录吗?').then(async () => {
|
|
378
|
-
|
|
379
|
-
const ids = selectedRows?.map((row) => row.id) || [];
|
|
357
|
+
let ids = i18nList.value?.getSelectionRows().map((row) => row.adTranslateId);
|
|
380
358
|
if (ids && ids.length) {
|
|
381
359
|
let len = ids.length;
|
|
382
360
|
let loading = ElLoadingService({
|
|
@@ -385,21 +363,15 @@ function delMore() {
|
|
|
385
363
|
for (let i = 0; i < ids.length; i++) {
|
|
386
364
|
const id = ids[i];
|
|
387
365
|
loading.setText(`正在删除... ${i + 1}/${len}`);
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
});
|
|
396
|
-
} catch (error) {
|
|
397
|
-
ElMessage.error(`删除第 ${i + 1} 条记录失败`);
|
|
398
|
-
console.error(`删除第 ${i + 1} 条记录失败:`, error);
|
|
399
|
-
}
|
|
366
|
+
await http.request({
|
|
367
|
+
url: deleteUrl,
|
|
368
|
+
method: 'POST',
|
|
369
|
+
data: {
|
|
370
|
+
id,
|
|
371
|
+
},
|
|
372
|
+
});
|
|
400
373
|
}
|
|
401
374
|
loading.close();
|
|
402
|
-
ElMessage.success(`删除完成,共 ${len} 条记录`);
|
|
403
375
|
getDataList();
|
|
404
376
|
}
|
|
405
377
|
});
|
|
@@ -407,7 +379,7 @@ function delMore() {
|
|
|
407
379
|
|
|
408
380
|
const formItems = reactive<VxeFormPropTypes.Items>([
|
|
409
381
|
{
|
|
410
|
-
field: '
|
|
382
|
+
field: 'key',
|
|
411
383
|
span: 24,
|
|
412
384
|
title: '翻译键值',
|
|
413
385
|
itemRender: {
|
|
@@ -417,8 +389,8 @@ const formItems = reactive<VxeFormPropTypes.Items>([
|
|
|
417
389
|
},
|
|
418
390
|
]);
|
|
419
391
|
|
|
420
|
-
const
|
|
421
|
-
|
|
392
|
+
const fromRules = reactive<VxeFormPropTypes.Rules>({
|
|
393
|
+
key: [{required: true, type: 'string', message: '请输入翻译键值'}],
|
|
422
394
|
});
|
|
423
395
|
|
|
424
396
|
let needInit = true;
|
|
@@ -451,32 +423,51 @@ watch(
|
|
|
451
423
|
}
|
|
452
424
|
);
|
|
453
425
|
|
|
454
|
-
const handleKeydown = (e: KeyboardEvent) => {
|
|
455
|
-
let {key, ctrlKey, altKey} = e;
|
|
456
|
-
if (key === 's' && ctrlKey) {
|
|
457
|
-
e.preventDefault();
|
|
458
|
-
e.stopPropagation();
|
|
459
|
-
saveOne();
|
|
460
|
-
}
|
|
461
|
-
if (key === 'ArrowRight' && (ctrlKey || altKey)) {
|
|
462
|
-
e.preventDefault();
|
|
463
|
-
e.stopPropagation();
|
|
464
|
-
nextOne();
|
|
465
|
-
}
|
|
466
|
-
if (key === 'ArrowLeft' && (ctrlKey || altKey)) {
|
|
467
|
-
e.preventDefault();
|
|
468
|
-
e.stopPropagation();
|
|
469
|
-
prevOne();
|
|
470
|
-
}
|
|
471
|
-
};
|
|
472
|
-
|
|
473
426
|
onMounted(() => {
|
|
474
427
|
getDataList();
|
|
475
|
-
window.addEventListener('keydown',
|
|
476
|
-
}
|
|
428
|
+
window.addEventListener('keydown', (e) => {
|
|
429
|
+
let {key, ctrlKey, altKey} = e;
|
|
430
|
+
if (key === 's' && ctrlKey) {
|
|
431
|
+
e.preventDefault();
|
|
432
|
+
e.stopPropagation();
|
|
433
|
+
saveOne();
|
|
434
|
+
}
|
|
435
|
+
if (key === 'ArrowRight' && (ctrlKey || altKey)) {
|
|
436
|
+
e.preventDefault();
|
|
437
|
+
e.stopPropagation();
|
|
438
|
+
nextOne();
|
|
439
|
+
}
|
|
440
|
+
if (key === 'ArrowLeft' && (ctrlKey || altKey)) {
|
|
441
|
+
e.preventDefault();
|
|
442
|
+
e.stopPropagation();
|
|
443
|
+
prevOne();
|
|
444
|
+
}
|
|
445
|
+
if (key === 'Tab') {
|
|
446
|
+
e.preventDefault();
|
|
447
|
+
e.stopPropagation();
|
|
448
|
+
if (
|
|
449
|
+
document.activeElement ||
|
|
450
|
+
// @ts-ignore
|
|
451
|
+
inputs.includes(document.activeElement)
|
|
452
|
+
) {
|
|
453
|
+
// @ts-ignore
|
|
454
|
+
let index = inputs.indexOf(document.activeElement);
|
|
477
455
|
|
|
478
|
-
|
|
479
|
-
|
|
456
|
+
if (index === inputs.length) {
|
|
457
|
+
index = 0;
|
|
458
|
+
} else {
|
|
459
|
+
index++;
|
|
460
|
+
}
|
|
461
|
+
inputs[index].focus();
|
|
462
|
+
} else {
|
|
463
|
+
setTimeout(() => {
|
|
464
|
+
if (!document.activeElement || !inputs.includes(document.activeElement as HTMLInputElement)) {
|
|
465
|
+
(document.querySelector('#i18nFormItem1 input') as HTMLInputElement)?.focus();
|
|
466
|
+
}
|
|
467
|
+
}, 100);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
});
|
|
480
471
|
});
|
|
481
472
|
</script>
|
|
482
473
|
<style lang="scss">
|