tanbin 7 месяцев назад
Родитель
Сommit
ca160c802d

+ 114 - 0
authorize-api-service/src/main/java/com/xy/service/TranslateService.java

@@ -0,0 +1,114 @@
+package com.xy.service;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.xy.annotate.RestMappingController;
+import com.xy.dto.TranslateDto;
+import com.xy.entity.SysMenu;
+import com.xy.service.impl.SysMenuServiceImpl;
+import com.xy.third.baidu.TransApi;
+import com.xy.utils.R;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.client.loadbalancer.AsyncLoadBalancerAutoConfiguration;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 翻译服务
+ */
+@Api(tags = "翻译服务")
+@Slf4j
+@Service
+@RequiredArgsConstructor
+@RestMappingController("/translate")
+public class TranslateService {
+
+    private static final String APP_ID = "20240428002037687";
+    private static final String SECURITY_KEY = "nXkFm4SaA2Wrmb42Xmky";
+    private final SysMenuServiceImpl sysMenuService;
+    private final AsyncLoadBalancerAutoConfiguration asyncLoadBalancerAutoConfiguration;
+
+    /**
+     * 调用百度翻译API
+     *
+     * @param query  待翻译的文本
+     * @param lanSrc 原语言 zh
+     * @param lanDst 目标语言 en
+     * @return
+     */
+    public static String translate(String query, String lanSrc, String lanDst) {
+        TransApi api = new TransApi(APP_ID, SECURITY_KEY);
+        log.info("正在翻译文本:{}", query);
+        JSONObject res = JSONUtil.parseObj(api.getTransResult(query, lanSrc, lanDst));
+        JSONArray transResult = res.getJSONArray("trans_result");
+        if (!JSONUtil.isNull(transResult)) {
+            JSONObject jsonObject = transResult.getJSONObject(0);
+            log.info("文本:{},翻译结果:{}", query, jsonObject.getStr("dst"));
+            return jsonObject.getStr("dst");
+        } else {
+            log.info("文本:{},翻译失败:{}", query, JSONUtil.toJsonPrettyStr(res));
+            return "-";
+        }
+    }
+
+    @PostMapping("/menuOne")
+    @ApiOperation("单个菜单翻译-同步返回结果")
+    public R<String> translateMenuOne(@RequestBody @Validated TranslateDto.One one) {
+        String content = one.getContent();
+        String targetType = one.getTargetType();
+        String translatedValue = translate(content, "zh", targetType);
+        return R.ok(translatedValue);
+    }
+
+
+    /**
+     * 全量菜单翻译
+     *
+     * @return
+     */
+    @PostMapping("/menuAll")
+    @ApiOperation("菜单全量翻译-已翻译的忽略")
+    public R<?> translateMenuAll() {
+        translateAllMenu();
+        return R.ok();
+    }
+
+    @Async
+    protected void translateAllMenu() {
+        List<SysMenu> sysMenus = sysMenuService.list();
+        List<SysMenu> updateMenus = new ArrayList<>();
+        for (SysMenu sysMenu : sysMenus) {
+            String name = sysMenu.getName();
+            String enName = sysMenu.getEnName();
+            if (StrUtil.isEmpty(enName)) {
+                //百度api翻译
+                String translatedValue = translate(name, "zh", "en");
+                sysMenu.setName(translatedValue);
+                updateMenus.add(sysMenu);
+                // 增加1.2秒的延迟
+                try {
+                    Thread.sleep(1800);
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                    log.error("线程中断异常", e);
+                }
+            }
+        }
+        if (CollUtil.isNotEmpty(updateMenus)) {
+            sysMenuService.updateBatchById(updateMenus);
+        }
+    }
+
+}

+ 152 - 0
authorize-api-service/src/main/java/com/xy/third/baidu/HttpGet.java

