xf 翻译
This commit is contained in:
33
src/main/java/com/newyetai/ai/controller/AiController.java
Normal file
33
src/main/java/com/newyetai/ai/controller/AiController.java
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package com.newyetai.ai.controller;
|
||||||
|
|
||||||
|
import com.newyetai.common.AlitaResult;
|
||||||
|
import com.newyetai.sdk.xf.model.ChatReq;
|
||||||
|
import com.newyetai.sdk.xf.model.TranslateReq;
|
||||||
|
import com.newyetai.sdk.xf.util.XfUtils;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@Api(tags = "ai")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/ai")
|
||||||
|
public class AiController {
|
||||||
|
|
||||||
|
@PostMapping("chat")
|
||||||
|
@ApiOperation("ai对话")
|
||||||
|
public AlitaResult<String> chat(@Validated @RequestBody ChatReq req) {
|
||||||
|
return AlitaResult.success(XfUtils.chat(req));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("translate")
|
||||||
|
@ApiOperation("ai翻译")
|
||||||
|
public AlitaResult<String> chat(@Validated @RequestBody TranslateReq req) {
|
||||||
|
return AlitaResult.success(XfUtils.translate(req));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -34,5 +34,8 @@ public class XfProperties implements Serializable{
|
|||||||
private String iatHostUrl;
|
private String iatHostUrl;
|
||||||
/** 语音合成地址 **/
|
/** 语音合成地址 **/
|
||||||
private String ttsHostUrl;
|
private String ttsHostUrl;
|
||||||
|
/** 机器翻译niutrans **/
|
||||||
|
private String otsHostUrl;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.newyetai.sdk.xf.model;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -19,6 +20,7 @@ public class ChatReq implements Serializable{
|
|||||||
@Default
|
@Default
|
||||||
private String model = "4.0Ultra";
|
private String model = "4.0Ultra";
|
||||||
@Singular
|
@Singular
|
||||||
|
@NotNull(message = "消息内容不能为空")
|
||||||
private List<MessageDTO> messages;
|
private List<MessageDTO> messages;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
67
src/main/java/com/newyetai/sdk/xf/model/TranslateReq.java
Normal file
67
src/main/java/com/newyetai/sdk/xf/model/TranslateReq.java
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
package com.newyetai.sdk.xf.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.newyetai.sdk.common.dto.ISdkRequest;
|
||||||
|
import com.newyetai.sdk.xf.model.TranslateReq.TranslateRes;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Builder.Default;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class TranslateReq implements ISdkRequest<XfRes<TranslateRes>> {
|
||||||
|
|
||||||
|
private static ParameterizedTypeReference<XfRes<TranslateRes>> type = new ParameterizedTypeReference<XfRes<TranslateRes>>() {
|
||||||
|
};
|
||||||
|
/** 中文 */
|
||||||
|
private static final String CN = "cn";
|
||||||
|
/** 维语 */
|
||||||
|
private static final String UY = "uy";
|
||||||
|
|
||||||
|
@NotBlank(message = "待翻译文本不能为空")
|
||||||
|
private String text;
|
||||||
|
@Default
|
||||||
|
private String from = CN;
|
||||||
|
@Default
|
||||||
|
private String to = UY;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParameterizedTypeReference getResponseType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public static class TranslateRes {
|
||||||
|
private TranslateResDTO result;
|
||||||
|
}
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public static class TranslateResDTO {
|
||||||
|
private String from;
|
||||||
|
private String to;
|
||||||
|
@JsonProperty("trans_result")
|
||||||
|
private TranslateResultDTO transResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public static class TranslateResultDTO {
|
||||||
|
private String src;
|
||||||
|
private String dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
19
src/main/java/com/newyetai/sdk/xf/model/XfRes.java
Normal file
19
src/main/java/com/newyetai/sdk/xf/model/XfRes.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package com.newyetai.sdk.xf.model;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
public class XfRes<T> {
|
||||||
|
|
||||||
|
private Integer code;
|
||||||
|
private String message;
|
||||||
|
private String sid;
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,24 @@
|
|||||||
package com.newyetai.sdk.xf.service;
|
package com.newyetai.sdk.xf.service;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.newyetai.common.constant.CommonConstants;
|
||||||
|
import com.newyetai.sdk.xf.model.TranslateReq;
|
||||||
|
import com.newyetai.sdk.xf.model.TranslateReq.TranslateRes;
|
||||||
|
import com.newyetai.sdk.xf.model.XfRes;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import org.springframework.http.HttpEntity;
|
import org.springframework.http.HttpEntity;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
@@ -67,6 +86,149 @@ public class XfSparkProvider {
|
|||||||
public static String dealJson(String content) {
|
public static String dealJson(String content) {
|
||||||
return content.replaceAll("(```json\n)|(\n```)|(\n)", "");
|
return content.replaceAll("(```json\n)|(\n```)|(\n)", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static AlitaResult<String> translate(TranslateReq translateReq){
|
||||||
|
return translate(translateReq, xfProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AlitaResult<String> translate(TranslateReq translateReq, XfProperties xfProperties){
|
||||||
|
|
||||||
|
ResponseEntity<XfRes<TranslateRes>> response = null;
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
String body = buildHttpBody(translateReq, xfProperties);
|
||||||
|
|
||||||
|
HttpHeaders header = buildHttpHeader(body, xfProperties);
|
||||||
|
// 发送请求
|
||||||
|
HttpEntity requestEntity = new HttpEntity(body, header);
|
||||||
|
response =
|
||||||
|
HttpUtils.restTemplate.exchange(xfProperties.getOtsHostUrl(),
|
||||||
|
HttpMethod.POST, requestEntity, translateReq.getResponseType());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("xfSpark http error:{}", e.getMessage());
|
||||||
|
return AlitaResult.error(SdkConstants.SDK_HTTP_INVOKE_ERROR_CODE, e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
XfRes<TranslateRes> res = response.getBody();
|
||||||
|
if (!res.getCode().equals(0)) {
|
||||||
|
return AlitaResult.error(SdkConstants.SDK_HTTP_INVOKE_RESPONSE_FAIL_CODE,
|
||||||
|
res.getCode() + CommonConstants.COLON + res.getMessage());
|
||||||
|
}
|
||||||
|
return AlitaResult.success(res.getData().getResult().getTransResult().getDst());
|
||||||
|
} catch (Exception e) {
|
||||||
|
return AlitaResult.error(SdkConstants.SDK_RESPONSE_CONVERT_ERROR_CODE, "xf返回结果获取content失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
log.info("xfSpark invoke:{}",
|
||||||
|
JsonUtils
|
||||||
|
.toJsonString(
|
||||||
|
DefaultSdkInvokeLogDTO.builder().requestData(translateReq).responseData(response)
|
||||||
|
.build()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 组装http请求头
|
||||||
|
*/
|
||||||
|
public static HttpHeaders buildHttpHeader(String body, XfProperties xfProperties)
|
||||||
|
throws MalformedURLException, NoSuchAlgorithmException, InvalidKeyException {
|
||||||
|
HttpHeaders header = new HttpHeaders();
|
||||||
|
URL url = new URL(xfProperties.getOtsHostUrl());
|
||||||
|
|
||||||
|
//时间戳
|
||||||
|
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
|
||||||
|
format.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
|
Date dateD = new Date();
|
||||||
|
String date = format.format(dateD);
|
||||||
|
//System.out.println("【OTS WebAPI date】\n" + date);
|
||||||
|
|
||||||
|
//对body进行sha256签名,生成digest头部,POST请求必须对body验证
|
||||||
|
String digestBase64 = "SHA-256=" + signBody(body);
|
||||||
|
//System.out.println("【OTS WebAPI digestBase64】\n" + digestBase64);
|
||||||
|
|
||||||
|
//hmacsha256加密原始字符串
|
||||||
|
StringBuilder builder = new StringBuilder("host: ").append(url.getHost()).append("\n").//
|
||||||
|
append("date: ").append(date).append("\n").//
|
||||||
|
append("POST ").append(url.getPath()).append(" HTTP/1.1").append("\n").//
|
||||||
|
append("digest: ").append(digestBase64);
|
||||||
|
//System.out.println("【OTS WebAPI builder】\n" + builder);
|
||||||
|
String sha = hmacsign(builder.toString(), xfProperties.getApiSecret());
|
||||||
|
//System.out.println("【OTS WebAPI sha】\n" + sha);
|
||||||
|
|
||||||
|
//组装authorization
|
||||||
|
String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", xfProperties.getApiKey(), "hmac-sha256", "host date request-line digest", sha);
|
||||||
|
//System.out.println("【OTS WebAPI authorization】\n" + authorization);
|
||||||
|
|
||||||
|
header.add("Authorization", authorization);
|
||||||
|
header.add("Content-Type", "application/json");
|
||||||
|
header.add("Accept", "application/json,version=1.0");
|
||||||
|
header.add("Host", url.getHost());
|
||||||
|
header.add("Date", date);
|
||||||
|
header.add("Digest", digestBase64);
|
||||||
|
//System.out.println("【OTS WebAPI header】\n" + header);
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 组装http请求体
|
||||||
|
*/
|
||||||
|
public static String buildHttpBody(TranslateReq translateReq, XfProperties xfProperties)
|
||||||
|
throws UnsupportedEncodingException {
|
||||||
|
JsonObject body = new JsonObject();
|
||||||
|
JsonObject business = new JsonObject();
|
||||||
|
JsonObject common = new JsonObject();
|
||||||
|
JsonObject data = new JsonObject();
|
||||||
|
//填充common
|
||||||
|
common.addProperty("app_id", xfProperties.getAppId());
|
||||||
|
//填充business
|
||||||
|
business.addProperty("from", translateReq.getFrom());
|
||||||
|
business.addProperty("to", translateReq.getTo());
|
||||||
|
//填充data
|
||||||
|
//System.out.println("【OTS WebAPI TEXT字个数:】\n" + TEXT.length());
|
||||||
|
byte[] textByte = translateReq.getText().getBytes("UTF-8");
|
||||||
|
String textBase64 = new String(Base64.getEncoder().encodeToString(textByte));
|
||||||
|
//System.out.println("【OTS WebAPI textBase64编码后长度:】\n" + textBase64.length());
|
||||||
|
data.addProperty("text", textBase64);
|
||||||
|
//填充body
|
||||||
|
body.add("common", common);
|
||||||
|
body.add("business", business);
|
||||||
|
body.add("data", data);
|
||||||
|
return body.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对body进行SHA-256加密
|
||||||
|
*/
|
||||||
|
private static String signBody(String body) {
|
||||||
|
MessageDigest messageDigest;
|
||||||
|
String encodestr = "";
|
||||||
|
try {
|
||||||
|
messageDigest = MessageDigest.getInstance("SHA-256");
|
||||||
|
messageDigest.update(body.getBytes("UTF-8"));
|
||||||
|
encodestr = Base64.getEncoder().encodeToString(messageDigest.digest());
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return encodestr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hmacsha256加密
|
||||||
|
*/
|
||||||
|
private static String hmacsign(String signature, String apiSecret)
|
||||||
|
throws NoSuchAlgorithmException, InvalidKeyException {
|
||||||
|
Charset charset = Charset.forName("UTF-8");
|
||||||
|
Mac mac = Mac.getInstance("hmacsha256");
|
||||||
|
SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(charset), "hmacsha256");
|
||||||
|
mac.init(spec);
|
||||||
|
byte[] hexDigits = mac.doFinal(signature.getBytes(charset));
|
||||||
|
return Base64.getEncoder().encodeToString(hexDigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.newyetai.sdk.xf.util;
|
package com.newyetai.sdk.xf.util;
|
||||||
|
|
||||||
|
import com.newyetai.sdk.xf.model.TranslateReq;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@@ -229,4 +230,16 @@ public class XfUtils {
|
|||||||
return result.getData();
|
return result.getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String chat(ChatReq req) {
|
||||||
|
AlitaResult<String> result = XfSparkProvider.httpChat(req);
|
||||||
|
Assert.isTrue(result.getSuccess(), result.getMsg());
|
||||||
|
return result.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String translate(TranslateReq req) {
|
||||||
|
AlitaResult<String> result = XfSparkProvider.translate(req);
|
||||||
|
Assert.isTrue(result.getSuccess(), result.getMsg());
|
||||||
|
return result.getData();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,13 +156,15 @@ ali.idcard.appcode=728e8c05167a482093418707ca22822b
|
|||||||
#讯飞配置
|
#讯飞配置
|
||||||
xf.httpAPIPassword=EiORVeNtBjFOcUSKXanT:oIVlTRNhWcEDpksviZaG
|
xf.httpAPIPassword=EiORVeNtBjFOcUSKXanT:oIVlTRNhWcEDpksviZaG
|
||||||
#在控制台-我的应用获取
|
#在控制台-我的应用获取
|
||||||
xf.appId=a2847f13
|
xf.appId=83b8ddca
|
||||||
xf.apiSecret=ZGYzYjY5N2E2ODJhYzJkZWNjMjBmMWU5
|
xf.apiSecret=ZWE2MjkzY2VmZDkwM2EwZGJhNGRhOWJm
|
||||||
xf.apiKey=a232b25616c1359d15c30711c1976de6
|
xf.apiKey=e092f93e28ebe6d27f756bb2d884dcff
|
||||||
#语音听写地址
|
#语音听写地址
|
||||||
xf.iatHostUrl=https://iat-api.xfyun.cn/v2/iat
|
xf.iatHostUrl=https://iat-api.xfyun.cn/v2/iat
|
||||||
#语音合成地址
|
#语音合成地址
|
||||||
xf.ttsHostUrl=https://tts-api.xfyun.cn/v2/tts
|
xf.ttsHostUrl=https://tts-api.xfyun.cn/v2/tts
|
||||||
|
#机器翻译niutrans
|
||||||
|
xf.otsHostUrl=https://ntrans.xfyun.cn/v2/ots
|
||||||
|
|
||||||
#腾讯地图
|
#腾讯地图
|
||||||
tencent.map.key=TS7BZ-GOVCB-CUZUL-JUUAV-WTYT3-Z2B4Z
|
tencent.map.key=TS7BZ-GOVCB-CUZUL-JUUAV-WTYT3-Z2B4Z
|
||||||
|
|||||||
Reference in New Issue
Block a user