Node.js使用百度翻译api实现文件翻译

35 阅读2分钟

整体思路:项目整体使用百度翻译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… 的文章改写的,后续的实现思路有不同,数据的更新方式也不同