From dc86e53e29bd05de664f3bc64c14b3dc07500ef0 Mon Sep 17 00:00:00 2001 From: La123123 <617330105@qq.com> Date: Fri, 24 Apr 2026 18:51:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9C=89=E9=81=93=E7=BF=BB?= =?UTF-8?q?=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/LoginController.java | 23 +- .../setting/domain/TranslationSetting.java | 10 +- .../implatform/service/IImSettingService.java | 2 + .../service/impl/ImSettingServiceImpl.java | 25 +++ .../util/YouDaoTranslationUtils.java | 211 ++++++++++++++++++ 5 files changed, 260 insertions(+), 11 deletions(-) create mode 100644 im-platform/src/main/java/com/bx/implatform/util/YouDaoTranslationUtils.java diff --git a/im-platform/src/main/java/com/bx/implatform/controller/LoginController.java b/im-platform/src/main/java/com/bx/implatform/controller/LoginController.java index c37253e..2e57ebd 100644 --- a/im-platform/src/main/java/com/bx/implatform/controller/LoginController.java +++ b/im-platform/src/main/java/com/bx/implatform/controller/LoginController.java @@ -12,6 +12,7 @@ import com.bx.implatform.service.IImSettingService; import com.bx.implatform.service.ImAgentService; import com.bx.implatform.service.UserService; import com.bx.implatform.util.BaiduTranslationUtils; +import com.bx.implatform.util.YouDaoTranslationUtils; import com.bx.implatform.vo.LoginVO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -32,6 +33,8 @@ public class LoginController { private final BaiduTranslationUtils baiduTranslationUtils; + private final YouDaoTranslationUtils youDaoTranslationUtils; + @PostMapping("/login") @Operation(summary = "用户登录", description = "用户登录") public Result login(@Valid @RequestBody LoginDTO dto) { @@ -96,20 +99,24 @@ public class LoginController { String country = jsonObject.getStr("country"); String trans = ""; - BaiduTranslationUtils translator = baiduTranslationUtils; - - //如果代理有配置,则使用代理的百度配置 - if(!settingService.isUseBaidu()) { + //如果代理有配置,则使用代理的配置 + if(settingService.isUseBaidu()) { + if (country == null || country.isEmpty()) { + trans = baiduTranslationUtils.translateByAgentConfiguration(str, "zh"); + } else { + trans = baiduTranslationUtils.translateByAgentConfiguration(str, country); + } + }else if(settingService.isUseYouDao()) { if (country == null || country.isEmpty()) { - trans = translator.translate(str, "zh"); + trans = youDaoTranslationUtils.translateByAgentConfiguration(str, "zh"); } else { - trans = translator.translate(str, country); + trans = youDaoTranslationUtils.translateByAgentConfiguration(str, country); } }else{ if (country == null || country.isEmpty()) { - trans = translator.translateByAgentConfiguration(str, "zh"); + trans = baiduTranslationUtils.translate(str, "zh"); } else { - trans = translator.translateByAgentConfiguration(str, country); + trans = baiduTranslationUtils.translate(str, country); } } diff --git a/im-platform/src/main/java/com/bx/implatform/entity/setting/domain/TranslationSetting.java b/im-platform/src/main/java/com/bx/implatform/entity/setting/domain/TranslationSetting.java index 33d725b..25cf631 100644 --- a/im-platform/src/main/java/com/bx/implatform/entity/setting/domain/TranslationSetting.java +++ b/im-platform/src/main/java/com/bx/implatform/entity/setting/domain/TranslationSetting.java @@ -8,12 +8,16 @@ import lombok.Setter; public class TranslationSetting { /** - * 翻译类型 0-默认管理员配置 1-百度翻译 2-谷歌翻译 + * 翻译类型 0-默认管理员配置 1-百度翻译 2-有道翻译 */ private String type = "0"; - private String appId = ""; + private String appId = "";//百度翻译使用 - private String secretKey = ""; + private String secretKey = "";//百度翻译使用 + + private String appKey = "";//有道翻译使用 + + private String appSecret = "";//有道翻译使用 } diff --git a/im-platform/src/main/java/com/bx/implatform/service/IImSettingService.java b/im-platform/src/main/java/com/bx/implatform/service/IImSettingService.java index 9e87e70..c872456 100644 --- a/im-platform/src/main/java/com/bx/implatform/service/IImSettingService.java +++ b/im-platform/src/main/java/com/bx/implatform/service/IImSettingService.java @@ -8,4 +8,6 @@ public interface IImSettingService extends IService { ImSetting getByTokenAndSettingName(String settingName); boolean isUseBaidu(); + + boolean isUseYouDao(); } diff --git a/im-platform/src/main/java/com/bx/implatform/service/impl/ImSettingServiceImpl.java b/im-platform/src/main/java/com/bx/implatform/service/impl/ImSettingServiceImpl.java index 3fdbecb..b273f82 100644 --- a/im-platform/src/main/java/com/bx/implatform/service/impl/ImSettingServiceImpl.java +++ b/im-platform/src/main/java/com/bx/implatform/service/impl/ImSettingServiceImpl.java @@ -70,4 +70,29 @@ public class ImSettingServiceImpl extends ServiceImpl queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(ImSetting::getUniqueToken, token); + queryWrapper.eq(ImSetting::getSettingName, SettingEnum.TRANSLATION_SETTING.name()); + ImSetting setting = baseMapper.selectOne(queryWrapper); + if(setting == null){ + return false; + } + + TranslationSetting baidu = JSONUtil.toBean(setting.getSettingValue(), TranslationSetting.class); + return baidu != null && baidu.getType().equals("2"); + } } diff --git a/im-platform/src/main/java/com/bx/implatform/util/YouDaoTranslationUtils.java b/im-platform/src/main/java/com/bx/implatform/util/YouDaoTranslationUtils.java new file mode 100644 index 0000000..a305f0c --- /dev/null +++ b/im-platform/src/main/java/com/bx/implatform/util/YouDaoTranslationUtils.java @@ -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; + }; + } +}