yh-i18n 2.2.12 → 2.2.14
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 +123 -120
- package/index.d.ts +0 -0
- package/index.js +9 -11
- package/lang/baseEnUS.js +0 -0
- package/lang/baseTh.js +0 -0
- package/lang/baseTr.js +0 -0
- package/lang/baseVi.js +0 -0
- package/lang/baseZhCn.js +0 -0
- package/lang/en.js +0 -0
- package/lang/th.js +0 -0
- package/lang/tr.js +0 -0
- package/lang/vi.js +0 -0
- package/lang/zh.js +0 -0
- package/language.vue +0 -0
- package/list.vue +81 -60
- package/package.json +1 -1
- package/readme.md +0 -0
package/excelTool.ts
CHANGED
|
@@ -5,58 +5,58 @@ import http from "@/libs/api.request";
|
|
|
5
5
|
import { useI18nStore } from "./index";
|
|
6
6
|
|
|
7
7
|
const verificationCode = "lkyhtranslateexcel";
|
|
8
|
-
export async function exportExcel(total) {
|
|
9
|
-
const loading = ElLoading.service({
|
|
8
|
+
export async function exportExcel ( total ) {
|
|
9
|
+
const loading = ElLoading.service( {
|
|
10
10
|
lock: true,
|
|
11
11
|
text: "正在获取所有翻译字段……",
|
|
12
12
|
background: "rgba(255, 255, 255, 0.2)",
|
|
13
|
-
});
|
|
13
|
+
} );
|
|
14
14
|
const i18nStore = useI18nStore();
|
|
15
15
|
let records = await http
|
|
16
|
-
.request({
|
|
16
|
+
.request( {
|
|
17
17
|
url: "/translate/select",
|
|
18
18
|
method: "post",
|
|
19
19
|
data: {
|
|
20
20
|
pageNum: 1,
|
|
21
21
|
pageSize: total,
|
|
22
22
|
},
|
|
23
|
-
})
|
|
24
|
-
.then((res) => {
|
|
25
|
-
let localKeys = i18nStore.localList.map((item) => item.value);
|
|
23
|
+
} )
|
|
24
|
+
.then( ( res ) => {
|
|
25
|
+
let localKeys = i18nStore.localList.map( ( item ) => item.value );
|
|
26
26
|
let { records } = res.data.data;
|
|
27
|
-
records = records.map((item) => {
|
|
27
|
+
records = records.map( ( item ) => {
|
|
28
28
|
try {
|
|
29
|
-
let content = JSON.parse(item.content);
|
|
30
|
-
let keys = Object.keys(content);
|
|
29
|
+
let content = JSON.parse( item.content );
|
|
30
|
+
let keys = Object.keys( content );
|
|
31
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] = "";
|
|
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 (error) {}
|
|
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
48
|
workbook.creator = "力控远海";
|
|
49
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(`${Config.title}-系统待翻译文字`);
|
|
53
|
+
const sheet = workbook.addWorksheet( `${ Config.title }-系统待翻译文字` );
|
|
54
54
|
|
|
55
55
|
let columns: any[] = [
|
|
56
56
|
{ width: 0, hidden: true },
|
|
57
57
|
{ width: 0, hidden: true },
|
|
58
58
|
];
|
|
59
|
-
let title: string[] = ["", ""];
|
|
59
|
+
let title: string[] = [ "", "" ];
|
|
60
60
|
let titleObj = {
|
|
61
61
|
zh_CN: "中文",
|
|
62
62
|
en_US: "英语",
|
|
@@ -64,30 +64,30 @@ export async function exportExcel(total) {
|
|
|
64
64
|
vi: "越南语",
|
|
65
65
|
tr: "土耳其语",
|
|
66
66
|
};
|
|
67
|
-
Config.i18nList.forEach((item) => {
|
|
68
|
-
columns.push({
|
|
67
|
+
Config.i18nList.forEach( ( item ) => {
|
|
68
|
+
columns.push( {
|
|
69
69
|
width: 30,
|
|
70
70
|
alignment: { vertical: "middle", horizontal: "center", wrapText: true },
|
|
71
71
|
value: item,
|
|
72
|
-
});
|
|
73
|
-
title.push(titleObj[item]);
|
|
74
|
-
});
|
|
72
|
+
} );
|
|
73
|
+
title.push( titleObj[ item ] );
|
|
74
|
+
} );
|
|
75
75
|
|
|
76
76
|
sheet.columns = columns;
|
|
77
|
-
sheet.addRow(title);
|
|
77
|
+
sheet.addRow( title );
|
|
78
78
|
sheet.addRows(
|
|
79
|
-
records.map((item) => {
|
|
79
|
+
records.map( ( item ) => {
|
|
80
80
|
let { adTranslateId, key } = item;
|
|
81
|
-
let row = [adTranslateId, key];
|
|
82
|
-
Config.i18nList.forEach((valKey) => {
|
|
83
|
-
row.push(item[valKey]);
|
|
84
|
-
});
|
|
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(1, 1)?.forEach((row, index) => {
|
|
88
|
+
sheet.getRows( 1, 1 )?.forEach( ( row, index ) => {
|
|
89
89
|
row.height = 25;
|
|
90
|
-
row.eachCell({ includeEmpty: true }, (cell, cellIndex) => {
|
|
90
|
+
row.eachCell( { includeEmpty: true }, ( cell, cellIndex ) => {
|
|
91
91
|
cell.font = { bold: true };
|
|
92
92
|
cell.alignment = {
|
|
93
93
|
vertical: "middle",
|
|
@@ -100,11 +100,11 @@ export async function exportExcel(total) {
|
|
|
100
100
|
bottom: { style: "thin" },
|
|
101
101
|
right: { style: "thin" },
|
|
102
102
|
};
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
sheet.getRows(2, records.length)?.forEach((row, index) => {
|
|
103
|
+
} );
|
|
104
|
+
} );
|
|
105
|
+
sheet.getRows( 2, records.length )?.forEach( ( row, index ) => {
|
|
106
106
|
row.height = 25;
|
|
107
|
-
row.eachCell({ includeEmpty: true }, (cell, cellIndex) => {
|
|
107
|
+
row.eachCell( { includeEmpty: true }, ( cell, cellIndex ) => {
|
|
108
108
|
cell.alignment = {
|
|
109
109
|
vertical: "middle",
|
|
110
110
|
horizontal: "left",
|
|
@@ -116,138 +116,141 @@ export async function exportExcel(total) {
|
|
|
116
116
|
bottom: { style: "thin" },
|
|
117
117
|
right: { style: "thin" },
|
|
118
118
|
};
|
|
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], {
|
|
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
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);
|
|
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({
|
|
138
|
+
let fileHandle = await window.showOpenFilePicker( {
|
|
139
139
|
id: "importTranslateExcel",
|
|
140
140
|
types: [
|
|
141
141
|
{
|
|
142
142
|
description: "请选择之前导出的文件",
|
|
143
143
|
accept: {
|
|
144
|
-
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [".xlsx", ".xls"],
|
|
144
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [ ".xlsx", ".xls" ],
|
|
145
145
|
},
|
|
146
146
|
},
|
|
147
147
|
],
|
|
148
|
-
});
|
|
149
|
-
if (Array.isArray(fileHandle)) {
|
|
150
|
-
fileHandle = fileHandle[0];
|
|
148
|
+
} );
|
|
149
|
+
if ( Array.isArray( fileHandle ) ) {
|
|
150
|
+
fileHandle = fileHandle[ 0 ];
|
|
151
151
|
}
|
|
152
|
-
let state = await fileHandle.queryPermission({ mode: "read" });
|
|
153
|
-
if (state === "denied") {
|
|
152
|
+
let state = await fileHandle.queryPermission( { mode: "read" } );
|
|
153
|
+
if ( state === "denied" ) {
|
|
154
154
|
return false;
|
|
155
155
|
} else {
|
|
156
|
-
if (state === "prompt") {
|
|
157
|
-
fileHandle.requestPermission({
|
|
156
|
+
if ( state === "prompt" ) {
|
|
157
|
+
fileHandle.requestPermission( {
|
|
158
158
|
mode: "read",
|
|
159
|
-
});
|
|
159
|
+
} );
|
|
160
160
|
}
|
|
161
161
|
return await fileHandle.getFile();
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
|
|
166
|
-
async function saveData(dataList){
|
|
166
|
+
async function saveData ( dataList ) {
|
|
167
167
|
return await http
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
168
|
+
.request( {
|
|
169
|
+
url: "/translate/save",
|
|
170
|
+
type: "json",
|
|
171
|
+
method: "POST",
|
|
172
|
+
data: dataList,
|
|
173
|
+
} )
|
|
174
|
+
.then( ( res ) => {
|
|
175
|
+
return res?.data?.status === 200;
|
|
176
|
+
} );
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
export async function importExcel(getDataList) {
|
|
180
|
-
if (!window["showOpenFilePicker"]) {
|
|
181
|
-
|
|
182
|
-
|
|
179
|
+
export async function importExcel ( e, getDataList ) {
|
|
180
|
+
// if (!window["showOpenFilePicker"]) {
|
|
181
|
+
// ElMessage({
|
|
182
|
+
// message: "请使用Chrome(Edge) 102 及以上版本的浏览器",
|
|
183
|
+
// type: "warning",
|
|
184
|
+
// });
|
|
185
|
+
// return false;
|
|
186
|
+
// }
|
|
187
|
+
// let file = await getFile();
|
|
188
|
+
const file = e.target.files[ 0 ];
|
|
189
|
+
if ( !( file instanceof File ) ) {
|
|
190
|
+
ElMessage( {
|
|
191
|
+
message: "请选择文件",
|
|
183
192
|
type: "warning",
|
|
184
|
-
});
|
|
185
|
-
return false;
|
|
186
|
-
}
|
|
187
|
-
let file = await getFile();
|
|
188
|
-
if (file === false) {
|
|
189
|
-
ElMessage({
|
|
190
|
-
message: "请授权浏览器读取文件",
|
|
191
|
-
type: "warning",
|
|
192
|
-
});
|
|
193
|
+
} );
|
|
193
194
|
return false;
|
|
194
195
|
} else {
|
|
195
196
|
try {
|
|
196
197
|
const workbook = new ExcelJS.Workbook();
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
198
|
+
// @ts-ignore
|
|
199
|
+
await workbook.xlsx.load( file );
|
|
200
|
+
if ( workbook.keywords !== verificationCode ) {
|
|
201
|
+
ElMessage( {
|
|
200
202
|
message: "您选择的文件不是系统导出的文件",
|
|
201
203
|
type: "warning",
|
|
202
|
-
});
|
|
204
|
+
} );
|
|
203
205
|
return false;
|
|
204
206
|
}
|
|
205
|
-
const loading = ElLoading.service({
|
|
207
|
+
const loading = ElLoading.service( {
|
|
206
208
|
lock: true,
|
|
207
209
|
text: "开始读取已翻译的字段",
|
|
208
210
|
background: "rgba(255, 255, 255, 0.5)",
|
|
209
211
|
customClass: "yh-i18n-loading"
|
|
210
|
-
});
|
|
211
|
-
let sheet = workbook.worksheets[0];
|
|
212
|
+
} );
|
|
213
|
+
let sheet = workbook.worksheets[ 0 ];
|
|
214
|
+
// @ts-ignore
|
|
212
215
|
let len = sheet._rows.length - 1;
|
|
213
216
|
let dataList: any[] = [];
|
|
214
|
-
sheet.getRows(2, len)?.forEach((row) => {
|
|
215
|
-
let id = row.getCell(1).value;
|
|
216
|
-
let key = row.getCell(2).value;
|
|
217
|
+
sheet.getRows( 2, len )?.forEach( ( row ) => {
|
|
218
|
+
let id = row.getCell( 1 ).value;
|
|
219
|
+
let key = row.getCell( 2 ).value;
|
|
217
220
|
let content: any = {};
|
|
218
|
-
Config.i18nList.forEach((item, index) => {
|
|
219
|
-
content[item] = row.getCell(index + 3).value;
|
|
220
|
-
});
|
|
221
|
-
dataList.push({
|
|
221
|
+
Config.i18nList.forEach( ( item, index ) => {
|
|
222
|
+
content[ item ] = row.getCell( index + 3 ).value;
|
|
223
|
+
} );
|
|
224
|
+
dataList.push( {
|
|
222
225
|
id,
|
|
223
226
|
key,
|
|
224
|
-
content: JSON.stringify(content),
|
|
225
|
-
});
|
|
226
|
-
});
|
|
227
|
-
loading.setText("读取完成,正在更新");
|
|
228
|
-
|
|
227
|
+
content: JSON.stringify( content ),
|
|
228
|
+
} );
|
|
229
|
+
} );
|
|
230
|
+
loading.setText( "读取完成,正在更新" );
|
|
231
|
+
|
|
229
232
|
let dataLen = dataList.length;
|
|
230
233
|
let flag = true;
|
|
231
234
|
let saveLength = 200;
|
|
232
|
-
while (flag) {
|
|
233
|
-
if(dataList.length > saveLength) {
|
|
234
|
-
let perCent = (dataLen - dataList.length)/dataLen
|
|
235
|
-
let fillIndex = parseInt((perCent / 0.5 * 10).toFixed(0));
|
|
236
|
-
let loadingText = new Array(20);
|
|
237
|
-
loadingText.fill('◇',0,20-fillIndex)
|
|
238
|
-
loadingText.fill('◆',20-fillIndex)
|
|
239
|
-
loading.setText(`${(perCent*100).toFixed(2)}% ${loadingText.join('')} 正在更新…………`)
|
|
240
|
-
await saveData(dataList.splice(0,saveLength))
|
|
235
|
+
while ( flag ) {
|
|
236
|
+
if ( dataList.length > saveLength ) {
|
|
237
|
+
let perCent = ( dataLen - dataList.length ) / dataLen;
|
|
238
|
+
let fillIndex = parseInt( ( perCent / 0.5 * 10 ).toFixed( 0 ) );
|
|
239
|
+
let loadingText = new Array( 20 );
|
|
240
|
+
loadingText.fill( '◇', 0, 20 - fillIndex );
|
|
241
|
+
loadingText.fill( '◆', 20 - fillIndex );
|
|
242
|
+
loading.setText( `${ ( perCent * 100 ).toFixed( 2 ) }% ${ loadingText.join( '' ) } 正在更新…………` );
|
|
243
|
+
await saveData( dataList.splice( 0, saveLength ) );
|
|
241
244
|
} else {
|
|
242
|
-
await saveData(dataList)
|
|
245
|
+
await saveData( dataList );
|
|
243
246
|
flag = false;
|
|
244
247
|
}
|
|
245
248
|
}
|
|
246
249
|
loading.close();
|
|
247
|
-
ElMessage.success("导入数据保存成功")
|
|
250
|
+
ElMessage.success( "导入数据保存成功" );
|
|
248
251
|
getDataList();
|
|
249
|
-
} catch (error) {
|
|
250
|
-
ElMessage.error("导入保存翻译数据遇到错误:",error.message)
|
|
252
|
+
} catch ( error ) {
|
|
253
|
+
ElMessage.error( "导入保存翻译数据遇到错误:", error.message );
|
|
251
254
|
}
|
|
252
255
|
}
|
|
253
256
|
}
|
package/index.d.ts
CHANGED
|
File without changes
|
package/index.js
CHANGED
|
@@ -37,7 +37,6 @@ const initlang = localStorage.translateLanguage || navLang || "zh_CN";
|
|
|
37
37
|
|
|
38
38
|
export let i18n = null;
|
|
39
39
|
window.translateReady = localStorage.translateReady ? localStorage.translateReady === "1" : import.meta.env.DEV;
|
|
40
|
-
const isDev = window.translateReady;
|
|
41
40
|
let contentReady = false;
|
|
42
41
|
|
|
43
42
|
const keySet = new Set();
|
|
@@ -78,7 +77,7 @@ function recursionAddTranslate () {
|
|
|
78
77
|
}
|
|
79
78
|
// 通过延时降低任务密度,避免挤兑正常逻辑的运算资源
|
|
80
79
|
recursionAddTimer = setTimeout(() => {
|
|
81
|
-
|
|
80
|
+
cLog(`${unHandle.length} ${key}`);
|
|
82
81
|
recursionAddTimer = null;
|
|
83
82
|
recursionAddTranslate();
|
|
84
83
|
}, 150);
|
|
@@ -86,9 +85,9 @@ function recursionAddTranslate () {
|
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
export const ct = (key, args) => {
|
|
89
|
-
if (
|
|
88
|
+
if (window.translateReady && window.translateCollect) {
|
|
90
89
|
// 将 键的处理全部放入队列中,避免挤兑正常逻辑的运算资源
|
|
91
|
-
if (!unHandle.includes(key)) {
|
|
90
|
+
if (!keySet.has(key) && !unHandle.includes(key)) {
|
|
92
91
|
unHandle.push(key);
|
|
93
92
|
recursionAddTranslate();
|
|
94
93
|
}
|
|
@@ -180,7 +179,6 @@ export const useI18nStore = defineStore("i18nStore", () => {
|
|
|
180
179
|
});
|
|
181
180
|
|
|
182
181
|
return {
|
|
183
|
-
isDev,
|
|
184
182
|
lang,
|
|
185
183
|
setLang,
|
|
186
184
|
langList,
|
|
@@ -214,7 +212,7 @@ async function getRemoteMessage (list) {
|
|
|
214
212
|
try {
|
|
215
213
|
let itemObj = JSON.parse(item);
|
|
216
214
|
let mKey = itemObj.zh_CN;
|
|
217
|
-
if (
|
|
215
|
+
if (window.translateReady && !keySet.has(mKey)) {
|
|
218
216
|
keySet.add(mKey);
|
|
219
217
|
}
|
|
220
218
|
Object.entries(itemObj).forEach(([key, val]) => {
|
|
@@ -223,7 +221,7 @@ async function getRemoteMessage (list) {
|
|
|
223
221
|
}
|
|
224
222
|
});
|
|
225
223
|
} catch (err) {
|
|
226
|
-
if (
|
|
224
|
+
if (window.translateReady) {
|
|
227
225
|
// console.count("翻译数据格式不对");
|
|
228
226
|
}
|
|
229
227
|
}
|
|
@@ -268,7 +266,7 @@ function createLocalMessage (list) {
|
|
|
268
266
|
}
|
|
269
267
|
|
|
270
268
|
export function addI18nPage (router) {
|
|
271
|
-
if (
|
|
269
|
+
if (window.translateReady) {
|
|
272
270
|
router.addRoute("Index", {
|
|
273
271
|
path: "translate",
|
|
274
272
|
name: "翻译管理",
|
|
@@ -304,10 +302,10 @@ export const yhI18n = {
|
|
|
304
302
|
app.use(i18n);
|
|
305
303
|
app.config.globalProperties.$T = ct;
|
|
306
304
|
|
|
307
|
-
if (!
|
|
308
|
-
cLog("没有开启翻译管理,可以在开发环境或者在控制台运行后面的代码再刷新页面: `localStorage.
|
|
305
|
+
if (!window.translateReady) {
|
|
306
|
+
cLog("没有开启翻译管理,可以在开发环境或者在控制台运行后面的代码再刷新页面: `localStorage.translateReady = '1'`");
|
|
309
307
|
}
|
|
310
|
-
if (router &&
|
|
308
|
+
if (router && window.translateReady) {
|
|
311
309
|
addI18nPage(router);
|
|
312
310
|
} else {
|
|
313
311
|
if (!router) {
|
package/lang/baseEnUS.js
CHANGED
|
File without changes
|
package/lang/baseTh.js
CHANGED
|
File without changes
|
package/lang/baseTr.js
CHANGED
|
File without changes
|
package/lang/baseVi.js
CHANGED
|
File without changes
|
package/lang/baseZhCn.js
CHANGED
|
File without changes
|
package/lang/en.js
CHANGED
|
File without changes
|
package/lang/th.js
CHANGED
|
File without changes
|
package/lang/tr.js
CHANGED
|
File without changes
|
package/lang/vi.js
CHANGED
|
File without changes
|
package/lang/zh.js
CHANGED
|
File without changes
|
package/language.vue
CHANGED
|
File without changes
|
package/list.vue
CHANGED
|
@@ -14,33 +14,35 @@
|
|
|
14
14
|
<el-button
|
|
15
15
|
type="primary"
|
|
16
16
|
@click="getDataList">
|
|
17
|
-
{{ ct(
|
|
17
|
+
{{ ct('搜索') }}
|
|
18
18
|
</el-button>
|
|
19
|
-
<el-button @click="resetList">{{ ct(
|
|
19
|
+
<el-button @click="resetList">{{ ct('重置') }}</el-button>
|
|
20
20
|
</div>
|
|
21
21
|
<div class="yh-i18n-list-actions">
|
|
22
22
|
<el-button
|
|
23
23
|
type="primary"
|
|
24
24
|
@click="addOne">
|
|
25
25
|
<i class="iconfont icon-add"></i>
|
|
26
|
-
{{ ct(
|
|
26
|
+
{{ ct('新增') }}
|
|
27
27
|
</el-button>
|
|
28
28
|
<el-button
|
|
29
29
|
type="danger"
|
|
30
30
|
@click="delMore">
|
|
31
31
|
<i class="iconfont icon-delete"></i>
|
|
32
|
-
{{ ct(
|
|
32
|
+
{{ ct('批量删除') }}
|
|
33
33
|
</el-button>
|
|
34
34
|
<el-button
|
|
35
35
|
text
|
|
36
36
|
@click="exportExcel(listForm.total)">
|
|
37
|
-
{{ ct(
|
|
38
|
-
</el-button>
|
|
39
|
-
<el-button
|
|
40
|
-
text
|
|
41
|
-
@click="importExcel(getDataList)">
|
|
42
|
-
{{ ct("导入") }}
|
|
37
|
+
{{ ct('导出') }}
|
|
43
38
|
</el-button>
|
|
39
|
+
<div class="el-button is-text import-excel-button">
|
|
40
|
+
<input
|
|
41
|
+
class="import-excel-input"
|
|
42
|
+
type="file"
|
|
43
|
+
@change="importExcel($event, getDataList)" />
|
|
44
|
+
{{ ct('导入') }}
|
|
45
|
+
</div>
|
|
44
46
|
</div>
|
|
45
47
|
<el-table
|
|
46
48
|
ref="i18nList"
|
|
@@ -64,18 +66,18 @@
|
|
|
64
66
|
width="140"
|
|
65
67
|
align="center"
|
|
66
68
|
fixed="left">
|
|
67
|
-
<template #default="{
|
|
69
|
+
<template #default="{row, $index}">
|
|
68
70
|
<el-button
|
|
69
71
|
link
|
|
70
72
|
type="primary"
|
|
71
73
|
@click="editOne(row, $index)">
|
|
72
|
-
{{ ct(
|
|
74
|
+
{{ ct('编辑') }}
|
|
73
75
|
</el-button>
|
|
74
76
|
<el-button
|
|
75
77
|
link
|
|
76
78
|
type="danger"
|
|
77
79
|
@click="delOne(row.adTranslateId)">
|
|
78
|
-
{{ ct(
|
|
80
|
+
{{ ct('删除') }}
|
|
79
81
|
</el-button>
|
|
80
82
|
</template>
|
|
81
83
|
</el-table-column>
|
|
@@ -93,7 +95,7 @@
|
|
|
93
95
|
</el-table>
|
|
94
96
|
<el-pagination
|
|
95
97
|
background
|
|
96
|
-
:page-sizes="[10, 100, 200, 500,
|
|
98
|
+
:page-sizes="[10, 100, 200, 500, 10000]"
|
|
97
99
|
v-model:page-size="listForm.pageSize"
|
|
98
100
|
:total="listForm.total"
|
|
99
101
|
v-model:current-page="listForm.pageNum"
|
|
@@ -119,46 +121,46 @@
|
|
|
119
121
|
@click="prevOne"
|
|
120
122
|
text
|
|
121
123
|
:disabled="!isNaN(formDataIndex) && formDataIndex <= 0">
|
|
122
|
-
{{ ct(
|
|
124
|
+
{{ ct('上一个') }}(←)
|
|
123
125
|
</el-button>
|
|
124
126
|
<el-button
|
|
125
127
|
type="primary"
|
|
126
128
|
plain
|
|
127
129
|
@click="cancelForm">
|
|
128
|
-
{{ ct(
|
|
130
|
+
{{ ct('取消') }}
|
|
129
131
|
</el-button>
|
|
130
132
|
<el-button
|
|
131
133
|
type="primary"
|
|
132
134
|
@click="saveOne">
|
|
133
|
-
{{ ct(
|
|
135
|
+
{{ ct('保存') }}
|
|
134
136
|
</el-button>
|
|
135
137
|
<el-button
|
|
136
138
|
@click="nextOne"
|
|
137
139
|
text
|
|
138
140
|
:disabled="!isNaN(formDataIndex) && formDataIndex >= dataList.leng - 1">
|
|
139
|
-
{{ ct(
|
|
141
|
+
{{ ct('下一个') }}(→)
|
|
140
142
|
</el-button>
|
|
141
143
|
</div>
|
|
142
144
|
</template>
|
|
143
145
|
</el-dialog>
|
|
144
146
|
</template>
|
|
145
147
|
<script setup lang="ts">
|
|
146
|
-
import {
|
|
147
|
-
import {
|
|
148
|
-
import {
|
|
149
|
-
import http from
|
|
150
|
-
import {
|
|
151
|
-
import {
|
|
148
|
+
import {reactive, ref, onMounted, watch} from 'vue';
|
|
149
|
+
import {ElLoadingService, ElMessage, ElMessageBox} from 'element-plus';
|
|
150
|
+
import {useI18nStore, ct} from 'yh-i18n';
|
|
151
|
+
import http from '@/libs/api.request';
|
|
152
|
+
import {VxeFormInstance, VxeFormPropTypes} from 'vxe-table';
|
|
153
|
+
import {exportExcel, importExcel} from './excelTool';
|
|
152
154
|
const i18nStore = useI18nStore();
|
|
153
155
|
const vxeFormRef = ref<VxeFormInstance>();
|
|
154
156
|
|
|
155
|
-
const insertUrl =
|
|
156
|
-
const updateUrl =
|
|
157
|
-
const deleteUrl =
|
|
157
|
+
const insertUrl = '/translate/insert';
|
|
158
|
+
const updateUrl = '/translate/edit';
|
|
159
|
+
const deleteUrl = '/translate/deleteTranslate';
|
|
158
160
|
|
|
159
161
|
const i18nList = ref();
|
|
160
162
|
const listForm = reactive({
|
|
161
|
-
key:
|
|
163
|
+
key: '',
|
|
162
164
|
pageNum: 1,
|
|
163
165
|
pageSize: 10,
|
|
164
166
|
total: 0,
|
|
@@ -166,14 +168,17 @@ const listForm = reactive({
|
|
|
166
168
|
const listColumns = reactive<any>([]);
|
|
167
169
|
const dataList = ref<any>([]);
|
|
168
170
|
function getDataList(isReset = false) {
|
|
169
|
-
let {
|
|
171
|
+
let {key, pageNum, pageSize} = listForm;
|
|
170
172
|
if (isReset) {
|
|
171
173
|
pageNum = 1;
|
|
172
174
|
}
|
|
175
|
+
let loading = ElLoadingService({
|
|
176
|
+
text: '获取列表数据中……',
|
|
177
|
+
});
|
|
173
178
|
http
|
|
174
179
|
.request({
|
|
175
|
-
url:
|
|
176
|
-
method:
|
|
180
|
+
url: '/translate/select',
|
|
181
|
+
method: 'post',
|
|
177
182
|
data: {
|
|
178
183
|
key,
|
|
179
184
|
pageNum,
|
|
@@ -182,7 +187,7 @@ function getDataList(isReset = false) {
|
|
|
182
187
|
})
|
|
183
188
|
.then((res) => {
|
|
184
189
|
let localKeys = i18nStore.localList.map((item) => item.value);
|
|
185
|
-
let {
|
|
190
|
+
let {records, total} = res.data.data;
|
|
186
191
|
records = records.map((item) => {
|
|
187
192
|
try {
|
|
188
193
|
let content = JSON.parse(item.content);
|
|
@@ -194,7 +199,7 @@ function getDataList(isReset = false) {
|
|
|
194
199
|
});
|
|
195
200
|
localKeys.forEach((k) => {
|
|
196
201
|
if (!keys.includes(k)) {
|
|
197
|
-
item[k] =
|
|
202
|
+
item[k] = '';
|
|
198
203
|
}
|
|
199
204
|
});
|
|
200
205
|
} catch (error) {}
|
|
@@ -202,6 +207,9 @@ function getDataList(isReset = false) {
|
|
|
202
207
|
});
|
|
203
208
|
dataList.value = records;
|
|
204
209
|
listForm.total = total;
|
|
210
|
+
})
|
|
211
|
+
.finally(() => {
|
|
212
|
+
loading.close();
|
|
205
213
|
});
|
|
206
214
|
}
|
|
207
215
|
|
|
@@ -223,7 +231,7 @@ function rowClickHandler(row) {
|
|
|
223
231
|
}
|
|
224
232
|
|
|
225
233
|
function resetList() {
|
|
226
|
-
listForm.key =
|
|
234
|
+
listForm.key = '';
|
|
227
235
|
listForm.pageNum = 1;
|
|
228
236
|
listForm.total = 0;
|
|
229
237
|
getDataList();
|
|
@@ -264,8 +272,8 @@ function editOne(item, index) {
|
|
|
264
272
|
}
|
|
265
273
|
formShow.value = true;
|
|
266
274
|
setTimeout(() => {
|
|
267
|
-
(document.querySelector(
|
|
268
|
-
inputs = Array.from(document.querySelectorAll(
|
|
275
|
+
(document.querySelector('#i18nFormItem1 input') as HTMLInputElement)?.focus();
|
|
276
|
+
inputs = Array.from(document.querySelectorAll('.i18n-form-item input'));
|
|
269
277
|
}, 500);
|
|
270
278
|
}
|
|
271
279
|
|
|
@@ -292,7 +300,7 @@ function saveOne() {
|
|
|
292
300
|
data.id = formData.adTranslateId;
|
|
293
301
|
}
|
|
294
302
|
for (const key in formData) {
|
|
295
|
-
if (key !==
|
|
303
|
+
if (key !== 'key' && langList.includes(key)) {
|
|
296
304
|
const val = formData[key];
|
|
297
305
|
data.content[key] = val;
|
|
298
306
|
}
|
|
@@ -301,7 +309,7 @@ function saveOne() {
|
|
|
301
309
|
http
|
|
302
310
|
.request({
|
|
303
311
|
url,
|
|
304
|
-
method:
|
|
312
|
+
method: 'POST',
|
|
305
313
|
data,
|
|
306
314
|
})
|
|
307
315
|
.then((res) => {
|
|
@@ -324,11 +332,11 @@ function saveOne() {
|
|
|
324
332
|
}
|
|
325
333
|
|
|
326
334
|
function delOne(id) {
|
|
327
|
-
ElMessageBox.confirm(
|
|
335
|
+
ElMessageBox.confirm('确认删除这条翻译记录吗?').then(() => {
|
|
328
336
|
http
|
|
329
337
|
.request({
|
|
330
338
|
url: deleteUrl,
|
|
331
|
-
method:
|
|
339
|
+
method: 'POST',
|
|
332
340
|
data: {
|
|
333
341
|
id,
|
|
334
342
|
},
|
|
@@ -345,19 +353,19 @@ function delOne(id) {
|
|
|
345
353
|
}
|
|
346
354
|
|
|
347
355
|
function delMore() {
|
|
348
|
-
ElMessageBox.confirm(
|
|
356
|
+
ElMessageBox.confirm('确认删除选中的翻译记录吗?').then(async () => {
|
|
349
357
|
let ids = i18nList.value?.getSelectionRows().map((row) => row.adTranslateId);
|
|
350
358
|
if (ids && ids.length) {
|
|
351
359
|
let len = ids.length;
|
|
352
360
|
let loading = ElLoadingService({
|
|
353
|
-
text:
|
|
361
|
+
text: '正在删除选中的翻译……',
|
|
354
362
|
});
|
|
355
363
|
for (let i = 0; i < ids.length; i++) {
|
|
356
364
|
const id = ids[i];
|
|
357
365
|
loading.setText(`正在删除... ${i + 1}/${len}`);
|
|
358
366
|
await http.request({
|
|
359
367
|
url: deleteUrl,
|
|
360
|
-
method:
|
|
368
|
+
method: 'POST',
|
|
361
369
|
data: {
|
|
362
370
|
id,
|
|
363
371
|
},
|
|
@@ -371,18 +379,18 @@ function delMore() {
|
|
|
371
379
|
|
|
372
380
|
const formItems = reactive<VxeFormPropTypes.Items>([
|
|
373
381
|
{
|
|
374
|
-
field:
|
|
382
|
+
field: 'key',
|
|
375
383
|
span: 24,
|
|
376
|
-
title:
|
|
384
|
+
title: '翻译键值',
|
|
377
385
|
itemRender: {
|
|
378
|
-
name:
|
|
379
|
-
props: {
|
|
386
|
+
name: '$input',
|
|
387
|
+
props: {class: 'i18n-form-item', id: `i18nFormItem${1}`},
|
|
380
388
|
},
|
|
381
389
|
},
|
|
382
390
|
]);
|
|
383
391
|
|
|
384
392
|
const fromRules = reactive<VxeFormPropTypes.Rules>({
|
|
385
|
-
key: [{
|
|
393
|
+
key: [{required: true, type: 'string', message: '请输入翻译键值'}],
|
|
386
394
|
});
|
|
387
395
|
|
|
388
396
|
let needInit = true;
|
|
@@ -395,15 +403,15 @@ watch(
|
|
|
395
403
|
listColumns.push({
|
|
396
404
|
field: item.value,
|
|
397
405
|
title: item.label,
|
|
398
|
-
minWidth:
|
|
406
|
+
minWidth: '200',
|
|
399
407
|
});
|
|
400
408
|
formItems.push({
|
|
401
409
|
field: item.value,
|
|
402
410
|
span: 24,
|
|
403
411
|
title: item.label,
|
|
404
412
|
itemRender: {
|
|
405
|
-
name:
|
|
406
|
-
props: {
|
|
413
|
+
name: '$input',
|
|
414
|
+
props: {class: 'i18n-form-item', id: `i18nFormItem${index + 2}`},
|
|
407
415
|
},
|
|
408
416
|
});
|
|
409
417
|
});
|
|
@@ -417,24 +425,24 @@ watch(
|
|
|
417
425
|
|
|
418
426
|
onMounted(() => {
|
|
419
427
|
getDataList();
|
|
420
|
-
window.addEventListener(
|
|
421
|
-
let {
|
|
422
|
-
if (key ===
|
|
428
|
+
window.addEventListener('keydown', (e) => {
|
|
429
|
+
let {key, ctrlKey, altKey} = e;
|
|
430
|
+
if (key === 's' && ctrlKey) {
|
|
423
431
|
e.preventDefault();
|
|
424
432
|
e.stopPropagation();
|
|
425
433
|
saveOne();
|
|
426
434
|
}
|
|
427
|
-
if (key ===
|
|
435
|
+
if (key === 'ArrowRight' && (ctrlKey || altKey)) {
|
|
428
436
|
e.preventDefault();
|
|
429
437
|
e.stopPropagation();
|
|
430
438
|
nextOne();
|
|
431
439
|
}
|
|
432
|
-
if (key ===
|
|
440
|
+
if (key === 'ArrowLeft' && (ctrlKey || altKey)) {
|
|
433
441
|
e.preventDefault();
|
|
434
442
|
e.stopPropagation();
|
|
435
443
|
prevOne();
|
|
436
444
|
}
|
|
437
|
-
if (key ===
|
|
445
|
+
if (key === 'Tab') {
|
|
438
446
|
e.preventDefault();
|
|
439
447
|
e.stopPropagation();
|
|
440
448
|
if (
|
|
@@ -454,7 +462,7 @@ onMounted(() => {
|
|
|
454
462
|
} else {
|
|
455
463
|
setTimeout(() => {
|
|
456
464
|
if (!document.activeElement || !inputs.includes(document.activeElement as HTMLInputElement)) {
|
|
457
|
-
(document.querySelector(
|
|
465
|
+
(document.querySelector('#i18nFormItem1 input') as HTMLInputElement)?.focus();
|
|
458
466
|
}
|
|
459
467
|
}, 100);
|
|
460
468
|
}
|
|
@@ -475,8 +483,21 @@ onMounted(() => {
|
|
|
475
483
|
padding: 0 8px;
|
|
476
484
|
flex: 1;
|
|
477
485
|
.el-form--inline .el-form-item {
|
|
478
|
-
|
|
479
|
-
|
|
486
|
+
margin-bottom: 0;
|
|
487
|
+
margin-right: 18px;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
.import-excel-button {
|
|
492
|
+
position: relative;
|
|
493
|
+
.import-excel-input {
|
|
494
|
+
position: absolute;
|
|
495
|
+
left: 0;
|
|
496
|
+
top: 0;
|
|
497
|
+
opacity: 0;
|
|
498
|
+
width: 100%;
|
|
499
|
+
height: 100%;
|
|
500
|
+
z-index: 10;
|
|
480
501
|
}
|
|
481
502
|
}
|
|
482
503
|
}
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
File without changes
|