V 3.0.1 LaiTool V3.0.1-preview.4
This commit is contained in:
parent
36178fbe5d
commit
f64c7ad677
BIN
default.realm
BIN
default.realm
Binary file not shown.
Binary file not shown.
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "laitool",
|
||||
"version": "3.0.1-preview.3",
|
||||
"version": "3.0.1-preview.4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "laitool",
|
||||
"version": "3.0.1-preview.3",
|
||||
"version": "3.0.1-preview.4",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@alicloud/alimt20181012": "^1.2.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "laitool",
|
||||
"version": "3.0.1-preview.3",
|
||||
"version": "3.0.1-preview.4",
|
||||
"description": "An AI tool for image processing, video processing, and other functions.",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "laitool.cn",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -20,4 +20,7 @@ export enum TranslateAPIType {
|
||||
|
||||
// 阿里翻译
|
||||
ALI = 'ali',
|
||||
|
||||
// Laitool GPT翻译
|
||||
LAITOOL = 'laitool',
|
||||
}
|
||||
|
||||
@ -12,6 +12,8 @@ let fspromises = require('fs').promises
|
||||
import { SoftwareService } from '../../define/db/service/SoftWare/softwareService'
|
||||
import { isEmpty } from 'lodash'
|
||||
import { ValidateJson } from '../../define/Tools/validate'
|
||||
import { GetOpenAISuccessResponse } from '../../define/response/openAIResponse'
|
||||
import { successMessage } from './generalTools'
|
||||
|
||||
let { Signer } = require('@volcengine/openapi')
|
||||
|
||||
@ -191,6 +193,10 @@ export class Translate {
|
||||
return await this.TranslateReturnNowTencent(value)
|
||||
} else if (this.translationBusiness.includes('aliyun')) {
|
||||
return await this.TranslateReturnNowAliyun(value)
|
||||
} else if (this.translationBusiness.includes('laitool')) {
|
||||
return await this.TranslateReturnNowGPT(value)
|
||||
} else {
|
||||
throw new Error('未知的翻译API,请检查设置')
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
@ -227,6 +233,8 @@ export class Translate {
|
||||
} else if (this.translationBusiness.includes('aliyun')) {
|
||||
// 阿里云翻译
|
||||
return await this.TranslatePromptAliyun(value)
|
||||
} else {
|
||||
throw new Error('反推这边不支持GPT翻译,请选择其他的翻译API')
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
@ -236,6 +244,139 @@ export class Translate {
|
||||
}
|
||||
}
|
||||
|
||||
//#region LaiTool GPT翻译
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value 使用laitool GPT翻译
|
||||
*/
|
||||
async TranslateReturnNowGPT(value) {
|
||||
try {
|
||||
// 判断该当前的翻译API
|
||||
let translateData = value[0]
|
||||
let from = value[1]
|
||||
let to = value[2]
|
||||
if (value[3]) {
|
||||
throw new Error('使用GPT翻译不支持拆分')
|
||||
}
|
||||
let model = this.translationAppId
|
||||
let token = this.translationSecret
|
||||
|
||||
let data = {
|
||||
model: model,
|
||||
messages: []
|
||||
}
|
||||
// 开始调用GPT进行翻译
|
||||
if (from == 'en' && to == "zh") {
|
||||
data.messages.push({
|
||||
"role": "system",
|
||||
"content": '我想让你充当英译中专家,用中文100%还原描述,不要加其他的联想,只翻译字面意思,请检查所有信息是否准确,并在回答时保持简活,不需要任何其他反馈。'
|
||||
})
|
||||
// 添加示例
|
||||
data.messages.push({
|
||||
"role": "user",
|
||||
"content": 'A woman in her twenties with messy hair and a look of shock and despair. She is wearing a simple white shirt and jeans. Her face shows mixed emotions. The background is a dim and quiet room. The historical background is modern. The screen content is a close-up of the woman’s face with tear marks.'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "assistant",
|
||||
"content": '一位二十多岁的女人,头发凌乱,表情震惊和绝望。她穿着一件简单的白色衬衫和牛仔裤。她的脸上显示出复杂的情感。背景是一个昏暗安静的房间。历史背景是现代的。屏幕内容是女人脸部的特写,带有泪痕。'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "user",
|
||||
"content": 'A twenty-something woman with short curly hair, smiling, wearing a casual white shirt and jeans, sitting on a comfortable sofa with a cup of coffee in her hand. She is in a small and cozy living room with a few books on the bookshelf, modern interior design, and natural light pouring into the room in the late afternoon. Screen content: Part of the sofa cushions.'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "assistant",
|
||||
"content": '一位二十多岁的女性,留着短卷发,面带微笑,穿着休闲的白色衬衫和牛仔裤,手拿一杯咖啡,坐在一个舒适的沙发上。她所在的是一个小而温馨的客厅,书架上有几本书,现代室内设计,下午晚些时候,自然光线洒进房间。屏幕内容:沙发垫的一部分。'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "user",
|
||||
"content": 'In a modern city, a streamlined car is parked on the street. A man in his thirties, with short brown hair combed back, a calm, confident look, tall and thin in a clean white shirt and black pants, sits in the car. The interior of the car is clean and modern, and the background is blurred to highlight the man\'s calm demeanor. The man\'s cell phone is ringing. The scene is set in the present.'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "assistant",
|
||||
"content": '在现代城市,一辆流线型轿车停在街上。一个三十多岁的男人,短短的棕色头发梳向后,神情冷静,自信,穿着干净的白衬衫和黑裤子,身材高挑瘦长,坐在车里。车内干净而现代,背景模糊,以突出男人平静的神态。男人的手机正在响。场景设定在现在。'
|
||||
})
|
||||
} else if (from == 'zh' && to == "en") {
|
||||
data.messages.push({
|
||||
"role": "system",
|
||||
"content": '我想让你充当中译英专家,用中文100%还原描述,不要加其他的联想,只翻译字面意思,请检查所有信息是否准确,并在回答时保持简活,不需要任何其他反馈。'
|
||||
})
|
||||
// 添加示例
|
||||
data.messages.push({
|
||||
"role": "user",
|
||||
"content": '一位二十多岁的女人,头发凌乱,表情震惊和绝望。她穿着一件简单的白色衬衫和牛仔裤。她的脸上显示出复杂的情感。背景是一个昏暗安静的房间。历史背景是现代的。屏幕内容是女人脸部的特写,带有泪痕。'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "assistant",
|
||||
"content": 'A woman in her twenties with messy hair and a look of shock and despair. She is wearing a simple white shirt and jeans. Her face shows mixed emotions. The background is a dim and quiet room. The historical background is modern. The screen content is a close-up of the woman’s face with tear marks.'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "user",
|
||||
"content": '一位二十多岁的女性,留着短卷发,面带微笑,穿着休闲的白色衬衫和牛仔裤,手拿一杯咖啡,坐在一个舒适的沙发上。她所在的是一个小而温馨的客厅,书架上有几本书,现代室内设计,下午晚些时候,自然光线洒进房间。屏幕内容:沙发垫的一部分。'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "assistant",
|
||||
"content": 'A twenty-something woman with short curly hair, smiling, wearing a casual white shirt and jeans, sitting on a comfortable sofa with a cup of coffee in her hand. She is in a small and cozy living room with a few books on the bookshelf, modern interior design, and natural light pouring into the room in the late afternoon. Screen content: Part of the sofa cushions.'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "user",
|
||||
"content": '在现代城市,一辆流线型轿车停在街上。一个三十多岁的男人,短短的棕色头发梳向后,神情冷静,自信,穿着干净的白衬衫和黑裤子,身材高挑瘦长,坐在车里。车内干净而现代,背景模糊,以突出男人平静的神态。男人的手机正在响。场景设定在现在。'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "assistant",
|
||||
"content": 'In a modern city, a streamlined car is parked on the street. A man in his thirties, with short brown hair combed back, a calm, confident look, tall and thin in a clean white shirt and black pants, sits in the car. The interior of the car is clean and modern, and the background is blurred to highlight the man\'s calm demeanor. The man\'s cell phone is ringing. The scene is set in the present.'
|
||||
})
|
||||
} else {
|
||||
throw new Error("GPT翻译只支持中英互译")
|
||||
}
|
||||
|
||||
data.messages.push({
|
||||
role: 'user',
|
||||
content: translateData
|
||||
})
|
||||
|
||||
let config = {
|
||||
method: 'post',
|
||||
maxBodyLength: Infinity,
|
||||
url: this.translationBusiness,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${token}`
|
||||
},
|
||||
data: JSON.stringify(data)
|
||||
}
|
||||
let res = await axios.request(config)
|
||||
// 将返回的数据进行拼接数据处理
|
||||
|
||||
let res_data = []
|
||||
let content = GetOpenAISuccessResponse(res.data)
|
||||
|
||||
if (to == 'zh') {
|
||||
res_data.push({
|
||||
src: translateData,
|
||||
dst: content
|
||||
})
|
||||
} else if (to == 'en') {
|
||||
res_data.push({
|
||||
src: content,
|
||||
dst: translateData
|
||||
})
|
||||
}
|
||||
|
||||
// 直接返回数据
|
||||
return {
|
||||
code: 1,
|
||||
to: to,
|
||||
data: res_data
|
||||
}
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
/**
|
||||
* 阿里云翻译写入队列中
|
||||
* @param {*} value
|
||||
|
||||
@ -15,6 +15,7 @@ let fspromises = require("fs").promises;
|
||||
import { SoftwareService } from "../../../define/db/service/SoftWare/softwareService";
|
||||
import { isEmpty } from "lodash";
|
||||
import { ValidateJson } from "../../../define/Tools/validate";
|
||||
import { GetOpenAISuccessResponse } from "../../../define/response/openAIResponse";
|
||||
|
||||
let {
|
||||
Signer
|
||||
@ -66,106 +67,6 @@ export class Translate {
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 将整句翻译的任务添加到数据库队列中
|
||||
// * @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:当前要翻译的字符串
|
||||
@ -188,7 +89,10 @@ export class Translate {
|
||||
return await this.TranslateReturnNowTencent(value);
|
||||
} else if (this.translationBusiness.includes("aliyun")) {
|
||||
return await this.TranslateReturnNowAliyun(value);
|
||||
} else {
|
||||
} else if (this.translationBusiness.includes("laitool")) {
|
||||
return await this.TranslateReturnNowGPT(value);
|
||||
}
|
||||
else {
|
||||
throw new Error("没有找到对应的翻译API")
|
||||
}
|
||||
|
||||
@ -197,192 +101,131 @@ export class Translate {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加翻译任务到队列中
|
||||
* @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);
|
||||
}
|
||||
//#region LAITOOL GPT翻译(只支持这个)
|
||||
|
||||
} catch (error) {
|
||||
return {
|
||||
code: 0,
|
||||
message: error.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//#region 阿里云翻译
|
||||
/**
|
||||
* 阿里云翻译写入队列中
|
||||
* @param {*} value
|
||||
*
|
||||
* @param value 使用laitool GPT翻译
|
||||
*/
|
||||
async TranslatePromptAliyun(value) {
|
||||
async TranslateReturnNowGPT(value: TranslateModel.TranslateNowReturnParams): Promise<GeneralResponse.SuccessItem> {
|
||||
try {
|
||||
let win = global.newWindow.filter(item => item.id == value[3])[0];
|
||||
if (!win) {
|
||||
win = global.newWindow[0];
|
||||
// 判断该当前的翻译API
|
||||
let from = value.from;
|
||||
let to = value.to;
|
||||
if (value.isSplit) {
|
||||
throw new Error("使用GPT翻译不支持拆分");
|
||||
}
|
||||
let translateData = value[0];
|
||||
let from = value[1];
|
||||
let to = value[2];
|
||||
let batch = DEFINE_STRING.QUEUE_BATCH.TRANSLATE_PROMPT;
|
||||
let model = this.translationAppId;
|
||||
let token = this.translationSecret;
|
||||
|
||||
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)
|
||||
let data = {
|
||||
"model": model,
|
||||
messages: []
|
||||
}
|
||||
// 监听总批次完成
|
||||
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: "翻译任务已加入队列任务中"
|
||||
// 开始调用GPT进行翻译
|
||||
if (from == 'en' && to == "zh") {
|
||||
data.messages.push({
|
||||
"role": "system",
|
||||
"content": '我想让你充当英译中专家,用中文100%还原描述,不要加其他的联想,只翻译字面意思,请检查所有信息是否准确,并在回答时保持简活,不需要任何其他反馈。'
|
||||
})
|
||||
// 添加示例
|
||||
data.messages.push({
|
||||
"role": "user",
|
||||
"content": 'A woman in her twenties with messy hair and a look of shock and despair. She is wearing a simple white shirt and jeans. Her face shows mixed emotions. The background is a dim and quiet room. The historical background is modern. The screen content is a close-up of the woman’s face with tear marks.'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "assistant",
|
||||
"content": '一位二十多岁的女人,头发凌乱,表情震惊和绝望。她穿着一件简单的白色衬衫和牛仔裤。她的脸上显示出复杂的情感。背景是一个昏暗安静的房间。历史背景是现代的。屏幕内容是女人脸部的特写,带有泪痕。'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "user",
|
||||
"content": 'A twenty-something woman with short curly hair, smiling, wearing a casual white shirt and jeans, sitting on a comfortable sofa with a cup of coffee in her hand. She is in a small and cozy living room with a few books on the bookshelf, modern interior design, and natural light pouring into the room in the late afternoon. Screen content: Part of the sofa cushions.'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "assistant",
|
||||
"content": '一位二十多岁的女性,留着短卷发,面带微笑,穿着休闲的白色衬衫和牛仔裤,手拿一杯咖啡,坐在一个舒适的沙发上。她所在的是一个小而温馨的客厅,书架上有几本书,现代室内设计,下午晚些时候,自然光线洒进房间。屏幕内容:沙发垫的一部分。'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "user",
|
||||
"content": 'In a modern city, a streamlined car is parked on the street. A man in his thirties, with short brown hair combed back, a calm, confident look, tall and thin in a clean white shirt and black pants, sits in the car. The interior of the car is clean and modern, and the background is blurred to highlight the man\'s calm demeanor. The man\'s cell phone is ringing. The scene is set in the present.'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "assistant",
|
||||
"content": '在现代城市,一辆流线型轿车停在街上。一个三十多岁的男人,短短的棕色头发梳向后,神情冷静,自信,穿着干净的白衬衫和黑裤子,身材高挑瘦长,坐在车里。车内干净而现代,背景模糊,以突出男人平静的神态。男人的手机正在响。场景设定在现在。'
|
||||
})
|
||||
} else if (from == 'zh' && to == "en") {
|
||||
data.messages.push({
|
||||
"role": "system",
|
||||
"content": '我想让你充当中译英专家,用中文100%还原描述,不要加其他的联想,只翻译字面意思,请检查所有信息是否准确,并在回答时保持简活,不需要任何其他反馈。'
|
||||
})
|
||||
// 添加示例
|
||||
data.messages.push({
|
||||
"role": "user",
|
||||
"content": '一位二十多岁的女人,头发凌乱,表情震惊和绝望。她穿着一件简单的白色衬衫和牛仔裤。她的脸上显示出复杂的情感。背景是一个昏暗安静的房间。历史背景是现代的。屏幕内容是女人脸部的特写,带有泪痕。'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "assistant",
|
||||
"content": 'A woman in her twenties with messy hair and a look of shock and despair. She is wearing a simple white shirt and jeans. Her face shows mixed emotions. The background is a dim and quiet room. The historical background is modern. The screen content is a close-up of the woman’s face with tear marks.'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "user",
|
||||
"content": '一位二十多岁的女性,留着短卷发,面带微笑,穿着休闲的白色衬衫和牛仔裤,手拿一杯咖啡,坐在一个舒适的沙发上。她所在的是一个小而温馨的客厅,书架上有几本书,现代室内设计,下午晚些时候,自然光线洒进房间。屏幕内容:沙发垫的一部分。'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "assistant",
|
||||
"content": 'A twenty-something woman with short curly hair, smiling, wearing a casual white shirt and jeans, sitting on a comfortable sofa with a cup of coffee in her hand. She is in a small and cozy living room with a few books on the bookshelf, modern interior design, and natural light pouring into the room in the late afternoon. Screen content: Part of the sofa cushions.'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "user",
|
||||
"content": '在现代城市,一辆流线型轿车停在街上。一个三十多岁的男人,短短的棕色头发梳向后,神情冷静,自信,穿着干净的白衬衫和黑裤子,身材高挑瘦长,坐在车里。车内干净而现代,背景模糊,以突出男人平静的神态。男人的手机正在响。场景设定在现在。'
|
||||
})
|
||||
data.messages.push({
|
||||
"role": "assistant",
|
||||
"content": 'In a modern city, a streamlined car is parked on the street. A man in his thirties, with short brown hair combed back, a calm, confident look, tall and thin in a clean white shirt and black pants, sits in the car. The interior of the car is clean and modern, and the background is blurred to highlight the man\'s calm demeanor. The man\'s cell phone is ringing. The scene is set in the present.'
|
||||
})
|
||||
} else {
|
||||
throw new Error("GPT翻译只支持中英互译")
|
||||
}
|
||||
|
||||
data.messages.push({
|
||||
"role": "user",
|
||||
"content": value.text
|
||||
});
|
||||
|
||||
let config = {
|
||||
method: 'post',
|
||||
maxBodyLength: Infinity,
|
||||
url: this.translationBusiness,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
data: JSON.stringify(data)
|
||||
};
|
||||
let res = await axios.request(config);
|
||||
// 将返回的数据进行拼接数据处理
|
||||
|
||||
let res_data = [];
|
||||
let content = GetOpenAISuccessResponse(res.data);
|
||||
res_data.push({
|
||||
src: value.text,
|
||||
dst: content
|
||||
});
|
||||
return successMessage({
|
||||
to: to,
|
||||
data: res_data
|
||||
}, `GPT${from == "en" ? '英' : '中'}译${from == "en" ? '英' : '中'}翻译成功`, 'Translate_TranslateReturnNowGPT');
|
||||
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region 阿里云翻译
|
||||
|
||||
/**
|
||||
* 阿里云翻译实时返回
|
||||
* @param {*} value
|
||||
@ -565,155 +408,6 @@ export class Translate {
|
||||
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 火山引擎翻译
|
||||
@ -801,154 +495,6 @@ export class Translate {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 火山引擎翻译所有数据队列返回
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取火山引擎请求的签名
|
||||
*/
|
||||
@ -984,134 +530,6 @@ export class Translate {
|
||||
//#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
|
||||
|
||||
@ -55,6 +55,12 @@ export class TranslateService {
|
||||
selectModel: TranslateAPIType.BAIDU,
|
||||
translation_auto: true,
|
||||
translates: [
|
||||
{
|
||||
name: TranslateAPIType.LAITOOL,
|
||||
translation_business: "https://api.laitool.cc/v1/chat/completions",
|
||||
translation_app_id: "gpt-4o-mini",
|
||||
translation_secret: "LAI API 令牌"
|
||||
},
|
||||
{
|
||||
name: TranslateAPIType.BAIDU,
|
||||
translation_business: "https://fanyi-api.baidu.com/api/trans/vip/translate",
|
||||
@ -105,6 +111,20 @@ export class TranslateService {
|
||||
}
|
||||
translateSetting = JSON.parse(translateSettingString);
|
||||
}
|
||||
|
||||
// v3.0.1 preview 4 版本新增laitool gpt翻译,之前版本没有,这边要检测下是不是有配置,没有初始化
|
||||
let index = translateSetting.translates.findIndex(item => item.name == TranslateAPIType.LAITOOL);
|
||||
if (index < 0) {
|
||||
// 初始化,将数据加在最前面
|
||||
let laitool = {
|
||||
name: TranslateAPIType.LAITOOL,
|
||||
translation_business: "https://api.laitool.cc/v1/chat/completions",
|
||||
translation_app_id: "gpt-4o-mini",
|
||||
translation_secret: "LAI API 令牌"
|
||||
}
|
||||
translateSetting.translates.unshift(laitool)
|
||||
}
|
||||
|
||||
return successMessage(translateSetting, "获取翻译设置成功", "TranslateService_GetTranslateSetting")
|
||||
} catch (error) {
|
||||
return errorMessage("获取翻译设置失败,失败信息如下:" + error.toString(), "TranslateService_GetTranslateSetting")
|
||||
@ -133,6 +153,14 @@ export class TranslateService {
|
||||
async SaveTranslateSetting(value: TranslateModel.TranslateModel): Promise<GeneralResponse.SuccessItem | GeneralResponse.ErrorItem> {
|
||||
try {
|
||||
let res = this.softwareService.SaveSoftwarePropertyData('translationSetting', JSON.stringify(value))
|
||||
// 这边要判断是不是用的laitool
|
||||
let laitool = value.translates.filter(item => item.name == TranslateAPIType.LAITOOL)
|
||||
if (laitool.length > 0) {
|
||||
let laitoolData = laitool[0]
|
||||
if (!laitoolData.translation_business.includes('laitool')) {
|
||||
throw new Error("不允许修改laitool的地址为其他外站地址")
|
||||
}
|
||||
}
|
||||
return successMessage(value, "保存翻译设置成功", "TranslateService_SaveTranslateSetting")
|
||||
} catch (error) {
|
||||
return errorMessage("保存翻译设置失败,失败信息如下:" + error.toString(), "TranslateService_SaveTranslateSetting")
|
||||
@ -193,7 +221,6 @@ export class TranslateService {
|
||||
let srcString = ""
|
||||
if (element.isSplit) {
|
||||
let dstStrs = []
|
||||
|
||||
} else {
|
||||
// 没有拆分的,只有一句
|
||||
srcString = data.data[0].dst
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
<n-select
|
||||
style="width: 160px"
|
||||
v-model:value="formValue.gptType"
|
||||
@update:value="UpdateSelectPromptType"
|
||||
:options="gptTypeOptions"
|
||||
placeholder="请选择提示词类型"
|
||||
>
|
||||
@ -88,6 +89,7 @@ export default defineComponent({
|
||||
{ label: 'DouBao', value: 'doubao' }
|
||||
])
|
||||
let softwareStore = useSoftwareStore()
|
||||
let allPromptDataOptions = ref([])
|
||||
|
||||
// 加载服务端数据
|
||||
async function InitServerGptOptions() {
|
||||
@ -105,6 +107,7 @@ export default defineComponent({
|
||||
gptDataOptions.value = gptRes.data.promptData.map((item) => {
|
||||
return { label: item.name, value: item.id }
|
||||
})
|
||||
allPromptDataOptions.value = gptRes.data.promptData
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
@ -134,7 +137,6 @@ export default defineComponent({
|
||||
* AI设置相关
|
||||
*/
|
||||
async function AISetting() {
|
||||
debugger
|
||||
// 判断当前数据是不是存在
|
||||
// 处理数据。获取当前的所有的数据
|
||||
let dialogWidth = 800
|
||||
@ -172,14 +174,29 @@ export default defineComponent({
|
||||
softwareStore.spin.spinning = false
|
||||
return
|
||||
}
|
||||
|
||||
newWord.value = res.data
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择的提示词类型发生变化时,删选提示词预设
|
||||
* @param value
|
||||
* @param options
|
||||
*/
|
||||
async function UpdateSelectPromptType(value, options) {
|
||||
gptDataOptions.value = allPromptDataOptions.value
|
||||
.filter((item) => {
|
||||
return item.promptTypeId == value
|
||||
})
|
||||
.map((item) => {
|
||||
return { label: item.name, value: item.id }
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
formValue,
|
||||
gptTypeOptions,
|
||||
gptDataOptions,
|
||||
UpdateSelectPromptType,
|
||||
oldWord,
|
||||
newWord,
|
||||
rules,
|
||||
@ -187,7 +204,8 @@ export default defineComponent({
|
||||
AISetting,
|
||||
gptOptions,
|
||||
softwareStore,
|
||||
ActionStart
|
||||
ActionStart,
|
||||
allPromptDataOptions
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -436,8 +436,10 @@ export default defineComponent({
|
||||
await window.api.TranslatePrompt(
|
||||
[JSON.stringify([row]), 'en', 'zh', window.id, false],
|
||||
(value) => {
|
||||
|
||||
console.log(value)
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -559,13 +561,11 @@ export default defineComponent({
|
||||
})
|
||||
|
||||
window.api.setEventListen([DEFINE_STRING.TRANSLATE_RETURN_REFRESH, window.id], (value) => {
|
||||
|
||||
if (value.code == 0) {
|
||||
message.error('返回数据错误')
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 直接
|
||||
let index = data.value.findIndex((item) => item.id == value.rowId)
|
||||
if (index < 0) {
|
||||
@ -620,8 +620,10 @@ export default defineComponent({
|
||||
async function TranslatePrompt(translateData, from, to) {
|
||||
console.log(translateData)
|
||||
await window.api.TranslatePrompt([translateData, from, to, window.id, true], (value) => {
|
||||
|
||||
console.log(value)
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -629,7 +631,6 @@ export default defineComponent({
|
||||
* 翻译中文到提示词
|
||||
*/
|
||||
async function TranslateChineseToPrompt() {
|
||||
|
||||
// 将当前的prompt和Chinese_prompt中的src全部删除(全部重新翻译)
|
||||
let fileterData = []
|
||||
for (let i = 0; i < data.value.length; i++) {
|
||||
@ -650,8 +651,10 @@ export default defineComponent({
|
||||
let tmp_str = JSON.stringify(fileterData)
|
||||
// 开始调用
|
||||
await window.api.TranslatePrompt([tmp_str, 'zh', 'en', window.id, true], (value) => {
|
||||
|
||||
console.log(value)
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -780,7 +783,6 @@ export default defineComponent({
|
||||
// 翻译立即返回
|
||||
// 翻译单个。马上返回
|
||||
await window.api.TranslateReturnNow([tmp_s, 'en', 'zh', true], (value) => {
|
||||
|
||||
console.log(value)
|
||||
if (value.code == 0) {
|
||||
message.error(value.message)
|
||||
|
||||
@ -439,7 +439,7 @@ export default defineComponent({
|
||||
dialog.create({
|
||||
showIcon: false,
|
||||
title: '翻译设置',
|
||||
content: () => h(TranslateSetting),
|
||||
content: () => h(TranslateSetting, { height: dialogHeight }),
|
||||
style: `width : ${dialogWidth}px; height : ${dialogHeight}px`,
|
||||
maskClosable: false
|
||||
})
|
||||
|
||||
@ -1,51 +1,60 @@
|
||||
<template>
|
||||
<div style="display: flex">
|
||||
<div style="display: flex; align-items: center">
|
||||
<div style="width: 200px">选择翻译服务商:</div>
|
||||
<n-select v-model:value="translateSetting.selectModel" :options="translateOptions"></n-select>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; margin-left: 20px">
|
||||
<n-checkbox v-model:checked="translateSetting.translation_auto"> 是否自动翻译 </n-checkbox>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; margin-left: 20px">
|
||||
<n-button :type="block ? 'warning' : 'primary'" @click="ModifyBlock">{{
|
||||
block ? '解锁' : '锁定'
|
||||
}}</n-button>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; margin-left: 20px">
|
||||
<n-button type="error" @click="ResetTranslateSetting">重置数据</n-button>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; margin-left: 20px">
|
||||
<n-button type="info" @click="SaveTranslateSetting">保存</n-button>
|
||||
<div id="translate-setting">
|
||||
<div style="display: flex">
|
||||
<div style="display: flex; align-items: center">
|
||||
<div style="width: 200px">选择翻译服务商:</div>
|
||||
<n-select
|
||||
v-model:value="translateSetting.selectModel"
|
||||
:options="translateOptions"
|
||||
></n-select>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; margin-left: 20px">
|
||||
<n-checkbox v-model:checked="translateSetting.translation_auto"> 是否自动翻译 </n-checkbox>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; margin-left: 20px">
|
||||
<n-button :type="block ? 'warning' : 'primary'" @click="ModifyBlock">{{
|
||||
block ? '解锁' : '锁定'
|
||||
}}</n-button>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; margin-left: 20px">
|
||||
<n-button type="error" @click="ResetTranslateSetting">重置数据</n-button>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; margin-left: 20px">
|
||||
<n-button type="info" @click="SaveTranslateSetting">保存</n-button>
|
||||
</div>
|
||||
</div>
|
||||
<n-card
|
||||
v-for="item in translateSetting.translates"
|
||||
style="margin-top: 10px"
|
||||
:title="GetTranslationName(item.name)"
|
||||
size="medium"
|
||||
>
|
||||
<n-form label-placement="left" inline="">
|
||||
<n-form-item label="API URL:">
|
||||
<n-input
|
||||
:disabled="block"
|
||||
style="width: 250px"
|
||||
v-model:value="item.translation_business"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="APP ID/应用ID:">
|
||||
<n-input
|
||||
:type="item.name == 'laitool' ? 'text' : 'password'"
|
||||
:show-password-on="mousedown"
|
||||
v-model:value="item.translation_app_id"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="产品密钥:">
|
||||
<n-input
|
||||
type="password"
|
||||
show-password-on="mousedown"
|
||||
v-model:value="item.translation_secret"
|
||||
/>
|
||||
</n-form-item>
|
||||
<!-- </div> -->
|
||||
</n-form>
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card
|
||||
v-for="item in translateSetting.translates"
|
||||
style="margin-top: 10px"
|
||||
:title="GetTranslationName(item.name)"
|
||||
size="medium"
|
||||
>
|
||||
<n-form label-placement="left" inline="">
|
||||
<n-form-item label="API URL:">
|
||||
<n-input :disabled="block" style="width: 250px" v-model:value="item.translation_business" />
|
||||
</n-form-item>
|
||||
<n-form-item label="APP ID/应用ID:">
|
||||
<n-input
|
||||
type="password"
|
||||
show-password-on="mousedown"
|
||||
v-model:value="item.translation_app_id"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="产品密钥:">
|
||||
<n-input
|
||||
type="password"
|
||||
show-password-on="mousedown"
|
||||
v-model:value="item.translation_secret"
|
||||
/>
|
||||
</n-form-item>
|
||||
<!-- </div> -->
|
||||
</n-form>
|
||||
</n-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -65,13 +74,18 @@ import { TranslateAPIType } from '../../../../define/enum/translate'
|
||||
|
||||
export default defineComponent({
|
||||
components: { NCard, NInput, NSelect, NButton, NCheckbox, NForm, NFormItem },
|
||||
|
||||
setup() {
|
||||
props: ['height'],
|
||||
setup(props) {
|
||||
let message = useMessage()
|
||||
let dialog = useDialog()
|
||||
let translateSetting = ref({})
|
||||
let block = ref(true)
|
||||
let height = ref(props.height)
|
||||
onMounted(async () => {
|
||||
let div = document.getElementById('translate-setting')
|
||||
div.style.height = height.value - 70 + 'px'
|
||||
div.style.overflow = 'auto'
|
||||
|
||||
// 初始化加载数据
|
||||
let translateSettingRes = await window.translate.GetTranslateSetting()
|
||||
if (translateSettingRes.code == 0) {
|
||||
@ -83,6 +97,8 @@ export default defineComponent({
|
||||
|
||||
function GetTranslationName(name) {
|
||||
switch (name) {
|
||||
case 'laitool':
|
||||
return 'Laitool GPT翻译'
|
||||
case 'baidu':
|
||||
return '百度翻译'
|
||||
case 'tencent':
|
||||
@ -125,7 +141,7 @@ export default defineComponent({
|
||||
// 判断当前选中的数据是不是设置完善
|
||||
let selectModel = translateSetting.value.selectModel
|
||||
let settingIndex = translateSetting.value.translates.findIndex(
|
||||
(item) => (item.name == selectModel)
|
||||
(item) => item.name == selectModel
|
||||
)
|
||||
if (settingIndex < 0) {
|
||||
message.error('未找到选中的数据,请检查')
|
||||
@ -152,6 +168,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
return {
|
||||
height,
|
||||
translateSetting,
|
||||
GetTranslationName,
|
||||
ResetTranslateSetting,
|
||||
@ -159,6 +176,10 @@ export default defineComponent({
|
||||
ModifyBlock,
|
||||
block,
|
||||
translateOptions: [
|
||||
{
|
||||
label: 'laitool GPT翻译',
|
||||
value: TranslateAPIType.LAITOOL
|
||||
},
|
||||
{
|
||||
label: '百度翻译',
|
||||
value: TranslateAPIType.BAIDU
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user