Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions src/main/java/com/star/easydoc/common/Consts.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ private Consts() {}
public static final Set<String> ENABLE_TRANSLATOR_SET = ImmutableSet.of(Consts.YOUDAO_TRANSLATOR,
Consts.BAIDU_TRANSLATOR, Consts.TENCENT_TRANSLATOR, Consts.ALIYUN_TRANSLATOR, Consts.YOUDAO_AI_TRANSLATOR,
Consts.MICROSOFT_TRANSLATOR, Consts.MICROSOFT_FREE_TRANSLATOR, Consts.GOOGLE_TRANSLATOR,
Consts.GOOGLE_FREE_TRANSLATOR, Consts.CHATGLM_GPT, Consts.LOCAL_DICTIONARY, Consts.SIMPLE_SPLITTER,
Consts.CLOSE_TRANSLATOR, Consts.CUSTOM_URL);
Consts.GOOGLE_FREE_TRANSLATOR, Consts.CHATGLM_GPT, Consts.OPENAI_GPT, Consts.OPENAI_TRANSLATOR, Consts.LOCAL_DICTIONARY, Consts.SIMPLE_SPLITTER,
Consts.CLOSE_TRANSLATOR, Consts.CUSTOM_URL, Consts.DEEPLX_TRANSLATOR);

/** AI翻译集合 */
public static final Set<String> AI_TRANSLATOR = ImmutableSet.of(Consts.CHATGLM_GPT);
public static final Set<String> AI_TRANSLATOR = ImmutableSet.of(Consts.CHATGLM_GPT, Consts.OPENAI_GPT);

/**
* 腾讯翻译
Expand Down Expand Up @@ -80,6 +80,14 @@ private Consts() {}
* 智谱清言
*/
public static final String CHATGLM_GPT = "智谱清言";
/**
* OpenAI API
*/
public static final String OPENAI_GPT = "OpenAI API";
/**
* OpenAI 翻译(复用 OpenAI 配置,走翻译流程)
*/
public static final String OPENAI_TRANSLATOR = "OpenAI 翻译";
/**
* 本地词典
*/
Expand All @@ -96,4 +104,9 @@ private Consts() {}
* 关闭翻译
*/
public static final String CLOSE_TRANSLATOR = "关闭(只使用自定义翻译)";
/**
* DeepLX 翻译
*/
public static final String DEEPLX_TRANSLATOR = "DeepLX 翻译";
}

