import { DEFINE_STRING } from "../../../define/define_string"; const tencentcloud = require("tencentcloud-sdk-nodejs") import { define } from "../../../define/define"; import { MD5 } from "crypto-js"; import axios from "axios"; import path from "path"; import { Tools } from "../../tools"; import { successMessage } from "../../Public/generalTools"; import { GeneralResponse } from "../../../model/generalResponse"; import { TranslateModel } from "../../../model/translate"; const alimt20181012 = require('@alicloud/alimt20181012'); const OpenApi = require('@alicloud/openapi-client'); const Util = require('@alicloud/tea-util'); let fspromises = require("fs").promises; import { SoftwareService } from "../../../define/db/service/SoftWare/softwareService"; import { isEmpty } from "lodash"; import { ValidateJson } from "../../../define/Tools/validate"; let { Signer } = require('@volcengine/openapi'); export class Translate { tools: Tools; softwareService: SoftwareService; translationBusiness: string; translationAppId: string; translationSecret: string; constructor() { this.tools = new Tools(); } /** * 初始化翻译设置 */ private async InitTranslate() { if (!this.softwareService) { this.softwareService = await SoftwareService.getInstance(); } // 获取翻译设置 if (!this.translationBusiness || !this.translationAppId || !this.translationSecret) { let translateSetting = this.softwareService.GetSoftWarePropertyData("translationSetting"); if (isEmpty(translateSetting)) { throw new Error("翻译设置为空,请先设置"); } let tryParse = ValidateJson(translateSetting); if (!tryParse) { throw new Error("翻译设置的格式错误,请重置后重新添加"); } let translateSettingData = JSON.parse(translateSetting); let selectModel = translateSettingData.selectModel; let translateIndex = translateSettingData.translates.findIndex(item => item.name == selectModel); if (translateIndex < 0) { throw new Error("没有找到对应的翻译API设置"); } let translateData = translateSettingData.translates[translateIndex]; for (const key in translateData) { if (!translateData[key]) { throw new Error(`翻译设置中的 ${key} 不能为空`); } } this.translationBusiness = translateData.translation_business; this.translationAppId = translateData.translation_app_id; this.translationSecret = translateData.translation_secret; } } // /** // * 将整句翻译的任务添加到数据库队列中 // * @param {*} value // * 0 第 0 个参数是要翻译的数据(数组) // * 1 第 1 个参数是源语言 // * 2 第 2 个参数是目标语言 // * 3 第 3 个参数是否分割(默认不分割false) // * 4 第 4 个参数是要不要全局弹窗提示 // * @returns // */ // async TranslateReturnNowTask(value) { // try { // value = JSON.parse(value); // let data = value[0]; // let to = value[2]; // let batch = DEFINE_STRING.QUEUE_BATCH.TRANSLATE_RETURN_NOW_TASK; // for (let i = 0; i < data.length; i++) { // const element = data[i]; // // 添加任务到队列 // global.requestQuene.enqueue(async () => { // try { // let res = await this.TranslateReturnNow([element.gpt_prompt, value[1], to, value[3], value[4]]); // if (res.code != 1) { // throw new Error(res.message); // } // let res_p = null; // if (!value[3]) { // if (to == "zh") { // res_p = res.data.map(item => item.dst).join(","); // } else { // res_p = res.data.map(item => item.src).join(","); // } // } else { // res_p = res.data; // } // // 修改chinese_prompt // global.fileQueue.enqueue(async () => { // let json_path = path.join(global.config.project_path, `tmp/input_crop/${element.name}.json`); // let prompt_json = JSON.parse(await fspromises.readFile(json_path, 'utf-8')); // if (!value[3]) { // prompt_json.gpt_prompt = res_p; // } else { // prompt_json.chinese_prompt = res_p; // } // await fspromises.writeFile(json_path, JSON.stringify(prompt_json)); // }) // global.newWindow[0].win.webContents.send(DEFINE_STRING.TRANSLATE_RETURN_REFRESH, { // code: 1, // to: to, // rowId: element.id, // data: res_p, // }) // } catch (error) { // throw error; // } // }, `${batch}_${element.name}`, batch) // } // // 监听总批次完成 // global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => { // if (failedTasks.length > 0) { // let message = ` // 翻译任务都已完成。 // 但是以下任务执行失败: // ` // failedTasks.forEach(({ taskId, error }) => { // message += `${taskId}-, \n 错误信息: ${error}` + '\n'; // }); // global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, { // code: 0, // message: message // }) // } else { // if (value[4]) { // global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, { // code: 1, // message: "翻译任务完成" // }) // } // } // }) // return { // code: 1, // message: "翻译任务已加入队列任务中" // } // } catch (error) { // return { // code: 0, // message: "翻译任务出错,错误信息: " + error.toString() // } // } // } /** * * @param {*} value 0:当前要翻译的字符串 * 1:源语言 * 2:目标语言 * 3:是否拆分(以逗号拆分) * [tags,'zh','en',false] */ async TranslateReturnNow(value: TranslateModel.TranslateNowReturnParams): Promise { try { await this.InitTranslate(); // 百度翻译 if (this.translationBusiness.includes("baidu")) { return await this.TranslateReturnNowBaidu(value); } else if (this.translationBusiness.includes("volcengine")) { // 火山引擎 return await this.TranslateReturnNowVolcengine(value); } else if (this.translationBusiness.includes("tencent")) { // 腾讯翻译 return await this.TranslateReturnNowTencent(value); } else if (this.translationBusiness.includes("aliyun")) { return await this.TranslateReturnNowAliyun(value); } else { throw new Error("没有找到对应的翻译API") } } catch (error) { throw error; } } /** * 添加翻译任务到队列中 * @param { * translateData :要翻译的数据 * from : 源语言 * to : 目标语言 * window.id : 显示的窗体的ID * isShow : 是不是提示 * [translateData, from, to, window.id,isShow] * } value */ async TranslatePrompt(value) { try { await this.InitTranslate(); value[0] = JSON.parse(value[0]) // baidu翻译 if (this.translationBusiness.includes("baidu")) { return await this.TranslatePromptBaidu(value); } else if (this.translationBusiness.includes("volcengine")) { // 火山引擎 return await this.TranslatePromptVolcengine(value); } else if (this.translationBusiness.includes("tencent")) { // 腾讯翻译 return await this.TranslatePromptTencent(value); } else if (this.translationBusiness.includes("aliyun")) { // 阿里云翻译 return await this.TranslatePromptAliyun(value); } } catch (error) { return { code: 0, message: error.toString() } } } //#region 阿里云翻译 /** * 阿里云翻译写入队列中 * @param {*} value */ async TranslatePromptAliyun(value) { try { let win = global.newWindow.filter(item => item.id == value[3])[0]; if (!win) { win = global.newWindow[0]; } let translateData = value[0]; let from = value[1]; let to = value[2]; let batch = DEFINE_STRING.QUEUE_BATCH.TRANSLATE_PROMPT; for (let i = 0; i < translateData.length; i++) { const element = translateData[i]; global.requestQuene.enqueue(async () => { if (translateData.length > 5) { await this.tools.delay(2000); } let arr_data = []; if (to == "zh") { let tmp_data = element.prompt; arr_data = tmp_data.replaceAll('_', ' ').replaceAll(',', ',').split(","); arr_data = arr_data.filter(item => item != '' && item != null); } else if (to == "en") { for (let j = 0; j < element.chinese_prompt.length; j++) { const item = element.chinese_prompt[j]; if (item != "" && item != null) { arr_data.push(item.dst); } } } // 如果为空(直接返回) if (arr_data.length <= 0) { return; } let req_data = {}; for (let j = 0; j < arr_data.length; j++) { const element = arr_data[j]; req_data[j.toString()] = element; } let config = new OpenApi.Config({ accessKeyId: this.translationAppId, accessKeySecret: this.translationSecret, }); config.endpoint = `mt.cn-hangzhou.aliyuncs.com`; let client = new alimt20181012.default(config); let getBatchTranslateRequest = new alimt20181012.GetBatchTranslateRequest({ apiType: 'translate_standard', scene: 'general', sourceLanguage: from, targetLanguage: to, formatType: 'text', sourceText: JSON.stringify(req_data), }); let runtime = new Util.RuntimeOptions({}); // 复制代码运行请自行打印 API 的返回值 let res = await client.getBatchTranslateWithOptions(getBatchTranslateRequest, runtime); console.log(res); // 处理返回的数据 // 检出返回的数据和输入的数据是不是一样的 let translateList = res.body.translatedList; if (translateList.length != arr_data.length) { throw new Error("请求的数据长度和返回的数据长度不一致。请重试"); } let res_data = []; if (to == "zh") { for (let j = 0; j < arr_data.length; j++) { const item = arr_data[j]; let res_tmp = translateList.find(item => item.index == j); let obj = { src: item, dst: res_tmp.translated, } res_data.push(obj); } } else if (to == 'en') { for (let j = 0; j < arr_data.length; j++) { const item = arr_data[j]; // 获取指定的index的返回数据 let res_tmp = translateList.find(item => item.index == j); let obj = { src: res_tmp.translated, dst: item } res_data.push(obj); } } // 数据返回。写入本地配置文件 // 修改chinese_prompt global.fileQueue.enqueue(async () => { let json_path = path.join(global.config.project_path, `tmp/input_crop/${element.name}.json`); let prompt_json = JSON.parse(await fspromises.readFile(json_path, 'utf-8')); prompt_json.chinese_prompt = res_data; await fspromises.writeFile(json_path, JSON.stringify(prompt_json)); }) win.win.webContents.send(DEFINE_STRING.TRANSLATE_RETURN_REFRESH, { code: 1, to: to, rowId: element.id, data: res_data, }) }, `${batch}_${element.name}`, batch) } // 监听总批次完成 global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => { if (failedTasks.length > 0) { let message = ` 翻译任务都已完成。 但是以下任务执行失败: ` failedTasks.forEach(({ taskId, error }) => { message += `${taskId}-, \n 错误信息: ${error}` + '\n'; }); global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, { code: 0, message: message }) } else { if (value[4]) { global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, { code: 1, message: "批次翻译任务完成" }) } } }) return { code: 1, message: "翻译任务已加入队列任务中" } } catch (error) { throw error; } } /** * 阿里云翻译实时返回 * @param {*} value */ async TranslateReturnNowAliyun(value: TranslateModel.TranslateNowReturnParams): Promise { try { // 判断该当前的翻译API let from = value.from; let to = value.to; let ts_d = value.text.replaceAll("_", " ").replaceAll(',', ","); let req_data = {}; let req_count = 0; let req_arr = []; if (value.isSplit) { let tmp_arr = ts_d.split(','); for (let i = 0; i < tmp_arr.length; i++) { const element = tmp_arr[i]; if (element != '' && element != null) { req_data[i.toString()] = element; req_arr.push(element); } req_count += 1; } } else { req_data["0"] = ts_d; req_count = 1; req_arr.push(ts_d); } if (req_count <= 0) { throw new Error("没有传入数据"); } let config = new OpenApi.Config({ accessKeyId: this.translationAppId, accessKeySecret: this.translationSecret, }); config.endpoint = `mt.cn-hangzhou.aliyuncs.com`; let client = new alimt20181012.default(config); let getBatchTranslateRequest = new alimt20181012.GetBatchTranslateRequest({ apiType: 'translate_standard', scene: 'general', sourceLanguage: from, targetLanguage: to, formatType: 'text', sourceText: JSON.stringify(req_data), }); let runtime = new Util.RuntimeOptions({}); // 复制代码运行请自行打印 API 的返回值 let res = await client.getBatchTranslateWithOptions(getBatchTranslateRequest, runtime); console.log(res); // 处理返回的数据 // 检出返回的数据和输入的数据是不是一样的 let translateList = res.body.translatedList; if (translateList.length != req_count) { throw new Error("请求的数据长度和返回的数据长度不一致。请重试"); } // { // "src": "blush", // "dst": "脸红" // } // 数据处理 let res_data = []; for (let j = 0; j < req_arr.length; j++) { const item = req_arr[j]; let res_tmp = translateList.find(item => item.index == j); if (to == "zh") { let obj = { src: item, dst: res_tmp.translated } res_data.push(obj); } else if (to == "en") { let obj = { src: res_tmp.translated, dst: item } res_data.push(obj); } } // 直接返回数据 return successMessage({ to: to, data: res_data }, '翻译成功', 'Translate_TranslateReturnNowAliyun'); } catch (error) { throw error; } } //#endregion //#region 腾讯翻译 /** * 腾讯翻译实时返回 * @param {*} value */ async TranslateReturnNowTencent(value: TranslateModel.TranslateNowReturnParams): Promise { try { // 判断该当前的翻译API let from = value.from; let to = value.to; let ts_d = value.text.replaceAll("_", " ").replaceAll(',', ","); let req_data = []; if (value.isSplit) { req_data = ts_d.split(','); } else { req_data.push(ts_d) } req_data = req_data.filter(item => item != "" && item != null); if (req_data.length <= 0) { throw new Error("没有传入数据"); } const CvmClient = tencentcloud.tmt.v20180321.Client; const client = new CvmClient({ credential: { secretId: this.translationAppId, secretKey: this.translationSecret }, // 产品地域 region: "ap-shanghai", // 可选配置实例 profile: { signMethod: "TC3-HMAC-SHA256", // 签名方法 httpProfile: { reqMethod: "POST", // 请求方法 reqTimeout: 60, // 请求超时时间,默认60s }, }, }) let res = await client.TextTranslateBatch({ SourceTextList: req_data, Source: from, Target: to, ProjectId: 0 }); console.log(res); // 处理返回的数据 // 检出返回的数据和输入的数据是不是一样的 let translateList = res.TargetTextList; if (translateList.length != req_data.length) { throw new Error("请求的数据长度和返回的数据长度不一致。请重试"); } // { // "src": "blush", // "dst": "脸红" // } // 数据处理 let res_data = []; for (let j = 0; j < req_data.length; j++) { const item = req_data[j]; if (to == "zh") { let obj = { src: item, dst: translateList[j] } res_data.push(obj); } else if (to == "en") { let obj = { src: translateList[j], dst: item } res_data.push(obj); } } // 直接返回数据 return successMessage({ to: to, data: res_data }, "翻译成功", 'Translate_TranslateReturnNowTencent'); } catch (error) { throw error; } } /** * 腾讯翻译将翻译的消息写入到队列中 * @param {*} value */ async TranslatePromptTencent(value) { try { let win = global.newWindow.filter(item => item.id == value[3])[0]; if (!win) { win = global.newWindow[0]; } let translateData = value[0]; let from = value[1]; let to = value[2]; let batch = DEFINE_STRING.QUEUE_BATCH.TRANSLATE_PROMPT; let secretId = this.translationAppId; let secretKey = this.translationSecret; const CvmClient = tencentcloud.tmt.v20180321.Client const client = new CvmClient({ credential: { secretId: secretId, secretKey: secretKey }, region: "ap-shanghai", profile: { signMethod: "TC3-HMAC-SHA256", // 签名方法 httpProfile: { reqMethod: "POST", // 请求方法 reqTimeout: 30, // 请求超时时间,默认60s }, }, }) for (let i = 0; i < translateData.length; i++) { const element = translateData[i]; global.requestQuene.enqueue(async () => { if (translateData.length > 5) { await this.tools.delay(2000); } let arr_data = []; if (to == "zh") { let tmp_data = element.prompt; arr_data = tmp_data.replaceAll('_', ' ').replaceAll(',', ',').split(","); arr_data = arr_data.filter(item => item != '' && item != null); } else if (to == "en") { for (let j = 0; j < element.chinese_prompt.length; j++) { const item = element.chinese_prompt[j]; if (item != "" && item != null) { arr_data.push(item.dst); } } } // 如果为空(直接返回) if (arr_data.length <= 0) { return; } // 请求数据 let req_data = { Source: from, Target: to, SourceTextList: arr_data, ProjectId: 0 } let res = await client.TextTranslateBatch(req_data); console.log(res); // 处理返回的数据 // 检出返回的数据和输入的数据是不是一样的 let translateList = res.TargetTextList; if (translateList.length != arr_data.length) { throw new Error("请求的数据长度和返回的数据长度不一致。请重试"); } let res_data = []; // { // "src": "blush", // "dst": "脸红" // } if (to == "zh") { for (let j = 0; j < arr_data.length; j++) { const item = arr_data[j]; let obj = { src: item, dst: translateList[j] } res_data.push(obj); } } else if (to == 'en') { for (let j = 0; j < arr_data.length; j++) { const item = arr_data[j]; let obj = { src: translateList[j], dst: item } res_data.push(obj); } } // 数据返回。写入本地配置文件 // 修改chinese_prompt global.fileQueue.enqueue(async () => { let json_path = path.join(global.config.project_path, `tmp/input_crop/${element.name}.json`); let prompt_json = JSON.parse(await fspromises.readFile(json_path, 'utf-8')); prompt_json.chinese_prompt = res_data; await fspromises.writeFile(json_path, JSON.stringify(prompt_json)); }) win.win.webContents.send(DEFINE_STRING.TRANSLATE_RETURN_REFRESH, { code: 1, to: to, rowId: element.id, data: res_data, }) }, `${batch}_${element.name}`, batch) } // 监听总批次完成 global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => { if (failedTasks.length > 0) { let message = ` 翻译任务都已完成。 但是以下任务执行失败: ` failedTasks.forEach(({ taskId, error }) => { message += `${taskId}-, \n 错误信息: ${error}` + '\n'; }); global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, { code: 0, message: message }) } else { if (value[4]) { global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, { code: 1, message: "批次翻译任务完成" }) } } }) return { code: 1, message: "翻译任务已加入队列任务中" } } catch (error) { throw error; } } //#endregion //#region 火山引擎翻译 /** * 火山引擎翻译实时返回 * @param {*} value */ async TranslateReturnNowVolcengine(value: TranslateModel.TranslateNowReturnParams): Promise { try { // 判断该当前的翻译API let from = value.from; let to = value.to; let ts_d = value.text.replaceAll("_", " ").replaceAll(',', ","); let req_data = []; if (value.isSplit) { req_data = ts_d.split(','); } else { req_data.push(ts_d) } if (req_data.length <= 0) { throw new Error("没有传入数据"); } let signer = await this.GetVolcengineSinger(); let config = { method: 'post', maxBodyLength: Infinity, url: `${this.translationBusiness}${signer}`, headers: { 'Content-Type': 'application/json' }, data: JSON.stringify({ SourceLanguage: from, TargetLanguage: to, TextList: req_data }) }; let res = await axios.request(config); if (res.status != 200) { throw new Error("请求错误。请检查网络"); } // 判断是不是有返回错误 if (res.data.ResponseMetadata && res.data.ResponseMetadata.Error) { let err = res.data.ResponseMetadata.Error; throw new Error(`错误码: ${err.Code} 错误编号:${err.CodeN} 错误详细信息:${err.Message}`); } // 处理返回的数据 // 检出返回的数据和输入的数据是不是一样的 let translateList = res.data.TranslationList; if (translateList.length != req_data.length) { throw new Error("请求的数据长度和返回的数据长度不一致。请重试"); } // { // "src": "blush", // "dst": "脸红" // } // 数据处理 let res_data = []; for (let j = 0; j < req_data.length; j++) { const item = req_data[j]; if (to == "zh") { let obj = { src: item, dst: translateList[j].Translation } res_data.push(obj); } else if (to == "en") { let obj = { src: translateList[j].Translation, dst: item } res_data.push(obj); } } // 直接返回数据 return successMessage({ to: to, data: res_data }, "翻译成功", 'Translate_TranslateReturnNowVolcengine'); } catch (error) { throw error; } } /** * 火山引擎翻译所有数据队列返回 * @param {*} value */ async TranslatePromptVolcengine(value) { try { let win = global.newWindow.filter(item => item.id == value[3])[0]; if (!win) { win = global.newWindow[0]; } let signer = await this.GetVolcengineSinger(); let translateData = value[0]; let from = value[1]; let to = value[2]; let batch = DEFINE_STRING.QUEUE_BATCH.TRANSLATE_PROMPT; for (let i = 0; i < translateData.length; i++) { const element = translateData[i]; global.requestQuene.enqueue(async () => { if (translateData.length > 5) { await this.tools.delay(2000); } let arr_data = []; if (to == "zh") { let tmp_data = element.prompt; arr_data = tmp_data.replaceAll('_', ' ').replaceAll(',', ',').split(","); arr_data = arr_data.filter(item => item != '' && item != null); } else if (to == "en") { for (let j = 0; j < element.chinese_prompt.length; j++) { const item = element.chinese_prompt[j]; if (item != "" && item != null) { arr_data.push(item.dst); } } } // 如果为空(直接返回) if (arr_data.length <= 0) { return; } // 开始请求 let req_data = JSON.stringify({ SourceLanguage: from, TargetLanguage: to, TextList: arr_data }) let config = { method: "post", maxBodyLength: Infinity, url: `${this.translationBusiness}${signer}`, headers: { 'Content-Type': 'application/json' }, data: req_data } let res = await axios.request(config); console.log(res); if (res.status != 200) { throw new Error("请求状态码错误。请检查网络"); } // 判断是不是有返回错误 if (res.data.ResponseMetadata && res.data.ResponseMetadata.Error) { let err = res.data.ResponseMetadata.Error; throw new Error(`错误码: ${err.Code} 错误编号:${err.CodeN} 错误详细信息:${err.Message}`); } // 处理返回的数据 // 检出返回的数据和输入的数据是不是一样的 let translateList = res.data.TranslationList; if (translateList.length != arr_data.length) { throw new Error("请求的数据长度和返回的数据长度不一致。请重试"); } let res_data = []; // { // "src": "blush", // "dst": "脸红" // } if (to == "zh") { for (let j = 0; j < arr_data.length; j++) { const item = arr_data[j]; let obj = { src: item, dst: translateList[j].Translation } res_data.push(obj); } } else if (to == 'en') { for (let j = 0; j < arr_data.length; j++) { const item = arr_data[j]; let obj = { src: translateList[j].Translation, dst: item } res_data.push(obj); } } // 数据返回。写入本地配置文件 // 修改chinese_prompt global.fileQueue.enqueue(async () => { let json_path = path.join(global.config.project_path, `tmp/input_crop/${element.name}.json`); let prompt_json = JSON.parse(await fspromises.readFile(json_path, 'utf-8')); prompt_json.chinese_prompt = res_data; await fspromises.writeFile(json_path, JSON.stringify(prompt_json)); }) win.win.webContents.send(DEFINE_STRING.TRANSLATE_RETURN_REFRESH, { code: 1, to: to, rowId: element.id, data: res_data, }) }, `${batch}_${element.name}`, batch) } // 监听总批次完成 global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => { if (failedTasks.length > 0) { let message = ` 翻译任务都已完成。 但是以下任务执行失败: ` failedTasks.forEach(({ taskId, error }) => { message += `${taskId}-, \n 错误信息: ${error}` + '\n'; }); global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, { code: 0, message: message }) } else { if (value[4]) { global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, { code: 1, message: "批次翻译任务完成" }) } } }) return { code: 1, message: "翻译任务已加入队列任务中" } } catch (error) { throw error; } } /** * 获取火山引擎请求的签名 */ async GetVolcengineSinger() { try { const openApiRequestData = { method: "POST", region: "cn-north-1", params: { Action: "TranslateText", Version: "2020-06-01", }, Service: "translate" } const credentials = { accessKeyId: this.translationAppId, secretKey: this.translationSecret } const signer = new Signer(openApiRequestData, "translate"); // 最终经过加签的 HTTP Query Params const signedQueryString = signer.getSignUrl(credentials); console.log(signedQueryString) return signedQueryString; } catch (error) { throw error; } } //#endregion //#region 百度翻译 /** * 百度引擎翻译翻译所有数据 * @param {} value * @returns */ async TranslatePromptBaidu(value) { try { let win = global.newWindow.filter(item => item.id == value[3])[0]; if (!win) { win = global.newWindow[0]; } let translateData = value[0]; let from = value[1]; let to = value[2]; let batch = DEFINE_STRING.QUEUE_BATCH.TRANSLATE_PROMPT; let appId = this.translationAppId; // 添加一个频次判断是不是演示 for (let i = 0; i < translateData.length; i++) { const element = translateData[i]; global.requestQuene.enqueue(async () => { try { if (translateData.length > 5) { await this.tools.delay(2000); } let ts_d = ""; if (to == "zh") { ts_d = element.prompt.replaceAll("_", " ").replaceAll(',', ",").replaceAll(',', "\n"); } else if (to == "en") { let tmp_arr = []; // 中文转英文。重新拼接一下 for (let j = 0; j < element.chinese_prompt.length; j++) { const item = element.chinese_prompt[j]; tmp_arr.push(item.dst); } ts_d = tmp_arr.join('\n'); } let salt = Date.now(); let sign = MD5(`${this.translationAppId}${ts_d}${salt}${this.translationSecret}`).toString(); let res = await axios.get(this.translationBusiness, { params: { q: ts_d, appid: appId, salt: salt, from: from, to: to, sign: sign } }); if (res.status != 200) { throw new Error("请求错误。请检查网络"); } // 判断是不是有错误码 if (res.data.error_code) { throw new Error(res.data.error_msg); } let res_data = [] // 将所有的数据协会到本地(然后发送消息到前台界面) if (res.data.to == "zh") { res_data = res.data.trans_result } else { // 直接在这边处理(前端不用处理) for (let i = 0; i < res.data.trans_result.length; i++) { const element = res.data.trans_result[i]; let obj = { src: element.dst, dst: element.src }; res_data.push(obj); } } // 修改chinese_prompt global.fileQueue.enqueue(async () => { let json_path = path.join(global.config.project_path, `tmp/input_crop/${element.name}.json`); let prompt_json = JSON.parse(await fspromises.readFile(json_path, 'utf-8')); prompt_json.chinese_prompt = res_data; await fspromises.writeFile(json_path, JSON.stringify(prompt_json)); }) win.win.webContents.send(DEFINE_STRING.TRANSLATE_RETURN_REFRESH, { code: 1, to: to, rowId: element.id, data: res_data, }) } catch (error) { throw error; } }, `${batch}_${element.name}`, batch); } // 监听总批次完成 global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => { if (failedTasks.length > 0) { let message = ` 翻译任务都已完成。 但是以下任务执行失败: ` failedTasks.forEach(({ taskId, error }) => { message += `${taskId}-, \n 错误信息: ${error}` + '\n'; }); global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, { code: 0, message: message }) } else { if (value[4]) { global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, { code: 1, message: "批次翻译任务完成" }) } } }) return { code: 1, message: "翻译任务已加入队列任务中" } } catch (error) { throw error; } } /** * 百度翻译引擎翻译单个数据。立即返回 * @param {*} value * @returns */ async TranslateReturnNowBaidu(value: TranslateModel.TranslateNowReturnParams) { try { // 判断该当前的翻译API let appId = this.translationAppId; let ts_d = value.text.replaceAll("_", " ").replaceAll(',', ","); if (value.isSplit) { ts_d = ts_d.replaceAll('.', "\n"); } let salt = Date.now(); let sign = MD5(`${this.translationAppId}${ts_d}${salt}${this.translationSecret}`).toString(); let res = await axios.get(this.translationBusiness, { params: { q: ts_d, appid: appId, salt: salt, from: value.from, to: value.to, sign: sign } }); if (res.status != 200) { throw new Error("请求错误。请检查网络"); } // 判断是不是有错误码 if (res.data.error_code) { throw new Error(res.data.error_msg); } let res_data = [] // 将所有的数据协会到本地(然后发送消息到前台界面) if (res.data.to == "zh") { res_data = res.data.trans_result } else { // 直接在这边处理(前端不用处理) for (let i = 0; i < res.data.trans_result.length; i++) { const element = res.data.trans_result[i]; let obj = { src: element.dst, dst: element.src }; res_data.push(obj); } } // 直接返回数据 return successMessage({ to: value.to, data: res_data }, '翻译成功', "Translate_TranslateReturnNowBaidu") } catch (error) { throw error; } } //#endregion }