整体思路:项目整体使用百度翻译api做接口,处理文件数据格式,百度翻译api只支持字符串传输,需要处理数据,保证能够处理数组,对象等,使用promise做到能同时翻译多个语言,使用lowdb到数据能对应类名精准更新
-
创建两个lowdb数据库对页面配置文件语言和整体数据语言做区分
const DATA_FILE = path.join(__dirname, `data.json`);
var DATA_STORE = lowdb(new jsonSet(DATA_FILE));
const Terminal = path.join(__dirname, `terminal.json`);
var DATA_Ter = lowdb(new jsonSet(Terminal));
-
获取数据并提取出value的数据
this.creatObjValue = async (value, params) => {
let index = 0;
const obj = Array.isArray(value) ? [] : {};
// 提取所有对象中的value返回一个数组
const strDatas = Array.isArray(value) ? value : Object.values(value);
// 提取所有对象为 string的
const reqData = strDatas
.filter((item) => typeof item === "string")
.join("\n");
// 换行后挨个翻译
const res = reqData ? await this.requestApi(reqData, params) : [];
for (let key in value) {
if (typeof value[key] === "string") {
obj[key] = res[index].dst;
index++;
}
// name下为对象或数组
if (
Array.isArray(value[key]) ||
Object.prototype.toString.call(value[key]) === "[object Object]"
) {
obj[key] = await this.translateString(value[key]);
}
}
return obj;
};
-
翻译传入数据
this.requestApi = (value, params) => {
if (this.requestNumber >= this.config.requestNumber) {
return new Promise((resolve) => {
setTimeout(() => {
this.requestApi(value, params).then((res) => {
resolve(res);
});
}, 1000);
});
}
this.requestNumber++;
const { appid, secret } = this.config;
const q = value;
const salt = Math.random();
const sign = md5(`${appid}${q}${salt}${secret}`);
const fromData = {
...params,
q: encodeURIComponent(q),
sign,
appid,
salt,
};
const fanyiApi = this.createUrl(this.config.baseUrl, fromData);
return new Promise((resolve) => {
axios
.get(fanyiApi)
.then(({ data: res }) => {
if (this.config.showProgress) console.log("翻译结果:", res);
if (!res.error_code) {
const resList = res.trans_result;
resolve(resList);
}
})
.finally(() => {
setTimeout(() => {
this.requestNumber--;
}, 1000);
});
});
};
-
写入文件并做判断
function createFile(Name, fileContent,fileName) {
let oldData = DataManager.getData(Name,fileName)
// 判断翻译的语言字段是否存在,如果不存在新增类并全量更新
if(oldData){
DataManager._save(Name,fileContent,fileName)
}else{
DataManager.setData(Name,fileContent,fileName)
}
}
-
整体数据管理的方法
const DataManager = { getData: (par,failName) => { if(failName === "ter"){ return par ? DATA_Ter.get(par).value() : DATA_Ter.value(); }else{ return par ? DATA_STORE.get(par).value() : DATA_STORE.value(); } }, setData: (par, data,failName) => { if(failName === "ter"){ console.log("ter",data); return DATA_Ter.set(par, data).write(); }else{ return DATA_STORE.set(par, data).write(); } }, _save: (key, data,failName) => { const newKeys = Object.keys(data) if(failName === "ter"){ let old = DATA_Ter.get(key).value(); const oldKeys = Object.keys(old); newKeys.filter((item) => { if (!oldKeys.includes(item)) { // 有新的key就新增 DATA_Ter.get(key).set(item, data[item]).write() }else{ // 有相同的key就更新 DATA_Ter.get(key).assign({[item]:data[item]}).write() } }); }else{ let old = DATA_STORE.get(key).value(); const oldKeys = Object.keys(old); newKeys.filter((item) => { if (!oldKeys.includes(item)) { // 有新的key就新增 DATA_STORE.get(key).set(item, data[item]).write() }else{ // 有相同的key就更新 DATA_STORE.get(key).assign({[item]:data[item]}).write() // find主要用于查找数组中的元素。所以DATA_STORE.get(key).find({key:item}).assign({value:data[item]}).write()不适用当前数据结构 } }); } }, };
缺陷:没有做针对多层嵌套的对象类型数据增加,做精准更新,翻译出来的文档的首字母大小写没有统一,本插件基于blog.csdn.net/qq_42036203… 的文章改写的,后续的实现思路有不同,数据的更新方式也不同