yh-i18n 2.2.17 → 2.2.19
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 +155 -156
- package/index.d.ts +6 -6
- package/index.js +1 -1
- package/list.vue +55 -50
- package/package.json +2 -2
package/excelTool.ts
CHANGED
|
@@ -1,182 +1,181 @@
|
|
|
1
|
-
import ExcelJS from
|
|
2
|
-
import Config from
|
|
3
|
-
import {
|
|
4
|
-
import http from
|
|
5
|
-
import {
|
|
1
|
+
import ExcelJS from 'exceljs';
|
|
2
|
+
import Config from '@/config';
|
|
3
|
+
import {ElMessage, ElLoading} from 'element-plus';
|
|
4
|
+
import http from '@/libs/api.request';
|
|
5
|
+
import {useI18nStore} from './index';
|
|
6
6
|
|
|
7
|
-
const verificationCode =
|
|
8
|
-
export async function exportExcel
|
|
9
|
-
const loading = ElLoading.service(
|
|
7
|
+
const verificationCode = 'lkyhtranslateexcel';
|
|
8
|
+
export async function exportExcel(total) {
|
|
9
|
+
const loading = ElLoading.service({
|
|
10
10
|
lock: true,
|
|
11
|
-
text:
|
|
12
|
-
background:
|
|
13
|
-
}
|
|
11
|
+
text: '正在获取所有翻译字段……',
|
|
12
|
+
background: 'rgba(255, 255, 255, 0.2)',
|
|
13
|
+
});
|
|
14
14
|
const i18nStore = useI18nStore();
|
|
15
15
|
let records = await http
|
|
16
|
-
.request(
|
|
17
|
-
url:
|
|
18
|
-
method:
|
|
16
|
+
.request({
|
|
17
|
+
url: '/translate/select',
|
|
18
|
+
method: 'post',
|
|
19
19
|
data: {
|
|
20
20
|
pageNum: 1,
|
|
21
21
|
pageSize: total,
|
|
22
22
|
},
|
|
23
|
-
}
|
|
24
|
-
.then(
|
|
25
|
-
let localKeys = i18nStore.localList.map(
|
|
26
|
-
let {
|
|
27
|
-
records = records.map(
|
|
23
|
+
})
|
|
24
|
+
.then((res) => {
|
|
25
|
+
let localKeys = i18nStore.localList.map((item) => item.value);
|
|
26
|
+
let {records} = res.data.data;
|
|
27
|
+
records = records.map((item) => {
|
|
28
28
|
try {
|
|
29
|
-
let content = JSON.parse(
|
|
30
|
-
let keys = Object.keys(
|
|
29
|
+
let content = JSON.parse(item.content);
|
|
30
|
+
let keys = Object.keys(content);
|
|
31
31
|
|
|
32
|
-
keys.forEach(
|
|
33
|
-
let val = content[
|
|
34
|
-
item[
|
|
35
|
-
}
|
|
36
|
-
localKeys.forEach(
|
|
37
|
-
if (
|
|
38
|
-
item[
|
|
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
39
|
}
|
|
40
|
-
}
|
|
41
|
-
} catch (
|
|
40
|
+
});
|
|
41
|
+
} catch (error) {}
|
|
42
42
|
return item;
|
|
43
|
-
}
|
|
43
|
+
});
|
|
44
44
|
return records;
|
|
45
|
-
}
|
|
46
|
-
loading.setText(
|
|
45
|
+
});
|
|
46
|
+
loading.setText('正在序列化表格数据……');
|
|
47
47
|
const workbook = new ExcelJS.Workbook();
|
|
48
|
-
workbook.creator =
|
|
49
|
-
workbook.lastModifiedBy =
|
|
48
|
+
workbook.creator = '力控元海';
|
|
49
|
+
workbook.lastModifiedBy = '力控元海技术中心前端';
|
|
50
50
|
workbook.keywords = verificationCode;
|
|
51
51
|
workbook.created = new Date();
|
|
52
52
|
workbook.modified = new Date();
|
|
53
|
-
const sheet = workbook.addWorksheet(
|
|
53
|
+
const sheet = workbook.addWorksheet(`${Config.title}-系统待翻译文字`);
|
|
54
54
|
|
|
55
55
|
let columns: any[] = [
|
|
56
|
-
{
|
|
57
|
-
{
|
|
56
|
+
{width: 0, hidden: true},
|
|
57
|
+
{width: 0, hidden: true},
|
|
58
58
|
];
|
|
59
|
-
let title: string[] = [
|
|
59
|
+
let title: string[] = ['', ''];
|
|
60
60
|
let titleObj = {
|
|
61
|
-
zh_CN:
|
|
62
|
-
en_US:
|
|
63
|
-
th:
|
|
64
|
-
vi:
|
|
65
|
-
tr:
|
|
61
|
+
zh_CN: '中文',
|
|
62
|
+
en_US: '英语',
|
|
63
|
+
th: '泰语',
|
|
64
|
+
vi: '越南语',
|
|
65
|
+
tr: '土耳其语',
|
|
66
66
|
};
|
|
67
|
-
Config.i18nList.forEach(
|
|
68
|
-
columns.push(
|
|
67
|
+
Config.i18nList.forEach((item) => {
|
|
68
|
+
columns.push({
|
|
69
69
|
width: 30,
|
|
70
|
-
alignment: {
|
|
70
|
+
alignment: {vertical: 'middle', horizontal: 'center', wrapText: true},
|
|
71
71
|
value: item,
|
|
72
|
-
}
|
|
73
|
-
title.push(
|
|
74
|
-
}
|
|
72
|
+
});
|
|
73
|
+
title.push(titleObj[item]);
|
|
74
|
+
});
|
|
75
75
|
|
|
76
76
|
sheet.columns = columns;
|
|
77
|
-
sheet.addRow(
|
|
77
|
+
sheet.addRow(title);
|
|
78
78
|
sheet.addRows(
|
|
79
|
-
records.map(
|
|
80
|
-
let {
|
|
81
|
-
let row = [
|
|
82
|
-
Config.i18nList.forEach(
|
|
83
|
-
row.push(
|
|
84
|
-
}
|
|
79
|
+
records.map((item) => {
|
|
80
|
+
let {adTranslateId, key} = item;
|
|
81
|
+
let row = [adTranslateId, key];
|
|
82
|
+
Config.i18nList.forEach((valKey) => {
|
|
83
|
+
row.push(item[valKey]);
|
|
84
|
+
});
|
|
85
85
|
return row;
|
|
86
|
-
}
|
|
86
|
+
})
|
|
87
87
|
);
|
|
88
|
-
sheet.getRows(
|
|
88
|
+
sheet.getRows(1, 1)?.forEach((row, index) => {
|
|
89
89
|
row.height = 25;
|
|
90
|
-
row.eachCell(
|
|
91
|
-
cell.font = {
|
|
90
|
+
row.eachCell({includeEmpty: true}, (cell, cellIndex) => {
|
|
91
|
+
cell.font = {bold: true};
|
|
92
92
|
cell.alignment = {
|
|
93
|
-
vertical:
|
|
94
|
-
horizontal:
|
|
93
|
+
vertical: 'middle',
|
|
94
|
+
horizontal: 'center',
|
|
95
95
|
wrapText: true,
|
|
96
96
|
};
|
|
97
97
|
cell.border = {
|
|
98
|
-
top: {
|
|
99
|
-
left: {
|
|
100
|
-
bottom: {
|
|
101
|
-
right: {
|
|
98
|
+
top: {style: 'thin'},
|
|
99
|
+
left: {style: 'thin'},
|
|
100
|
+
bottom: {style: 'thin'},
|
|
101
|
+
right: {style: 'thin'},
|
|
102
102
|
};
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
sheet.getRows(
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
sheet.getRows(2, records.length)?.forEach((row, index) => {
|
|
106
106
|
row.height = 25;
|
|
107
|
-
row.eachCell(
|
|
107
|
+
row.eachCell({includeEmpty: true}, (cell, cellIndex) => {
|
|
108
108
|
cell.alignment = {
|
|
109
|
-
vertical:
|
|
110
|
-
horizontal:
|
|
109
|
+
vertical: 'middle',
|
|
110
|
+
horizontal: 'left',
|
|
111
111
|
wrapText: true,
|
|
112
112
|
};
|
|
113
113
|
cell.border = {
|
|
114
|
-
top: {
|
|
115
|
-
left: {
|
|
116
|
-
bottom: {
|
|
117
|
-
right: {
|
|
114
|
+
top: {style: 'thin'},
|
|
115
|
+
left: {style: 'thin'},
|
|
116
|
+
bottom: {style: 'thin'},
|
|
117
|
+
right: {style: 'thin'},
|
|
118
118
|
};
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
sheet.views = [
|
|
122
|
-
loading.setText(
|
|
123
|
-
workbook.xlsx.writeBuffer().then(
|
|
124
|
-
const blob = new Blob(
|
|
125
|
-
type:
|
|
126
|
-
}
|
|
127
|
-
let downloadA = document.createElement(
|
|
128
|
-
downloadA.download = `${
|
|
129
|
-
downloadA.href = window.URL.createObjectURL(
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
sheet.views = [{state: 'frozen', xSplit: 0, ySplit: 1, activeCell: 'C2'}];
|
|
122
|
+
loading.setText('正在生成表格文件……');
|
|
123
|
+
workbook.xlsx.writeBuffer().then((data) => {
|
|
124
|
+
const blob = new Blob([data], {
|
|
125
|
+
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8',
|
|
126
|
+
});
|
|
127
|
+
let downloadA = document.createElement('a');
|
|
128
|
+
downloadA.download = `${Config.title}-系统待翻译文字.xlsx`;
|
|
129
|
+
downloadA.href = window.URL.createObjectURL(blob);
|
|
130
130
|
downloadA.click();
|
|
131
131
|
loading.close();
|
|
132
|
-
ElMessage.success(
|
|
133
|
-
}
|
|
132
|
+
ElMessage.success('导出成功,请到下载目录查看');
|
|
133
|
+
});
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
async function getFile
|
|
136
|
+
async function getFile() {
|
|
137
137
|
// @ts-ignore
|
|
138
|
-
let fileHandle = await window.showOpenFilePicker(
|
|
139
|
-
id:
|
|
138
|
+
let fileHandle = await window.showOpenFilePicker({
|
|
139
|
+
id: 'importTranslateExcel',
|
|
140
140
|
types: [
|
|
141
141
|
{
|
|
142
|
-
description:
|
|
142
|
+
description: '请选择之前导出的文件',
|
|
143
143
|
accept: {
|
|
144
|
-
|
|
144
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx', '.xls'],
|
|
145
145
|
},
|
|
146
146
|
},
|
|
147
147
|
],
|
|
148
|
-
}
|
|
149
|
-
if (
|
|
150
|
-
fileHandle = fileHandle[
|
|
148
|
+
});
|
|
149
|
+
if (Array.isArray(fileHandle)) {
|
|
150
|
+
fileHandle = fileHandle[0];
|
|
151
151
|
}
|
|
152
|
-
let state = await fileHandle.queryPermission(
|
|
153
|
-
if (
|
|
152
|
+
let state = await fileHandle.queryPermission({mode: 'read'});
|
|
153
|
+
if (state === 'denied') {
|
|
154
154
|
return false;
|
|
155
155
|
} else {
|
|
156
|
-
if (
|
|
157
|
-
fileHandle.requestPermission(
|
|
158
|
-
mode:
|
|
159
|
-
}
|
|
156
|
+
if (state === 'prompt') {
|
|
157
|
+
fileHandle.requestPermission({
|
|
158
|
+
mode: 'read',
|
|
159
|
+
});
|
|
160
160
|
}
|
|
161
161
|
return await fileHandle.getFile();
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
|
|
166
|
-
async function saveData ( dataList ) {
|
|
165
|
+
async function saveData(dataList) {
|
|
167
166
|
return await http
|
|
168
|
-
.request(
|
|
169
|
-
url:
|
|
170
|
-
type:
|
|
171
|
-
method:
|
|
167
|
+
.request({
|
|
168
|
+
url: '/translate/save',
|
|
169
|
+
type: 'json',
|
|
170
|
+
method: 'POST',
|
|
172
171
|
data: dataList,
|
|
173
|
-
}
|
|
174
|
-
.then(
|
|
172
|
+
})
|
|
173
|
+
.then((res) => {
|
|
175
174
|
return res?.data?.status === 200;
|
|
176
|
-
}
|
|
175
|
+
});
|
|
177
176
|
}
|
|
178
177
|
|
|
179
|
-
export async function importExcel
|
|
178
|
+
export async function importExcel(e, getDataList) {
|
|
180
179
|
// if (!window["showOpenFilePicker"]) {
|
|
181
180
|
// ElMessage({
|
|
182
181
|
// message: "请使用Chrome(Edge) 102 及以上版本的浏览器",
|
|
@@ -185,72 +184,72 @@ export async function importExcel ( e, getDataList ) {
|
|
|
185
184
|
// return false;
|
|
186
185
|
// }
|
|
187
186
|
// let file = await getFile();
|
|
188
|
-
const file = e.target.files[
|
|
189
|
-
if (
|
|
190
|
-
ElMessage(
|
|
191
|
-
message:
|
|
192
|
-
type:
|
|
193
|
-
}
|
|
187
|
+
const file = e.target.files[0];
|
|
188
|
+
if (!(file instanceof File)) {
|
|
189
|
+
ElMessage({
|
|
190
|
+
message: '请选择文件',
|
|
191
|
+
type: 'warning',
|
|
192
|
+
});
|
|
194
193
|
return false;
|
|
195
194
|
} else {
|
|
196
195
|
try {
|
|
197
196
|
const workbook = new ExcelJS.Workbook();
|
|
198
197
|
// @ts-ignore
|
|
199
|
-
await workbook.xlsx.load(
|
|
200
|
-
if (
|
|
201
|
-
ElMessage(
|
|
202
|
-
message:
|
|
203
|
-
type:
|
|
204
|
-
}
|
|
198
|
+
await workbook.xlsx.load(file);
|
|
199
|
+
if (workbook.keywords !== verificationCode) {
|
|
200
|
+
ElMessage({
|
|
201
|
+
message: '您选择的文件不是系统导出的文件',
|
|
202
|
+
type: 'warning',
|
|
203
|
+
});
|
|
205
204
|
return false;
|
|
206
205
|
}
|
|
207
|
-
const loading = ElLoading.service(
|
|
206
|
+
const loading = ElLoading.service({
|
|
208
207
|
lock: true,
|
|
209
|
-
text:
|
|
210
|
-
background:
|
|
211
|
-
customClass:
|
|
212
|
-
}
|
|
213
|
-
let sheet = workbook.worksheets[
|
|
208
|
+
text: '开始读取已翻译的字段',
|
|
209
|
+
background: 'rgba(255, 255, 255, 0.5)',
|
|
210
|
+
customClass: 'yh-i18n-loading',
|
|
211
|
+
});
|
|
212
|
+
let sheet = workbook.worksheets[0];
|
|
214
213
|
// @ts-ignore
|
|
215
214
|
let len = sheet._rows.length - 1;
|
|
216
215
|
let dataList: any[] = [];
|
|
217
|
-
sheet.getRows(
|
|
218
|
-
let id = row.getCell(
|
|
219
|
-
let key = row.getCell(
|
|
216
|
+
sheet.getRows(2, len)?.forEach((row) => {
|
|
217
|
+
let id = row.getCell(1).value;
|
|
218
|
+
let key = row.getCell(2).value;
|
|
220
219
|
let content: any = {};
|
|
221
|
-
Config.i18nList.forEach(
|
|
222
|
-
content[
|
|
223
|
-
}
|
|
224
|
-
dataList.push(
|
|
220
|
+
Config.i18nList.forEach((item, index) => {
|
|
221
|
+
content[item] = row.getCell(index + 3).value;
|
|
222
|
+
});
|
|
223
|
+
dataList.push({
|
|
225
224
|
id,
|
|
226
225
|
key,
|
|
227
|
-
content: JSON.stringify(
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
loading.setText(
|
|
226
|
+
content: JSON.stringify(content),
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
loading.setText('读取完成,正在更新');
|
|
231
230
|
|
|
232
231
|
let dataLen = dataList.length;
|
|
233
232
|
let flag = true;
|
|
234
233
|
let saveLength = 200;
|
|
235
|
-
while (
|
|
236
|
-
if (
|
|
237
|
-
let perCent = (
|
|
238
|
-
let fillIndex = parseInt(
|
|
239
|
-
let loadingText = new Array(
|
|
240
|
-
loadingText.fill(
|
|
241
|
-
loadingText.fill(
|
|
242
|
-
loading.setText(
|
|
243
|
-
await saveData(
|
|
234
|
+
while (flag) {
|
|
235
|
+
if (dataList.length > saveLength) {
|
|
236
|
+
let perCent = (dataLen - dataList.length) / dataLen;
|
|
237
|
+
let fillIndex = parseInt(((perCent / 0.5) * 10).toFixed(0));
|
|
238
|
+
let loadingText = new Array(20);
|
|
239
|
+
loadingText.fill('◇', 0, 20 - fillIndex);
|
|
240
|
+
loadingText.fill('◆', 20 - fillIndex);
|
|
241
|
+
loading.setText(`${(perCent * 100).toFixed(2)}% ${loadingText.join('')} 正在更新…………`);
|
|
242
|
+
await saveData(dataList.splice(0, saveLength));
|
|
244
243
|
} else {
|
|
245
|
-
await saveData(
|
|
244
|
+
await saveData(dataList);
|
|
246
245
|
flag = false;
|
|
247
246
|
}
|
|
248
247
|
}
|
|
249
248
|
loading.close();
|
|
250
|
-
ElMessage.success(
|
|
249
|
+
ElMessage.success('导入数据保存成功');
|
|
251
250
|
getDataList();
|
|
252
|
-
} catch (
|
|
253
|
-
ElMessage.error(
|
|
251
|
+
} catch (error) {
|
|
252
|
+
ElMessage.error('导入保存翻译数据遇到错误:', error.message);
|
|
254
253
|
}
|
|
255
254
|
}
|
|
256
255
|
}
|
package/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import {I18n} from 'vue-i18n';
|
|
2
|
+
import {Plugin, Component} from 'vue';
|
|
3
|
+
import {StoreDefinition} from 'pinia';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* zh_CN 简体中文
|
|
@@ -9,7 +9,7 @@ import { StoreDefinition } from "pinia";
|
|
|
9
9
|
* vi 越南语(越南)
|
|
10
10
|
* tr 土耳其语(土耳其)
|
|
11
11
|
*/
|
|
12
|
-
type I18nList =
|
|
12
|
+
type I18nList = 'zh_CN' | 'en_US' | 'th' | 'vi' | 'tr';
|
|
13
13
|
|
|
14
14
|
declare global {
|
|
15
15
|
interface Window {
|
|
@@ -21,12 +21,12 @@ 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;
|
|
28
28
|
|
|
29
|
-
/**
|
|
29
|
+
/** 力控元海 vue-i18n 插件封装 */
|
|
30
30
|
export const yhI18n: Plugin;
|
|
31
31
|
|
|
32
32
|
/** 多语言选择插件 */
|
package/index.js
CHANGED
|
@@ -84,7 +84,7 @@ function recursionAddTranslate () {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
export const ct = (key, args) => {
|
|
87
|
+
export const ct = (key, args = []) => {
|
|
88
88
|
if (key && window.translateReady && window.translateCollect) {
|
|
89
89
|
// 将 键的处理全部放入队列中,避免挤兑正常逻辑的运算资源
|
|
90
90
|
if (!keySet.has(key) && !unHandle.includes(key)) {
|
package/list.vue
CHANGED
|
@@ -105,6 +105,7 @@
|
|
|
105
105
|
class="form-drawer"
|
|
106
106
|
v-model="formShow"
|
|
107
107
|
@close="cancelForm"
|
|
108
|
+
:close-on-click-modal="false"
|
|
108
109
|
draggable
|
|
109
110
|
:title="formData.adTranslateId ? ct('编辑翻译') : ct('新增翻译')">
|
|
110
111
|
<vxe-form
|
|
@@ -121,7 +122,7 @@
|
|
|
121
122
|
@click="prevOne"
|
|
122
123
|
text
|
|
123
124
|
:disabled="!isNaN(formDataIndex) && formDataIndex <= 0">
|
|
124
|
-
{{ ct('上一个') }}
|
|
125
|
+
{{ ct('上一个') }} (ctrl/alt + ←)
|
|
125
126
|
</el-button>
|
|
126
127
|
<el-button
|
|
127
128
|
type="primary"
|
|
@@ -132,13 +133,13 @@
|
|
|
132
133
|
<el-button
|
|
133
134
|
type="primary"
|
|
134
135
|
@click="saveOne">
|
|
135
|
-
{{ ct('保存') }}
|
|
136
|
+
{{ ct('保存') }}(ctrl + S)
|
|
136
137
|
</el-button>
|
|
137
138
|
<el-button
|
|
138
139
|
@click="nextOne"
|
|
139
140
|
text
|
|
140
|
-
:disabled="!isNaN(formDataIndex) && formDataIndex >= dataList.
|
|
141
|
-
{{ ct('下一个') }}
|
|
141
|
+
:disabled="!isNaN(formDataIndex) && formDataIndex >= dataList.length - 1">
|
|
142
|
+
{{ ct('下一个') }}(ctrl/alt + →)
|
|
142
143
|
</el-button>
|
|
143
144
|
</div>
|
|
144
145
|
</template>
|
|
@@ -151,6 +152,25 @@ import {useI18nStore, ct} from 'yh-i18n';
|
|
|
151
152
|
import http from '@/libs/api.request';
|
|
152
153
|
import {VxeFormInstance, VxeFormPropTypes} from 'vxe-table';
|
|
153
154
|
import {exportExcel, importExcel} from './excelTool';
|
|
155
|
+
|
|
156
|
+
interface TranslateItem {
|
|
157
|
+
adTranslateId?: string;
|
|
158
|
+
key: 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
|
+
key: string;
|
|
171
|
+
content: Record<string, string>;
|
|
172
|
+
id?: string;
|
|
173
|
+
}
|
|
154
174
|
const i18nStore = useI18nStore();
|
|
155
175
|
const vxeFormRef = ref<VxeFormInstance>();
|
|
156
176
|
|
|
@@ -165,8 +185,8 @@ const listForm = reactive({
|
|
|
165
185
|
pageSize: 10,
|
|
166
186
|
total: 0,
|
|
167
187
|
});
|
|
168
|
-
const listColumns = reactive<
|
|
169
|
-
const dataList = ref<
|
|
188
|
+
const listColumns = reactive<ListColumn[]>([]);
|
|
189
|
+
const dataList = ref<TranslateItem[]>([]);
|
|
170
190
|
function getDataList(isReset = false) {
|
|
171
191
|
let {key, pageNum, pageSize} = listForm;
|
|
172
192
|
if (isReset) {
|
|
@@ -202,7 +222,9 @@ function getDataList(isReset = false) {
|
|
|
202
222
|
item[k] = '';
|
|
203
223
|
}
|
|
204
224
|
});
|
|
205
|
-
} catch (error) {
|
|
225
|
+
} catch (error) {
|
|
226
|
+
console.error('解析翻译内容失败:', error);
|
|
227
|
+
}
|
|
206
228
|
return item;
|
|
207
229
|
});
|
|
208
230
|
dataList.value = records;
|
|
@@ -238,8 +260,11 @@ function resetList() {
|
|
|
238
260
|
}
|
|
239
261
|
|
|
240
262
|
const langList = Object.keys(i18nStore.langList);
|
|
241
|
-
const formDataIndex = ref();
|
|
242
|
-
const formData = reactive<
|
|
263
|
+
const formDataIndex = ref<number>();
|
|
264
|
+
const formData = reactive<TranslateItem>({
|
|
265
|
+
key: '',
|
|
266
|
+
content: '',
|
|
267
|
+
});
|
|
243
268
|
const formShow = ref(false);
|
|
244
269
|
let inputs: HTMLInputElement[] = [];
|
|
245
270
|
function cancelForm() {
|
|
@@ -255,7 +280,7 @@ function addOne() {
|
|
|
255
280
|
}
|
|
256
281
|
|
|
257
282
|
function prevOne() {
|
|
258
|
-
if (formDataIndex.value > 0) {
|
|
283
|
+
if (formDataIndex.value !== void 0 && formDataIndex.value > 0) {
|
|
259
284
|
let index = formDataIndex.value - 1;
|
|
260
285
|
let item = dataList.value[index];
|
|
261
286
|
editOne(item, index);
|
|
@@ -278,7 +303,7 @@ function editOne(item, index) {
|
|
|
278
303
|
}
|
|
279
304
|
|
|
280
305
|
function nextOne() {
|
|
281
|
-
if (formDataIndex.value < dataList.value.length - 1) {
|
|
306
|
+
if (formDataIndex.value !== void 0 && formDataIndex.value < dataList.value.length - 1) {
|
|
282
307
|
let index = formDataIndex.value + 1;
|
|
283
308
|
let item = dataList.value[index];
|
|
284
309
|
editOne(item, index);
|
|
@@ -286,11 +311,11 @@ function nextOne() {
|
|
|
286
311
|
}
|
|
287
312
|
|
|
288
313
|
function saveOne() {
|
|
289
|
-
let isAdd =
|
|
314
|
+
let isAdd = !formData.adTranslateId;
|
|
290
315
|
let url = updateUrl;
|
|
291
316
|
vxeFormRef?.value?.validate().then((errMap) => {
|
|
292
317
|
if (!errMap) {
|
|
293
|
-
let data:
|
|
318
|
+
let data: SaveData = {
|
|
294
319
|
key: formData.key,
|
|
295
320
|
content: {},
|
|
296
321
|
};
|
|
@@ -315,13 +340,14 @@ function saveOne() {
|
|
|
315
340
|
.then((res) => {
|
|
316
341
|
if (res?.data?.status === 200) {
|
|
317
342
|
ElMessage.success(res.data.msg);
|
|
318
|
-
if (
|
|
343
|
+
if (isAdd) {
|
|
344
|
+
getDataList();
|
|
345
|
+
cancelForm();
|
|
346
|
+
} else {
|
|
319
347
|
dataList.value[formDataIndex.value] = {
|
|
320
348
|
...formData,
|
|
321
349
|
};
|
|
322
350
|
nextOne();
|
|
323
|
-
} else {
|
|
324
|
-
cancelForm();
|
|
325
351
|
}
|
|
326
352
|
} else {
|
|
327
353
|
ElMessage.error(res.data.msg);
|
|
@@ -363,13 +389,17 @@ function delMore() {
|
|
|
363
389
|
for (let i = 0; i < ids.length; i++) {
|
|
364
390
|
const id = ids[i];
|
|
365
391
|
loading.setText(`正在删除... ${i + 1}/${len}`);
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
392
|
+
try {
|
|
393
|
+
await http.request({
|
|
394
|
+
url: deleteUrl,
|
|
395
|
+
method: 'POST',
|
|
396
|
+
data: {
|
|
397
|
+
id,
|
|
398
|
+
},
|
|
399
|
+
});
|
|
400
|
+
} catch (error) {
|
|
401
|
+
ElMessage.error(`删除第 ${i + 1} 条记录失败`);
|
|
402
|
+
}
|
|
373
403
|
}
|
|
374
404
|
loading.close();
|
|
375
405
|
getDataList();
|
|
@@ -379,7 +409,7 @@ function delMore() {
|
|
|
379
409
|
|
|
380
410
|
const formItems = reactive<VxeFormPropTypes.Items>([
|
|
381
411
|
{
|
|
382
|
-
field: '
|
|
412
|
+
field: 'tkey',
|
|
383
413
|
span: 24,
|
|
384
414
|
title: '翻译键值',
|
|
385
415
|
itemRender: {
|
|
@@ -390,7 +420,7 @@ const formItems = reactive<VxeFormPropTypes.Items>([
|
|
|
390
420
|
]);
|
|
391
421
|
|
|
392
422
|
const fromRules = reactive<VxeFormPropTypes.Rules>({
|
|
393
|
-
|
|
423
|
+
tkey: [{required: true, type: 'string', message: '请输入翻译键值'}],
|
|
394
424
|
});
|
|
395
425
|
|
|
396
426
|
let needInit = true;
|
|
@@ -442,31 +472,6 @@ onMounted(() => {
|
|
|
442
472
|
e.stopPropagation();
|
|
443
473
|
prevOne();
|
|
444
474
|
}
|
|
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);
|
|
455
|
-
|
|
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
475
|
});
|
|
471
476
|
});
|
|
472
477
|
</script>
|