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' 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 { constructor(global) { this.global = global this.tools = new Tools() } /** * 初始化翻译设置 */ async InitTranslate() { if (!this.softwareService) { this.softwareService = await SoftwareService.getInstance() } // 获取翻译设置 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 { await this.InitTranslate() 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] // 添加任务到队列 this.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 this.global.fileQueue.enqueue(async () => { let json_path = path.join( this.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)) }) this.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 ) } // 监听总批次完成 this.global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => { if (failedTasks.length > 0) { let message = ` 翻译任务都已完成。 但是以下任务执行失败: ` failedTasks.forEach(({ taskId, error }) => { message += `${taskId}-, \n 错误信息: ${error}` + '\n' }) this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, { code: 0, message: message }) } else { if (value[4]) { this.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) { 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) } } catch (error) { return { code: 0, message: error.toString() } } } /** * 添加翻译任务到队列中 * @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() } } } /** * 阿里云翻译写入队列中 * @param {*} value */ async TranslatePromptAliyun(value) { try { let win = this.global.newWindow.filter((item) => item.id == value[3])[0] if (!win) { win = this.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] this.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 = [] // { // "src": "blush", // "dst": "脸红" // } 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 this.global.fileQueue.enqueue(async () => { let json_path = path.join( this.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 ) } // 监听总批次完成 this.global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => { if (failedTasks.length > 0) { let message = ` 翻译任务都已完成。 但是以下任务执行失败: ` failedTasks.forEach(({ taskId, error }) => { message += `${taskId}-, \n 错误信息: ${error}` + '\n' }) this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, { code: 0, message: message }) } else { if (value[4]) { this.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) { try { // 判断该当前的翻译API let from = value[1] let to = value[2] let ts_d = value[0].replaceAll('_', ' ').replaceAll(',', ',') let req_data = {} let req_count = 0 let req_arr = [] if (value[3]) { 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 { code: 1, to: to, data: res_data } } catch (error) { throw error } } /** * 腾讯翻译实时返回 * @param {*} value */ async TranslateReturnNowTencent(value) { try { // 判断该当前的翻译API let from = value[1] let to = value[2] let ts_d = value[0].replaceAll('_', ' ').replaceAll(',', ',') let req_data = [] if (value[3]) { 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: 30 // 请求超时时间,默认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 { code: 1, to: to, data: res_data } } catch (error) { throw error } } /** * 腾讯翻译将翻译的消息写入到队列中 * @param {*} value */ async TranslatePromptTencent(value) { try { let win = this.global.newWindow.filter((item) => item.id == value[3])[0] if (!win) { win = this.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] this.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 this.global.fileQueue.enqueue(async () => { let json_path = path.join( this.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 ) } // 监听总批次完成 this.global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => { if (failedTasks.length > 0) { let message = ` 翻译任务都已完成。 但是以下任务执行失败: ` failedTasks.forEach(({ taskId, error }) => { message += `${taskId}-, \n 错误信息: ${error}` + '\n' }) this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, { code: 0, message: message }) } else { if (value[4]) { this.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 TranslateReturnNowVolcengine(value) { try { // 判断该当前的翻译API let from = value[1] let to = value[2] let ts_d = value[0].replaceAll('_', ' ').replaceAll(',', ',') let req_data = [] if (value[3]) { 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 { code: 1, to: to, data: res_data } } catch (error) { throw error } } /** * 火山引擎翻译所有数据队列返回 * @param {*} value */ async TranslatePromptVolcengine(value) { try { let win = this.global.newWindow.filter((item) => item.id == value[3])[0] if (!win) { win = this.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] this.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 this.global.fileQueue.enqueue(async () => { let json_path = path.join( this.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 ) } // 监听总批次完成 this.global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => { if (failedTasks.length > 0) { let message = ` 翻译任务都已完成。 但是以下任务执行失败: ` failedTasks.forEach(({ taskId, error }) => { message += `${taskId}-, \n 错误信息: ${error}` + '\n' }) this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, { code: 0, message: message }) } else { if (value[4]) { this.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 } } /** * 百度引擎翻译翻译所有数据 * @param {} value * @returns */ async TranslatePromptBaidu(value) { try { let win = this.global.newWindow.filter((item) => item.id == value[3])[0] if (!win) { win = this.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] this.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 this.global.fileQueue.enqueue(async () => { let json_path = path.join( this.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 ) } // 监听总批次完成 this.global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => { if (failedTasks.length > 0) { let message = ` 翻译任务都已完成。 但是以下任务执行失败: ` failedTasks.forEach(({ taskId, error }) => { message += `${taskId}-, \n 错误信息: ${error}` + '\n' }) this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, { code: 0, message: message }) } else { if (value[4]) { this.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) { try { // 判断该当前的翻译API let from = value[1] let to = value[2] let appId = this.translationAppId let ts_d = value[0].replaceAll('_', ' ').replaceAll(',', ',') if (value[3]) { 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: 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) } } // 直接返回数据 return { code: 1, to: to, data: res_data } } catch (error) { throw error } } }