@@ -0,0 +1,152 @@
+package com.xy.third.baidu;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Map;
+
+class HttpGet {
+    protected static final int SOCKET_TIMEOUT = 10000; // 10S
+    protected static final String GET = "GET";
+    private static TrustManager myX509TrustManager = new X509TrustManager() {
+
+        @Override
+        public X509Certificate[] getAcceptedIssuers() {
+            return null;
+        }
+
+        @Override
+        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+        }
+
+        @Override
+        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+        }
+    };
+
+    public static String get(String host, Map<String, String> params) {
+        try {
+            // 设置SSLContext
+            SSLContext sslcontext = SSLContext.getInstance("TLS");
+            sslcontext.init(null, new TrustManager[]{myX509TrustManager}, null);
+
+            String sendUrl = getUrlWithQueryString(host, params);
+
+            // System.out.println("URL:" + sendUrl);
+
+            URL uri = new URL(sendUrl); // 创建URL对象
+            HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
+            if (conn instanceof HttpsURLConnection) {
+                ((HttpsURLConnection) conn).setSSLSocketFactory(sslcontext.getSocketFactory());
+            }
+
+            conn.setConnectTimeout(SOCKET_TIMEOUT); // 设置相应超时
+            conn.setRequestMethod(GET);
+            int statusCode = conn.getResponseCode();
+            if (statusCode != HttpURLConnection.HTTP_OK) {
+                System.out.println("Http错误码:" + statusCode);
+            }
+
+            // 读取服务器的数据
+            InputStream is = conn.getInputStream();
+            BufferedReader br = new BufferedReader(new InputStreamReader(is));
+            StringBuilder builder = new StringBuilder();
+            String line = null;
+            while ((line = br.readLine()) != null) {
+                builder.append(line);
+            }
+
+            String text = builder.toString();
+
+            close(br); // 关闭数据流
+            close(is); // 关闭数据流
+            conn.disconnect(); // 断开连接
+
+            return text;
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (KeyManagementException e) {
+            e.printStackTrace();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    public static String getUrlWithQueryString(String url, Map<String, String> params) {
+        if (params == null) {
+            return url;
+        }
+
+        StringBuilder builder = new StringBuilder(url);
+        if (url.contains("?")) {
+            builder.append("&");
+        } else {
+            builder.append("?");
+        }
+
+        int i = 0;
+        for (String key : params.keySet()) {
+            String value = params.get(key);
+            if (value == null) { // 过滤空的key
+                continue;
+            }
+
+            if (i != 0) {
+                builder.append('&');
+            }
+
+            builder.append(key);
+            builder.append('=');
+            builder.append(encode(value));
+
+            i++;
+        }
+
+        return builder.toString();
+    }
+
+    protected static void close(Closeable closeable) {
+        if (closeable != null) {
+            try {
+                closeable.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * 对输入的字符串进行URL编码, 即转换为%20这种形式
+     *
+     * @param input 原文
+     * @return URL编码. 如果编码失败, 则返回原文
+     */
+    public static String encode(String input) {
+        if (input == null) {
+            return "";
+        }
+
+        try {
+            return URLEncoder.encode(input, "utf-8");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        return input;
+    }
+
+}

+ 120 - 0
authorize-api-service/src/main/java/com/xy/third/baidu/MD5.java

@@ -0,0 +1,120 @@
+package com.xy.third.baidu;
+
+import java.io.*;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * MD5编码相关的类
+ *
+ * @author wangjingtao
+ */
+public class MD5 {
+    // 首先初始化一个字符数组,用来存放每个16进制字符
+    private static final char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
+            'e', 'f'};
+
+    /**
+     * 获得一个字符串的MD5值
+     *
+     * @param input 输入的字符串
+     * @return 输入字符串的MD5值
+     */
+    public static String md5(String input) {
+        if (input == null)
+            return null;
+
+        try {
+            try {
+
+                // 拿到一个MD5转换器(如果想要SHA1参数换成”SHA1”)
+                MessageDigest messageDigest = MessageDigest.getInstance("MD5");
+                // 输入的字符串转换成字节数组
+                byte[] inputByteArray = input.getBytes("utf-8");
+                // inputByteArray是输入字符串转换得到的字节数组
+                messageDigest.update(inputByteArray);
+                // 转换并返回结果,也是字节数组,包含16个元素
+                byte[] resultByteArray = messageDigest.digest();
+                // 字符数组转换成字符串返回
+                return byteArrayToHex(resultByteArray);
+            } catch (UnsupportedEncodingException e) {
+                return null;
+            }
+        } catch (NoSuchAlgorithmException e) {
+            return null;
+        }
+    }
+
+    /**
+     * 获取文件的MD5值
+     *
+     * @param file
+     * @return
+     */
+    public static String md5(File file) {
+        try {
+            if (!file.isFile()) {
+                System.err.println("文件" + file.getAbsolutePath() + "不存在或者不是文件");
+                return null;
+            }
+
+            FileInputStream in = new FileInputStream(file);
+
+            String result = md5(in);
+
+            in.close();
+
+            return result;
+
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    public static String md5(InputStream in) {
+
+        try {
+            MessageDigest messagedigest = MessageDigest.getInstance("MD5");
+
+            byte[] buffer = new byte[1024];
+            int read = 0;
+            while ((read = in.read(buffer)) != -1) {
+                messagedigest.update(buffer, 0, read);
+            }
+
+            in.close();
+
+            String result = byteArrayToHex(messagedigest.digest());
+
+            return result;
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    private static String byteArrayToHex(byte[] byteArray) {
+        // new一个字符数组,这个就是用来组成结果字符串的(解释一下:一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方))
+        char[] resultCharArray = new char[byteArray.length * 2];
+        // 遍历字节数组,通过位运算(位运算效率高),转换成字符放到字符数组中去
+        int index = 0;
+        for (byte b : byteArray) {
+            resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
+            resultCharArray[index++] = hexDigits[b & 0xf];
+        }
+
+        // 字符数组组合成字符串返回
+        return new String(resultCharArray);
+
+    }
+
+}

+ 44 - 0
authorize-api-service/src/main/java/com/xy/third/baidu/TransApi.java

@@ -0,0 +1,44 @@
+package com.xy.third.baidu;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 百度翻译API接口
+ */
+public class TransApi {
+    private static final String TRANS_API_HOST = "https://fanyi-api.baidu.com/api/trans/vip/translate";
+
+    private String appid;
+    private String securityKey;
+
+    public TransApi(String appid, String securityKey) {
+        this.appid = appid;
+        this.securityKey = securityKey;
+    }
+
+    public String getTransResult(String query, String from, String to) {
+        Map<String, String> params = buildParams(query, from, to);
+        return HttpGet.get(TRANS_API_HOST, params);
+    }
+
+    private Map<String, String> buildParams(String query, String from, String to) {
+        Map<String, String> params = new HashMap<String, String>();
+        params.put("q", query);
+        params.put("from", from);
+        params.put("to", to);
+
+        params.put("appid", appid);
+
+        // 随机数
+        String salt = String.valueOf(System.currentTimeMillis());
+        params.put("salt", salt);
+
+        // 签名
+        String src = appid + query + salt + securityKey; // 加密前的原文
+        params.put("sign", MD5.md5(src));
+
+        return params;
+    }
+
+}

+ 27 - 0
authorize-api/src/main/java/com/xy/dto/TranslateDto.java

@@ -0,0 +1,27 @@
+package com.xy.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+@ApiModel("翻译DTO")
+@Accessors(chain = true)
+public class TranslateDto {
+
+    @Data
+    @Accessors(chain = true)
+    public static class One {
+        @NotBlank(message = "待翻译字符串不能为空")
+        @ApiModelProperty(value = "待翻译字符串")
+        private String content;
+
+        @NotBlank(message = "目标语言类型不能为空")
+        @ApiModelProperty(value = "目标语言类型:(en-英语,kor-韩语,th-泰语..")
+        private String targetType;
+    }
+
+}