56 changes: 56 additions & 0 deletions src/main/java/com/star/easydoc/config/EasyDocConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,16 @@ public class EasyDocConfig {
* chatglmApiKey
*/
private String chatGlmApiKey;
/** OpenAI apiKey */
private String openAiApiKey;
/** OpenAI 模型 */
private String openAiModel;
/** OpenAI Base URL */
private String openAiBaseUrl;
/** DeepLX Base URL */
private String deepLxBaseUrl;
/** DeepLX Token */
private String deepLxToken;
/**
* 微软key
*/
Expand Down Expand Up @@ -187,6 +197,12 @@ public void reset() {
accessKeySecret = null;
youdaoAppKey = null;
youdaoAppSecret = null;
chatGlmApiKey = null;
openAiApiKey = null;
openAiModel = null;
openAiBaseUrl = null;
deepLxBaseUrl = null;
deepLxToken = null;
wordMap = new TreeMap<>();
projectWordMap = new TreeMap<>();
classTemplateConfig = new TemplateConfig();
Expand Down Expand Up @@ -645,6 +661,46 @@ public void setChatGlmApiKey(String chatGlmApiKey) {
this.chatGlmApiKey = chatGlmApiKey;
}

public String getOpenAiApiKey() {
return openAiApiKey;
}

public void setOpenAiApiKey(String openAiApiKey) {
this.openAiApiKey = openAiApiKey;
}

public String getOpenAiModel() {
return openAiModel;
}

public String getOpenAiBaseUrl() {
return openAiBaseUrl;
}

public void setOpenAiBaseUrl(String openAiBaseUrl) {
this.openAiBaseUrl = openAiBaseUrl;
}

public String getDeepLxBaseUrl() {
return deepLxBaseUrl;
}

public String getDeepLxToken() {
return deepLxToken;
}

public void setDeepLxToken(String deepLxToken) {
this.deepLxToken = deepLxToken;
}

public void setDeepLxBaseUrl(String deepLxBaseUrl) {
this.deepLxBaseUrl = deepLxBaseUrl;
}

public void setOpenAiModel(String openAiModel) {
this.openAiModel = openAiModel;
}

public String getCoverMode() {
return coverMode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ private String generateWithAI(PsiElement psiElement) {
String prompt; // 定义提示变量
try {
// 将资源文件中的文本读取为字符串
prompt = IOUtils.toString(ResourceUtil.getResource(getClass(), "prompts/chatglm", "class.prompt"));
String folder = Consts.OPENAI_GPT.equals(config.getTranslator()) ? "prompts/openai" : "prompts/chatglm";
prompt = IOUtils.toString(ResourceUtil.getResource(getClass(), folder, "class.prompt"));
} catch (IOException e) {
// 如果发生IO异常,则抛出运行时异常
throw new RuntimeException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ public String generate(PsiElement psiElement) {
private String generateWithAI(PsiElement psiElement) {
String prompt;
try {
prompt = IOUtils.toString(ResourceUtil.getResource(getClass(), "prompts/chatglm", "field.prompt"));
String folder = Consts.OPENAI_GPT.equals(config.getTranslator()) ? "prompts/openai" : "prompts/chatglm";
prompt = IOUtils.toString(ResourceUtil.getResource(getClass(), folder, "field.prompt"));
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ private String getDefaultTemplate(PsiMethod psiMethod) {
private String generateWithAI(PsiElement psiElement) {
String prompt;
try {
prompt = IOUtils.toString(ResourceUtil.getResource(getClass(), "prompts/chatglm", "method.prompt"));
String folder = Consts.OPENAI_GPT.equals(config.getTranslator()) ? "prompts/openai" : "prompts/chatglm";
prompt = IOUtils.toString(ResourceUtil.getResource(getClass(), folder, "method.prompt"));
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/star/easydoc/service/gpt/GptService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.star.easydoc.common.Consts;
import com.star.easydoc.config.EasyDocConfig;
import com.star.easydoc.service.gpt.impl.ChatGlmGptSupplier;
import com.star.easydoc.service.gpt.impl.OpenAiGptSupplier;
import org.apache.commons.lang3.StringUtils;

/**
Expand Down Expand Up @@ -34,6 +35,7 @@ public void init(EasyDocConfig config) {
}
gptSupplierMap = ImmutableMap.<String, GptSupplier>builder()
.put(Consts.CHATGLM_GPT, new ChatGlmGptSupplier().init(config))
.put(Consts.OPENAI_GPT, new OpenAiGptSupplier().init(config))
.build();
this.config = config;
}
Expand Down
109 changes: 109 additions & 0 deletions src/main/java/com/star/easydoc/service/gpt/impl/OpenAiGptSupplier.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package com.star.easydoc.service.gpt.impl;

import com.alibaba.fastjson2.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.star.easydoc.common.util.HttpUtil;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;

/**
* OpenAI Chat Completions API
* https://api.openai.com/v1/chat/completions
*/
public class OpenAiGptSupplier extends AbstractGptSupplier {

private static final String DEFAULT_BASE = "https://api.openai.com/v1";
/** 超时 */
private static final int TIMEOUT = 30 * 1000;

@Override
public String chat(String content) {
String apiKey = getConfig().getOpenAiApiKey();
String model = getConfig().getOpenAiModel();
if (StringUtils.isBlank(apiKey) || StringUtils.isBlank(model)) {
return StringUtils.EMPTY;
}

Map<String, String> headers = Maps.newHashMap();
headers.put("Authorization", "Bearer " + apiKey);
headers.put("Content-Type", "application/json");

Message message = new Message();
message.setRole("user");
message.setContent(content);

OpenAiRequest request = new OpenAiRequest();
request.setModel(model);
request.setMessages(Lists.newArrayList(message));
request.setStream(false);

String base = StringUtils.isNotBlank(getConfig().getOpenAiBaseUrl()) ? getConfig().getOpenAiBaseUrl() : DEFAULT_BASE;
String url = base.endsWith("/") ? (base + "chat/completions") : (base + "/chat/completions");
String response = HttpUtil.postJson(url, headers, JSON.toJSONString(request), TIMEOUT);
String result = JSON.parseObject(response)
.getJSONArray("choices")
.getJSONObject(0)
.getJSONObject("message")
.getString("content");

// 复用 ChatGLM 的返回处理逻辑,提取 /** ... */
return "/**" + org.apache.commons.lang.StringUtils.substringBeforeLast(
org.apache.commons.lang.StringUtils.substringAfterLast(result, "/**"), "*/") + "*/";
}

// --- request/response payloads ---
private static class OpenAiRequest {
private String model;
private List<Message> messages;
private Boolean stream;

public String getModel() {
return model;
}

public void setModel(String model) {
this.model = model;
}

public List<Message> getMessages() {
return messages;
}

public void setMessages(List<Message> messages) {
this.messages = messages;
}

public Boolean getStream() {
return stream;
}

public void setStream(Boolean stream) {
this.stream = stream;
}
}

private static class Message {
private String role;
private String content;

public String getRole() {
return role;
}

public void setRole(String role) {
this.role = role;
}

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@
import com.star.easydoc.service.translator.impl.AliyunTranslator;
import com.star.easydoc.service.translator.impl.BaiduTranslator;
import com.star.easydoc.service.translator.impl.CustomTranslator;
import com.star.easydoc.service.translator.impl.DeepLXTranslator;
import com.star.easydoc.service.translator.impl.GoogleFreeTranslator;
import com.star.easydoc.service.translator.impl.GoogleTranslator;
import com.star.easydoc.service.translator.impl.JinshanTranslator;
import com.star.easydoc.service.translator.impl.LocalTranslator;
import com.star.easydoc.service.translator.impl.MicrosoftFreeTranslator;
import com.star.easydoc.service.translator.impl.MicrosoftTranslator;
import com.star.easydoc.service.translator.impl.OpenAiTranslator;
import com.star.easydoc.service.translator.impl.SimpleSplitterTranslator;
import com.star.easydoc.service.translator.impl.TencentTranslator;
import com.star.easydoc.service.translator.impl.YoudaoAiTranslator;
Expand Down Expand Up @@ -68,6 +70,8 @@ public void init(EasyDocConfig config) {
.put(Consts.MICROSOFT_FREE_TRANSLATOR, new MicrosoftFreeTranslator().init(config))
.put(Consts.GOOGLE_TRANSLATOR, new GoogleTranslator().init(config))
.put(Consts.GOOGLE_FREE_TRANSLATOR, new GoogleFreeTranslator().init(config))
.put(Consts.DEEPLX_TRANSLATOR, new DeepLXTranslator().init(config))
.put(Consts.OPENAI_TRANSLATOR, new OpenAiTranslator().init(config))
.put(Consts.SIMPLE_SPLITTER, new SimpleSplitterTranslator().init(config))
.put(Consts.LOCAL_DICTIONARY, new LocalTranslator().init(config))
.put(Consts.CUSTOM_URL, new CustomTranslator().init(config))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.star.easydoc.service.translator.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Maps;
import com.intellij.openapi.diagnostic.Logger;
import com.star.easydoc.common.util.HttpUtil;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;

/**
* DeepLX 翻译
* 文档参考: https://deeplx.owo.network/endpoints/free.html
*
* 使用说明:
* - 默认使用公共免费端点:https://deeplx.owo.network/translate
* - 如需自建或替换,请在设置中为“DeepLX 翻译”配置 DeepLX 地址(独立字段,不再复用自定义HTTP)
* - 如有鉴权令牌,可在设置中“密钥”处填写(将作为 Authorization: Bearer ${token} 发送)
*/
public class DeepLXTranslator extends AbstractTranslator {

private static final Logger LOGGER = Logger.getInstance(DeepLXTranslator.class);
private static final String DEFAULT_URL = "https://deeplx.owo.network/translate";

@Override
protected String translateCh2En(String text) {
return translate("ZH", "EN", text);
}

@Override
protected String translateEn2Ch(String text) {
return translate("EN", "ZH", text);
}

private String translate(String from, String to, String query) {
String cfg = getConfig().getDeepLxBaseUrl();
String url = StringUtils.isBlank(cfg) ? DEFAULT_URL : cfg;
String json = null;
try {
Map<String, String> headers = Maps.newHashMap();
if (StringUtils.isNotBlank(getConfig().getDeepLxToken())) {
headers.put("Authorization", "Bearer " + getConfig().getDeepLxToken());
}
JSONObject body = new JSONObject();
body.put("text", query);
body.put("source_lang", from);
body.put("target_lang", to);

json = HttpUtil.postJson(url, headers, JSON.toJSONString(body), getConfig().getTimeout());
JSONObject resp = JSON.parseObject(json);
if (resp == null) {
return StringUtils.EMPTY;
}
Integer code = resp.getInteger("code");
if (code != null && code == 200) {
return StringUtils.defaultString(resp.getString("data"));
}
LOGGER.error(String.format("deeplx translate error:url:%s,response:%s", url, json));
return StringUtils.EMPTY;
} catch (Exception e) {
LOGGER.error(String.format("deeplx translate error:url:%s,response:%s", url, json), e);
return StringUtils.EMPTY;
}
}
}

Loading