5 changed files with 260 additions and 11 deletions
@ -0,0 +1,211 @@ |
|||
package com.bx.implatform.util; |
|||
|
|||
import cn.hutool.crypto.digest.DigestUtil; |
|||
import cn.hutool.http.HttpRequest; |
|||
import cn.hutool.http.HttpResponse; |
|||
import cn.hutool.json.JSONArray; |
|||
import cn.hutool.json.JSONObject; |
|||
import cn.hutool.json.JSONUtil; |
|||
import com.bx.implatform.entity.ImSetting; |
|||
import com.bx.implatform.entity.setting.domain.TranslationSetting; |
|||
import com.bx.implatform.enums.SettingEnum; |
|||
import com.bx.implatform.service.IImSettingService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
/** |
|||
* 有道翻译工具类 |
|||
*/ |
|||
@Slf4j |
|||
@Component |
|||
@RequiredArgsConstructor |
|||
public class YouDaoTranslationUtils { |
|||
|
|||
/** |
|||
* 有道翻译API地址 |
|||
*/ |
|||
private static final String YouDao_URL = "https://openapi.youdao.com/api"; |
|||
|
|||
/** |
|||
* 有道翻译APPID |
|||
*/ |
|||
private static final String APP_KEY = "20311d34bea5d593"; |
|||
|
|||
/** |
|||
* 有道翻译密钥 |
|||
*/ |
|||
private static final String APP_SECRET = "n1XjfaBApp9xed8YnmVNLaOlBqhEB6Wq"; |
|||
|
|||
private final IImSettingService settingService; |
|||
|
|||
/** |
|||
* 翻译文本 |
|||
* |
|||
* @param query 待翻译文本 |
|||
* @param from 源语言 |
|||
* @param to 目标语言 |
|||
* @return 翻译结果 |
|||
*/ |
|||
public String translate(String query, String from, String to) { |
|||
try { |
|||
// 生成随机数
|
|||
String salt = String.valueOf(System.currentTimeMillis()); |
|||
|
|||
// 生成当前时间戳
|
|||
String curtime = String.valueOf(System.currentTimeMillis() / 1000); |
|||
|
|||
// 生成签名:appKey + truncate(q) + salt + curtime + appSecret的SHA256值
|
|||
String signStr = APP_KEY + truncate(query) + salt + curtime + APP_SECRET; |
|||
String sign = DigestUtil.sha256Hex(signStr); |
|||
|
|||
// 发送请求
|
|||
HttpResponse response = HttpRequest.post(YouDao_URL) |
|||
.form("q", query) |
|||
.form("from", from) |
|||
.form("to", to) |
|||
.form("appKey", APP_KEY) |
|||
.form("salt", salt) |
|||
.form("sign", sign) |
|||
.form("signType", "v3") |
|||
.form("curtime", curtime) |
|||
.execute(); |
|||
|
|||
// 解析响应
|
|||
String body = response.body(); |
|||
JSONObject result = JSONUtil.parseObj(body); |
|||
|
|||
// 检查是否有错误
|
|||
if (result.containsKey("errorCode") && result.getStr("errorCode").equals("0")) { |
|||
log.error("有道翻译失败,错误码:{},错误信息:{}", result.getStr("errorCode"), result.getStr("errorMsg")); |
|||
return result.getStr("errorMsg") == null ? "system error" : "system error:" + result.getStr("errorMsg"); |
|||
} |
|||
|
|||
// 获取翻译结果
|
|||
JSONArray translationArray = result.getJSONArray("translation"); |
|||
if (translationArray == null || translationArray.isEmpty()) { |
|||
log.error("有道翻译结果为空"); |
|||
return "result empty"; |
|||
} |
|||
|
|||
// 返回第一条翻译结果
|
|||
return translationArray.getStr(0); |
|||
} catch (Exception e) { |
|||
log.error("有道翻译异常", e); |
|||
return "translation unknown error"; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 翻译文本(自动检测源语言) |
|||
* |
|||
* @param query 待翻译文本 |
|||
* @param to 目标语言 |
|||
* @return 翻译结果 |
|||
*/ |
|||
public String translate(String query, String to) { |
|||
return translate(query, "auto", to); |
|||
} |
|||
|
|||
/** |
|||
* 翻译文本 |
|||
* |
|||
* @param query 待翻译文本 |
|||
* @param from 源语言 |
|||
* @param to 目标语言 |
|||
* @return 翻译结果 |
|||
*/ |
|||
public String translateByAgentConfiguration(String query, String from, String to) { |
|||
try { |
|||
|
|||
ImSetting setting = settingService.getByTokenAndSettingName(SettingEnum.TRANSLATION_SETTING.name()); |
|||
TranslationSetting configuration = JSONUtil.toBean(setting.getSettingValue(), TranslationSetting.class); |
|||
|
|||
//转化语言标识
|
|||
to = convertTo(to); |
|||
|
|||
// 生成随机数
|
|||
String salt = String.valueOf(System.currentTimeMillis()); |
|||
|
|||
// 生成当前时间戳
|
|||
String curtime = String.valueOf(System.currentTimeMillis() / 1000); |
|||
|
|||
// 生成签名:appKey + truncate(q) + salt + curtime + appSecret的SHA256值
|
|||
String signStr = configuration.getAppKey() + truncate(query) + salt + curtime + configuration.getAppSecret(); |
|||
String sign = DigestUtil.sha256Hex(signStr); |
|||
|
|||
// 发送请求
|
|||
HttpResponse response = HttpRequest.post(YouDao_URL) |
|||
.form("q", query) |
|||
.form("from", from) |
|||
.form("to", to) |
|||
.form("appKey", configuration.getAppKey()) |
|||
.form("salt", salt) |
|||
.form("sign", sign) |
|||
.form("signType", "v3") |
|||
.form("curtime", curtime) |
|||
.execute(); |
|||
|
|||
// 解析响应
|
|||
String body = response.body(); |
|||
JSONObject result = JSONUtil.parseObj(body); |
|||
|
|||
// 检查是否有错误
|
|||
if (result.containsKey("errorCode") &&!result.getStr("errorCode").equals("0")) { |
|||
System.out.println(result); |
|||
log.error("有道翻译失败,错误码:{},错误信息:{}", result.getStr("errorCode"), result.getStr("errorMsg")); |
|||
return result.getStr("errorMsg") == null ? "system error" : "system error:" + result.getStr("errorMsg"); |
|||
} |
|||
System.out.println(result); |
|||
// 获取翻译结果
|
|||
JSONArray translationArray = result.getJSONArray("translation"); |
|||
if (translationArray == null || translationArray.isEmpty()) { |
|||
log.error("有道翻译结果为空"); |
|||
return "result empty"; |
|||
} |
|||
|
|||
// 返回第一条翻译结果
|
|||
return translationArray.getStr(0); |
|||
} catch (Exception e) { |
|||
log.error("有道翻译异常", e); |
|||
return "translation unknown error"; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 翻译文本(自动检测源语言) |
|||
* |
|||
* @param query 待翻译文本 |
|||
* @param to 目标语言 |
|||
* @return 翻译结果 |
|||
*/ |
|||
public String translateByAgentConfiguration(String query, String to) { |
|||
return translateByAgentConfiguration(query, "auto", to); |
|||
} |
|||
|
|||
/** |
|||
* 截断字符串用于生成签名 |
|||
* |
|||
* @param q 待截断的字符串 |
|||
* @return 截断后的字符串 |
|||
*/ |
|||
private String truncate(String q) { |
|||
if (q == null) { |
|||
return null; |
|||
} |
|||
int len = q.length(); |
|||
return len <= 20 ? q : (q.substring(0, 10) + len + q.substring(len - 10, len)); |
|||
} |
|||
|
|||
//转化to
|
|||
private String convertTo(String to) { |
|||
return switch (to) { |
|||
case "jp" -> "ja"; |
|||
case "kor" -> "ko"; |
|||
case "vie" -> "vi"; |
|||
case "fra" -> "fr"; |
|||
case "ara" -> "ar"; |
|||
default -> to; |
|||
}; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue